ptp-pack.c revision 0546a76acd169daf35572ece1f58c9b3bc7f0f56
1b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij/* currently this file is included into ptp.c */ 2eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 36db174f4d18af574fab991309e11010aa0eb4543Linus Walleij#ifdef HAVE_ICONV 4a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij#include <iconv.h> 56db174f4d18af574fab991309e11010aa0eb4543Linus Walleij#endif 6a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij 7b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint16_t 8eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleijhtod16p (PTPParams *params, uint16_t var) 9eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 10eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return ((params->byteorder==PTP_DL_LE)?htole16(var):htobe16(var)); 11eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 12eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 13b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint32_t 14eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleijhtod32p (PTPParams *params, uint32_t var) 15eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 16eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return ((params->byteorder==PTP_DL_LE)?htole32(var):htobe32(var)); 17eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 18eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 19b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 20eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleijhtod16ap (PTPParams *params, unsigned char *a, uint16_t val) 21eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 22eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij if (params->byteorder==PTP_DL_LE) 23b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htole16a(a,val); 24e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij else 25eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htobe16a(a,val); 26eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 27eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 28b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 29eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleijhtod32ap (PTPParams *params, unsigned char *a, uint32_t val) 30eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 31eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij if (params->byteorder==PTP_DL_LE) 32b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htole32a(a,val); 33e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij else 34eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htobe32a(a,val); 35eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 36eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 37abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleijstatic inline void 38abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleijhtod64ap (PTPParams *params, unsigned char *a, uint64_t val) 39abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij{ 40abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij if (params->byteorder==PTP_DL_LE) 41abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij htole64a(a,val); 42e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij else 43abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij htobe64a(a,val); 44abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij} 45abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij 46b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint16_t 47eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleijdtoh16p (PTPParams *params, uint16_t var) 48eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 49eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return ((params->byteorder==PTP_DL_LE)?le16toh(var):be16toh(var)); 50eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 51eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 52b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint32_t 53eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleijdtoh32p (PTPParams *params, uint32_t var) 54eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 55eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return ((params->byteorder==PTP_DL_LE)?le32toh(var):be32toh(var)); 56eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 57eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 58abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleijstatic inline uint64_t 59abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleijdtoh64p (PTPParams *params, uint64_t var) 60abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij{ 61abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij return ((params->byteorder==PTP_DL_LE)?le64toh(var):be64toh(var)); 62abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij} 63abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij 64b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint16_t 651a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleijdtoh16ap (PTPParams *params, const unsigned char *a) 66eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 67eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return ((params->byteorder==PTP_DL_LE)?le16atoh(a):be16atoh(a)); 68eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 69eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 70b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint32_t 711a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleijdtoh32ap (PTPParams *params, const unsigned char *a) 72eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 73eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return ((params->byteorder==PTP_DL_LE)?le32atoh(a):be32atoh(a)); 74eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 75eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 76b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint64_t 771a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleijdtoh64ap (PTPParams *params, const unsigned char *a) 78eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 79abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij return ((params->byteorder==PTP_DL_LE)?le64atoh(a):be64atoh(a)); 80eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 81eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 82b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define htod8a(a,x) *(uint8_t*)(a) = x 83b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define htod16a(a,x) htod16ap(params,a,x) 84b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define htod32a(a,x) htod32ap(params,a,x) 85abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij#define htod64a(a,x) htod64ap(params,a,x) 86b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define htod16(x) htod16p(params,x) 87b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define htod32(x) htod32p(params,x) 88abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij#define htod64(x) htod64p(params,x) 89b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 90b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define dtoh8a(x) (*(uint8_t*)(x)) 91b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define dtoh16a(a) dtoh16ap(params,a) 92b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define dtoh32a(a) dtoh32ap(params,a) 93b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define dtoh64a(a) dtoh64ap(params,a) 94b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define dtoh16(x) dtoh16p(params,x) 95b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define dtoh32(x) dtoh32p(params,x) 96abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij#define dtoh64(x) dtoh64p(params,x) 97b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 98b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 99b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline char* 100b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_string(PTPParams *params, unsigned char* data, uint16_t offset, uint8_t *len) 101eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 102a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij uint8_t length; 103a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij uint16_t string[PTP_MAXSTRLEN+1]; 104a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij /* allow for UTF-8: max of 3 bytes per UCS-2 char, plus final null */ 105e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij char loclstr[PTP_MAXSTRLEN*3+1]; 106a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij size_t nconv, srclen, destlen; 107a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij char *src, *dest; 108a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij 109a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij length = dtoh8a(&data[offset]); /* PTP_MAXSTRLEN == 255, 8 bit len */ 110a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij *len = length; 111a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij if (length == 0) /* nothing to do? */ 112a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij return(NULL); 113a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij 114a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij /* copy to string[] to ensure correct alignment for iconv(3) */ 115a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij memcpy(string, &data[offset+1], length * sizeof(string[0])); 116a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij string[length] = 0x0000U; /* be paranoid! add a terminator. */ 117a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij loclstr[0] = '\0'; 118e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij 119a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij /* convert from camera UCS-2 to our locale */ 120a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij src = (char *)string; 121a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij srclen = length * sizeof(string[0]); 122a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij dest = loclstr; 123a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij destlen = sizeof(loclstr)-1; 1246db174f4d18af574fab991309e11010aa0eb4543Linus Walleij nconv = (size_t)-1; 1256db174f4d18af574fab991309e11010aa0eb4543Linus Walleij#ifdef HAVE_ICONV 126d6f25baf36fba05e3d8b2fa6d3cd4c026e2e6d33Linus Walleij if (params->cd_ucs2_to_locale != (iconv_t)-1) 127d6f25baf36fba05e3d8b2fa6d3cd4c026e2e6d33Linus Walleij nconv = iconv(params->cd_ucs2_to_locale, &src, &srclen, &dest, &destlen); 1286db174f4d18af574fab991309e11010aa0eb4543Linus Walleij#endif 129a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij if (nconv == (size_t) -1) { /* do it the hard way */ 130a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij int i; 131a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij /* try the old way, in case iconv is broken */ 132a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij for (i=0;i<length;i++) { 133a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij if (dtoh16a(&data[offset+1+2*i])>127) 134a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij loclstr[i] = '?'; 135a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij else 136a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij loclstr[i] = dtoh16a(&data[offset+1+2*i]); 137eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 138a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij dest = loclstr+length; 139eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 140a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij *dest = '\0'; 141a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij loclstr[sizeof(loclstr)-1] = '\0'; /* be safe? */ 142a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij return(strdup(loclstr)); 143a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij} 144a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij 145a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleijstatic inline int 146a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleijucs2strlen(uint16_t const * const unicstr) 147a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij{ 14896aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij int length = 0; 149a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij 150a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij /* Unicode strings are terminated with 2 * 0x00 */ 151a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij for(length = 0; unicstr[length] != 0x0000U; length ++); 152a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij return length; 153eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 154eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 155a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij 156b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 157b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_pack_string(PTPParams *params, char *string, unsigned char* data, uint16_t offset, uint8_t *len) 158eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 15996aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij int packedlen = 0; 160a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij uint16_t ucs2str[PTP_MAXSTRLEN+1]; 161a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij char *ucs2strp = (char *) ucs2str; 162a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij size_t convlen = strlen(string); 163a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij 164a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij /* Cannot exceed 255 (PTP_MAXSTRLEN) since it is a single byte, duh ... */ 165a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij memset(ucs2strp, 0, sizeof(ucs2str)); /* XXX: necessary? */ 1666db174f4d18af574fab991309e11010aa0eb4543Linus Walleij#ifdef HAVE_ICONV 167d000c371601fafcf75d2de2d1060ee11be2007d6Linus Walleij if (params->cd_locale_to_ucs2 != (iconv_t)-1) { 1686db174f4d18af574fab991309e11010aa0eb4543Linus Walleij size_t nconv; 1696db174f4d18af574fab991309e11010aa0eb4543Linus Walleij size_t convmax = PTP_MAXSTRLEN * 2; /* Includes the terminator */ 1706db174f4d18af574fab991309e11010aa0eb4543Linus Walleij char *stringp = string; 1716db174f4d18af574fab991309e11010aa0eb4543Linus Walleij 1726db174f4d18af574fab991309e11010aa0eb4543Linus Walleij nconv = iconv(params->cd_locale_to_ucs2, &stringp, &convlen, 1736db174f4d18af574fab991309e11010aa0eb4543Linus Walleij &ucs2strp, &convmax); 1746db174f4d18af574fab991309e11010aa0eb4543Linus Walleij if (nconv == (size_t) -1) 1756db174f4d18af574fab991309e11010aa0eb4543Linus Walleij ucs2str[0] = 0x0000U; 176d6f25baf36fba05e3d8b2fa6d3cd4c026e2e6d33Linus Walleij } else 177d000c371601fafcf75d2de2d1060ee11be2007d6Linus Walleij#endif 1786db174f4d18af574fab991309e11010aa0eb4543Linus Walleij { 1796db174f4d18af574fab991309e11010aa0eb4543Linus Walleij int i; 1806db174f4d18af574fab991309e11010aa0eb4543Linus Walleij for (i=0;i<convlen;i++) { 1816db174f4d18af574fab991309e11010aa0eb4543Linus Walleij ucs2str[i] = string[i]; 1826db174f4d18af574fab991309e11010aa0eb4543Linus Walleij } 1836db174f4d18af574fab991309e11010aa0eb4543Linus Walleij ucs2str[convlen] = 0; 1846db174f4d18af574fab991309e11010aa0eb4543Linus Walleij } 185a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij /* 186a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij * XXX: isn't packedlen just ( (uint16_t *)ucs2strp - ucs2str )? 187a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij * why do we need ucs2strlen()? 188a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij */ 189a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij packedlen = ucs2strlen(ucs2str); 190a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij if (packedlen > PTP_MAXSTRLEN-1) { 191a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij *len=0; 192a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij return; 193a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij } 194958441f8ed3e704cf07c9f600730f90a80a0d424Linus Walleij 1957f2343824550452974d78f5dbd94e64844355c33Linus Walleij /* number of characters including terminating 0 (PTP standard confirmed) */ 196a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij htod8a(&data[offset],packedlen+1); 197a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij memcpy(&data[offset+1], &ucs2str[0], packedlen * sizeof(ucs2str[0])); 198a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij htod16a(&data[offset+packedlen*2+1], 0x0000); /* terminate 0 */ 199958441f8ed3e704cf07c9f600730f90a80a0d424Linus Walleij 200958441f8ed3e704cf07c9f600730f90a80a0d424Linus Walleij /* The returned length is in number of characters */ 201048d938dc4889b74b258a786d5f53142b059fc32Linus Walleij *len = (uint8_t) packedlen+1; 202eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 203eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 204a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleijstatic inline unsigned char * 205735f41692934a716158cf051d76e988febeca7eeLinus Walleijptp_get_packed_stringcopy(PTPParams *params, char *string, uint32_t *packed_size) 206a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij{ 2078b42ca3d3baeb7c8f3e5eca88c613adb612e4ec0Richard Low uint8_t packed[PTP_MAXSTRLEN*2+3], len; 208a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij size_t plen; 209a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij unsigned char *retcopy = NULL; 210d47b9218023a6b943a93faa743712ae072cba85cRichard Low 211d47b9218023a6b943a93faa743712ae072cba85cRichard Low if (string == NULL) 212d47b9218023a6b943a93faa743712ae072cba85cRichard Low ptp_pack_string(params, "", (unsigned char*) packed, 0, &len); 213d47b9218023a6b943a93faa743712ae072cba85cRichard Low else 214d47b9218023a6b943a93faa743712ae072cba85cRichard Low ptp_pack_string(params, string, (unsigned char*) packed, 0, &len); 215d47b9218023a6b943a93faa743712ae072cba85cRichard Low 216958441f8ed3e704cf07c9f600730f90a80a0d424Linus Walleij /* returned length is in characters, then one byte for string length */ 217958441f8ed3e704cf07c9f600730f90a80a0d424Linus Walleij plen = len*2 + 1; 218048d938dc4889b74b258a786d5f53142b059fc32Linus Walleij 219a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij retcopy = malloc(plen); 220735f41692934a716158cf051d76e988febeca7eeLinus Walleij if (!retcopy) { 221735f41692934a716158cf051d76e988febeca7eeLinus Walleij *packed_size = 0; 222a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij return NULL; 223735f41692934a716158cf051d76e988febeca7eeLinus Walleij } 224a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij memcpy(retcopy, packed, plen); 225735f41692934a716158cf051d76e988febeca7eeLinus Walleij *packed_size = plen; 226a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij return (retcopy); 227a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij} 228a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij 229b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint32_t 230b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_uint32_t_array(PTPParams *params, unsigned char* data, uint16_t offset, uint32_t **array) 231eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 232eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint32_t n, i=0; 233eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 234eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij n=dtoh32a(&data[offset]); 235eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij *array = malloc (n*sizeof(uint32_t)); 236eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij while (n>i) { 237eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij (*array)[i]=dtoh32a(&data[offset+(sizeof(uint32_t)*(i+1))]); 238eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij i++; 239eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 240eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return n; 241eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 242eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 243b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint32_t 244f67bca9bde733f456ad341c0d852147124ab388aLinus Walleijptp_pack_uint32_t_array(PTPParams *params, uint32_t *array, uint32_t arraylen, unsigned char **data ) 245f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij{ 246f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij uint32_t i=0; 247f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij 248f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij *data = malloc ((arraylen+1)*sizeof(uint32_t)); 249f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij htod32a(&(*data)[0],arraylen); 250f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij for (i=0;i<arraylen;i++) 251f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij htod32a(&(*data)[sizeof(uint32_t)*(i+1)], array[i]); 252f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij return (arraylen+1)*sizeof(uint32_t); 253f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij} 254f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij 255f67bca9bde733f456ad341c0d852147124ab388aLinus Walleijstatic inline uint32_t 256b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_uint16_t_array(PTPParams *params, unsigned char* data, uint16_t offset, uint16_t **array) 257eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 258eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint32_t n, i=0; 259eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 260eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij n=dtoh32a(&data[offset]); 261eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij *array = malloc (n*sizeof(uint16_t)); 262eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij while (n>i) { 263eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij (*array)[i]=dtoh16a(&data[offset+(sizeof(uint16_t)*(i+2))]); 264eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij i++; 265eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 266eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return n; 267eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 268eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 269eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* DeviceInfo pack/unpack */ 270eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 271eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_di_StandardVersion 0 272eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_di_VendorExtensionID 2 273eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_di_VendorExtensionVersion 6 274eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_di_VendorExtensionDesc 8 275eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_di_FunctionalMode 8 276eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_di_OperationsSupported 10 277eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 278b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 279b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_DI (PTPParams *params, unsigned char* data, PTPDeviceInfo *di, unsigned int datalen) 280eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 281eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint8_t len; 282eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij unsigned int totallen; 2837e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij 284d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij if (!data) return; 285d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij if (datalen < 12) return; 2867347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij di->StandardVersion = dtoh16a(&data[PTP_di_StandardVersion]); 287eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->VendorExtensionID = 288eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij dtoh32a(&data[PTP_di_VendorExtensionID]); 289eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->VendorExtensionVersion = 290eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij dtoh16a(&data[PTP_di_VendorExtensionVersion]); 291eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->VendorExtensionDesc = 292eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij ptp_unpack_string(params, data, 293eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_VendorExtensionDesc, &len); 294eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen=len*2+1; 295eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->FunctionalMode = 296eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij dtoh16a(&data[PTP_di_FunctionalMode+totallen]); 297eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->OperationsSupported_len = ptp_unpack_uint16_t_array(params, data, 298eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 299eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &di->OperationsSupported); 300eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen=totallen+di->OperationsSupported_len*sizeof(uint16_t)+sizeof(uint32_t); 301eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->EventsSupported_len = ptp_unpack_uint16_t_array(params, data, 302eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 303eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &di->EventsSupported); 304eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen=totallen+di->EventsSupported_len*sizeof(uint16_t)+sizeof(uint32_t); 305eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->DevicePropertiesSupported_len = 306eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij ptp_unpack_uint16_t_array(params, data, 307eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 308eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &di->DevicePropertiesSupported); 309eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen=totallen+di->DevicePropertiesSupported_len*sizeof(uint16_t)+sizeof(uint32_t); 310eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->CaptureFormats_len = ptp_unpack_uint16_t_array(params, data, 311eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 312eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &di->CaptureFormats); 313eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen=totallen+di->CaptureFormats_len*sizeof(uint16_t)+sizeof(uint32_t); 314eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->ImageFormats_len = ptp_unpack_uint16_t_array(params, data, 315eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 316eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &di->ImageFormats); 317eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen=totallen+di->ImageFormats_len*sizeof(uint16_t)+sizeof(uint32_t); 318eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->Manufacturer = ptp_unpack_string(params, data, 319eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 320eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &len); 321eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen+=len*2+1; 322eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->Model = ptp_unpack_string(params, data, 323eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 324eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &len); 325eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen+=len*2+1; 326eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->DeviceVersion = ptp_unpack_string(params, data, 327eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 328eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &len); 329eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen+=len*2+1; 330eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->SerialNumber = ptp_unpack_string(params, data, 331eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 332eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &len); 333eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 334a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij 335e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleijstatic void inline 336a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleijptp_free_DI (PTPDeviceInfo *di) { 337a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij if (di->SerialNumber) free (di->SerialNumber); 338a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij if (di->DeviceVersion) free (di->DeviceVersion); 339a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij if (di->Model) free (di->Model); 340a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij if (di->Manufacturer) free (di->Manufacturer); 341a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij if (di->ImageFormats) free (di->ImageFormats); 342a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij if (di->CaptureFormats) free (di->CaptureFormats); 343a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij if (di->VendorExtensionDesc) free (di->VendorExtensionDesc); 344a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij if (di->OperationsSupported) free (di->OperationsSupported); 345a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij if (di->EventsSupported) free (di->EventsSupported); 346a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij if (di->DevicePropertiesSupported) free (di->DevicePropertiesSupported); 347a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij} 3487e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij 3497e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij/* EOS Device Info unpack */ 3507e75653e64021908ca66b155eeb950d8304c87d8Linus Walleijstatic inline void 3517e75653e64021908ca66b155eeb950d8304c87d8Linus Walleijptp_unpack_EOS_DI (PTPParams *params, unsigned char* data, PTPCanonEOSDeviceInfo *di, unsigned int datalen) 3527e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij{ 3537e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij int totallen = 4; 35496aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij 35596aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij memset (di,0, sizeof(*di)); 3567e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij if (datalen < 8) return; 3577e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij 3587e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij /* uint32_t struct len - ignore */ 3597e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij di->EventsSupported_len = ptp_unpack_uint32_t_array(params, data, 3607e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij totallen, &di->EventsSupported); 3617e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij if (!di->EventsSupported) return; 3627e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij totallen += di->EventsSupported_len*sizeof(uint32_t)+4; 3637e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij if (totallen >= datalen) return; 3647e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij 3657e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij di->DevicePropertiesSupported_len = ptp_unpack_uint32_t_array(params, data, 3667e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij totallen, &di->DevicePropertiesSupported); 3677e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij if (!di->DevicePropertiesSupported) return; 3687e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij totallen += di->DevicePropertiesSupported_len*sizeof(uint32_t)+4; 3697e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij if (totallen >= datalen) return; 3707e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij 3717e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij di->unk_len = ptp_unpack_uint32_t_array(params, data, 3727e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij totallen, &di->unk); 3737e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij if (!di->unk) return; 3747e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij totallen += di->unk_len*sizeof(uint32_t)+4; 3757e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij return; 3767e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij} 3770d762ccc39331608119dd0267021b165e22de499Linus Walleij 3780d762ccc39331608119dd0267021b165e22de499Linus Walleijstatic inline void 3790d762ccc39331608119dd0267021b165e22de499Linus Walleijptp_free_EOS_DI (PTPCanonEOSDeviceInfo *di) 3800d762ccc39331608119dd0267021b165e22de499Linus Walleij{ 3810d762ccc39331608119dd0267021b165e22de499Linus Walleij free (di->EventsSupported); 3820d762ccc39331608119dd0267021b165e22de499Linus Walleij free (di->DevicePropertiesSupported); 3830d762ccc39331608119dd0267021b165e22de499Linus Walleij free (di->unk); 3840d762ccc39331608119dd0267021b165e22de499Linus Walleij} 385eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 386eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* ObjectHandles array pack/unpack */ 387eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 388eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oh 0 389eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 390b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 391b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_OH (PTPParams *params, unsigned char* data, PTPObjectHandles *oh, unsigned int len) 392eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 393f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if (len) { 394f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij oh->n = ptp_unpack_uint32_t_array(params, data, PTP_oh, &oh->Handler); 395f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } else { 396f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij oh->n = 0; 397f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij oh->Handler = NULL; 398f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 399eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 400eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 401eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* StoreIDs array pack/unpack */ 402eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 403eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_sids 0 404eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 405b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 406b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_SIDs (PTPParams *params, unsigned char* data, PTPStorageIDs *sids, unsigned int len) 407eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 40896aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij if (!data && !len) { 40996aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij sids->n = 0; 41096aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij sids->Storage = NULL; 41196aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij return; 41296aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij } 413eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij sids->n = ptp_unpack_uint32_t_array(params, data, PTP_sids, 414eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &sids->Storage); 415eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 416eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 417eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* StorageInfo pack/unpack */ 418eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 419eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_si_StorageType 0 420eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_si_FilesystemType 2 421eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_si_AccessCapability 4 422eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_si_MaxCapability 6 423eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_si_FreeSpaceInBytes 14 424eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_si_FreeSpaceInImages 22 425eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_si_StorageDescription 26 426eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 427b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 428b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_SI (PTPParams *params, unsigned char* data, PTPStorageInfo *si, unsigned int len) 429eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 430eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint8_t storagedescriptionlen; 431eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 432eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->StorageType=dtoh16a(&data[PTP_si_StorageType]); 433eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->FilesystemType=dtoh16a(&data[PTP_si_FilesystemType]); 434eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->AccessCapability=dtoh16a(&data[PTP_si_AccessCapability]); 435eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->MaxCapability=dtoh64a(&data[PTP_si_MaxCapability]); 436eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->FreeSpaceInBytes=dtoh64a(&data[PTP_si_FreeSpaceInBytes]); 437eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->FreeSpaceInImages=dtoh32a(&data[PTP_si_FreeSpaceInImages]); 438eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->StorageDescription=ptp_unpack_string(params, data, 439eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_si_StorageDescription, &storagedescriptionlen); 440eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->VolumeLabel=ptp_unpack_string(params, data, 441eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_si_StorageDescription+storagedescriptionlen*2+1, 442eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &storagedescriptionlen); 443eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 444eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 445eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* ObjectInfo pack/unpack */ 446eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 447eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_StorageID 0 448eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ObjectFormat 4 449eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ProtectionStatus 6 450eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ObjectCompressedSize 8 451eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ThumbFormat 12 452eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ThumbCompressedSize 14 453eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ThumbPixWidth 18 454eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ThumbPixHeight 22 455eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ImagePixWidth 26 456eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ImagePixHeight 30 457eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ImageBitDepth 34 458eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ParentObject 38 459eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_AssociationType 42 460eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_AssociationDesc 44 461eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_SequenceNumber 48 462eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_filenamelen 52 463eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_Filename 53 464eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 465a032327c7485548c42f8162f87469dc0e0dd2126Linus Walleij/* the max length assuming zero length dates. We have need 3 */ 466a032327c7485548c42f8162f87469dc0e0dd2126Linus Walleij/* bytes for these. */ 467a679b1c4d273f210abb6befc5d9954a25427c329Richard Low#define PTP_oi_MaxLen PTP_oi_Filename+(PTP_MAXSTRLEN+1)*2+3 468a679b1c4d273f210abb6befc5d9954a25427c329Richard Low 469b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint32_t 470b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_pack_OI (PTPParams *params, PTPObjectInfo *oi, unsigned char** oidataptr) 471eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 472b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij unsigned char* oidata; 473eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint8_t filenamelen; 474eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint8_t capturedatelen=0; 475a679b1c4d273f210abb6befc5d9954a25427c329Richard Low /* let's allocate some memory first; correct assuming zero length dates */ 4760546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner oidata=malloc(PTP_oi_MaxLen + params->ocs64*4); 4770546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner *oidataptr=oidata; 478eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij /* the caller should free it after use! */ 479eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#if 0 480eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij char *capture_date="20020101T010101"; /* XXX Fake date */ 481eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#endif 4820546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner memset (oidata, 0, PTP_oi_MaxLen + params->ocs64*4); 483eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_StorageID],oi->StorageID); 484eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod16a(&oidata[PTP_oi_ObjectFormat],oi->ObjectFormat); 485eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod16a(&oidata[PTP_oi_ProtectionStatus],oi->ProtectionStatus); 486eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ObjectCompressedSize],oi->ObjectCompressedSize); 4870546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner if (params->ocs64) 4880546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner oidata += 4; 489eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod16a(&oidata[PTP_oi_ThumbFormat],oi->ThumbFormat); 490eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ThumbCompressedSize],oi->ThumbCompressedSize); 491eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ThumbPixWidth],oi->ThumbPixWidth); 492eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ThumbPixHeight],oi->ThumbPixHeight); 493eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ImagePixWidth],oi->ImagePixWidth); 494eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ImagePixHeight],oi->ImagePixHeight); 495eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ImageBitDepth],oi->ImageBitDepth); 496eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ParentObject],oi->ParentObject); 497eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod16a(&oidata[PTP_oi_AssociationType],oi->AssociationType); 498eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_AssociationDesc],oi->AssociationDesc); 499eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_SequenceNumber],oi->SequenceNumber); 500eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 501eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij ptp_pack_string(params, oi->Filename, oidata, PTP_oi_filenamelen, &filenamelen); 502eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* 503eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij filenamelen=(uint8_t)strlen(oi->Filename); 504eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod8a(&req->data[PTP_oi_filenamelen],filenamelen+1); 505eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij for (i=0;i<filenamelen && i< PTP_MAXSTRLEN; i++) { 506eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij req->data[PTP_oi_Filename+i*2]=oi->Filename[i]; 507eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 508eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij*/ 509eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij /* 510eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij *XXX Fake date. 511eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij * for example Kodak sets Capture date on the basis of EXIF data. 512eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij * Spec says that this field is from perspective of Initiator. 513eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij */ 514eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#if 0 /* seems now we don't need any data packed in OI dataset... for now ;)*/ 515eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij capturedatelen=strlen(capture_date); 516eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod8a(&data[PTP_oi_Filename+(filenamelen+1)*2], 517eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij capturedatelen+1); 518eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij for (i=0;i<capturedatelen && i< PTP_MAXSTRLEN; i++) { 519eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij data[PTP_oi_Filename+(i+filenamelen+1)*2+1]=capture_date[i]; 520eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 521eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod8a(&data[PTP_oi_Filename+(filenamelen+capturedatelen+2)*2+1], 522eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij capturedatelen+1); 523eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij for (i=0;i<capturedatelen && i< PTP_MAXSTRLEN; i++) { 524eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij data[PTP_oi_Filename+(i+filenamelen+capturedatelen+2)*2+2]= 525eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij capture_date[i]; 526eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 527eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#endif 528eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij /* XXX this function should return dataset length */ 5290546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner return (PTP_oi_Filename+filenamelen*2+(capturedatelen+1)*3)+params->ocs64*4; 530eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 531eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 5323bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleijstatic time_t 5336db174f4d18af574fab991309e11010aa0eb4543Linus Walleijptp_unpack_PTPTIME (const char *str) { 5343bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij char ptpdate[40]; 5353bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij char tmp[5]; 5363bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij int ptpdatelen; 5373bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij struct tm tm; 5383bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij 5393bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij if (!str) 5403bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij return 0; 5413bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij ptpdatelen = strlen(str); 5427e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij if (ptpdatelen >= sizeof (ptpdate)) { 5436db174f4d18af574fab991309e11010aa0eb4543Linus Walleij /*ptp_debug (params ,"datelen is larger then size of buffer", ptpdatelen, (int)sizeof(ptpdate));*/ 5443bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij return 0; 5457e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij } 5463bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij strcpy (ptpdate, str); 5477e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij if (ptpdatelen<15) { 5486db174f4d18af574fab991309e11010aa0eb4543Linus Walleij /*ptp_debug (params ,"datelen is less than 15 (%d)", ptpdatelen);*/ 5493bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij return 0; 5507e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij } 5513bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij 5523bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij memset(&tm,0,sizeof(tm)); 5533bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij strncpy (tmp, ptpdate, 4); 5543bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij tmp[4] = 0; 5553bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij tm.tm_year=atoi (tmp) - 1900; 5563bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij strncpy (tmp, ptpdate + 4, 2); 5573bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij tmp[2] = 0; 5583bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij tm.tm_mon = atoi (tmp) - 1; 5593bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij strncpy (tmp, ptpdate + 6, 2); 5603bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij tmp[2] = 0; 5613bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij tm.tm_mday = atoi (tmp); 5623bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij strncpy (tmp, ptpdate + 9, 2); 5633bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij tmp[2] = 0; 5643bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij tm.tm_hour = atoi (tmp); 5653bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij strncpy (tmp, ptpdate + 11, 2); 5663bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij tmp[2] = 0; 5673bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij tm.tm_min = atoi (tmp); 5683bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij strncpy (tmp, ptpdate + 13, 2); 5693bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij tmp[2] = 0; 5703bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij tm.tm_sec = atoi (tmp); 571e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij tm.tm_isdst = -1; 5723bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij return mktime (&tm); 5733bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij} 5743bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij 575b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 576b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_OI (PTPParams *params, unsigned char* data, PTPObjectInfo *oi, unsigned int len) 577eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 578eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint8_t filenamelen; 579eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint8_t capturedatelen; 580eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij char *capture_date; 581eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 582eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->StorageID=dtoh32a(&data[PTP_oi_StorageID]); 583eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ObjectFormat=dtoh16a(&data[PTP_oi_ObjectFormat]); 584eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ProtectionStatus=dtoh16a(&data[PTP_oi_ProtectionStatus]); 585eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ObjectCompressedSize=dtoh32a(&data[PTP_oi_ObjectCompressedSize]); 5860546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner 5870546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner /* Stupid Samsung Galaxy developers emit a 64bit objectcompressedsize */ 5880546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner if ((data[PTP_oi_filenamelen] == 0) && (data[PTP_oi_filenamelen+4] != 0)) { 5890546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner params->ocs64 = 1; 5900546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner data += 4; 5910546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner } 592eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ThumbFormat=dtoh16a(&data[PTP_oi_ThumbFormat]); 593eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ThumbCompressedSize=dtoh32a(&data[PTP_oi_ThumbCompressedSize]); 594eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ThumbPixWidth=dtoh32a(&data[PTP_oi_ThumbPixWidth]); 595eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ThumbPixHeight=dtoh32a(&data[PTP_oi_ThumbPixHeight]); 596eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ImagePixWidth=dtoh32a(&data[PTP_oi_ImagePixWidth]); 597eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ImagePixHeight=dtoh32a(&data[PTP_oi_ImagePixHeight]); 598eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ImageBitDepth=dtoh32a(&data[PTP_oi_ImageBitDepth]); 599eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ParentObject=dtoh32a(&data[PTP_oi_ParentObject]); 600eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->AssociationType=dtoh16a(&data[PTP_oi_AssociationType]); 601eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->AssociationDesc=dtoh32a(&data[PTP_oi_AssociationDesc]); 602eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->SequenceNumber=dtoh32a(&data[PTP_oi_SequenceNumber]); 6030546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner 604eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->Filename= ptp_unpack_string(params, data, PTP_oi_filenamelen, &filenamelen); 605eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 606eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij capture_date = ptp_unpack_string(params, data, 607eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_oi_filenamelen+filenamelen*2+1, &capturedatelen); 608eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij /* subset of ISO 8601, without '.s' tenths of second and 609eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij * time zone 610eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij */ 6116db174f4d18af574fab991309e11010aa0eb4543Linus Walleij oi->CaptureDate = ptp_unpack_PTPTIME(capture_date); 612eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij free(capture_date); 613eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 6143bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij /* now the modification date ... */ 615eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij capture_date = ptp_unpack_string(params, data, 616eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_oi_filenamelen+filenamelen*2 617eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij +capturedatelen*2+2,&capturedatelen); 6186db174f4d18af574fab991309e11010aa0eb4543Linus Walleij oi->ModificationDate = ptp_unpack_PTPTIME(capture_date); 619eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij free(capture_date); 620eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 621eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 622eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* Custom Type Value Assignement (without Length) macro frequently used below */ 623b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define CTVAL(target,func) { \ 624b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (total - *offset < sizeof(target)) \ 625b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 0; \ 626b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij target = func(&data[*offset]); \ 627b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij *offset += sizeof(target); \ 628eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 629eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 630b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define RARR(val,member,func) { \ 631b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij int n,j; \ 632b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (total - *offset < sizeof(uint32_t)) \ 633b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 0; \ 634b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij n = dtoh32a (&data[*offset]); \ 635b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij *offset += sizeof(uint32_t); \ 636b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij \ 637b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij val->a.count = n; \ 638b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij val->a.v = malloc(sizeof(val->a.v[0])*n); \ 639b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!val->a.v) return 0; \ 640b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (j=0;j<n;j++) \ 641b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij CTVAL(val->a.v[j].member, func); \ 642b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij} 643eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 644b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline int 645b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_DPV ( 646b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij PTPParams *params, unsigned char* data, int *offset, int total, 647b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij PTPPropertyValue* value, uint16_t datatype 648b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij) { 649eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij switch (datatype) { 650b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_INT8: 651b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij CTVAL(value->i8,dtoh8a); 652b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 653b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_UINT8: 654b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij CTVAL(value->u8,dtoh8a); 655b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 656b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_INT16: 657b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij CTVAL(value->i16,dtoh16a); 658b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 659b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_UINT16: 660b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij CTVAL(value->u16,dtoh16a); 661b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 662b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_INT32: 663b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij CTVAL(value->i32,dtoh32a); 664b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 665b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_UINT32: 666b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij CTVAL(value->u32,dtoh32a); 667b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 668abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij case PTP_DTC_INT64: 669abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij CTVAL(value->i64,dtoh64a); 670abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij break; 671abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij case PTP_DTC_UINT64: 672abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij CTVAL(value->u64,dtoh64a); 673abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij break; 674abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij 675037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij case PTP_DTC_UINT128: 676037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij *offset += 16; 677037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij /*fprintf(stderr,"unhandled unpack of uint128n");*/ 678037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij break; 679037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij case PTP_DTC_INT128: 680037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij *offset += 16; 681037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij /*fprintf(stderr,"unhandled unpack of int128n");*/ 682037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij break; 683037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij 684037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij 685037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij 686b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AINT8: 687b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij RARR(value,i8,dtoh8a); 688b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 689b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AUINT8: 690b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij RARR(value,u8,dtoh8a); 691b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 692b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AUINT16: 693b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij RARR(value,u16,dtoh16a); 694b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 695b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AINT16: 696b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij RARR(value,i16,dtoh16a); 697b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 698b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AUINT32: 699b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij RARR(value,u32,dtoh32a); 700b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 701b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AINT32: 702b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij RARR(value,i32,dtoh32a); 703b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 704abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij case PTP_DTC_AUINT64: 705abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij RARR(value,u64,dtoh64a); 706abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij break; 707abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij case PTP_DTC_AINT64: 708abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij RARR(value,i64,dtoh64a); 709abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij break; 710b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij /* XXX: other int types are unimplemented */ 711b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij /* XXX: other int arrays are unimplemented also */ 712b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_STR: { 713b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij uint8_t len; 714b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij /* XXX: max size */ 715b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij value->str = ptp_unpack_string(params,data,*offset,&len); 716b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij *offset += len*2+1; 717b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!value->str) 718deddc3490b3084b802737017982285bfa58b382fLinus Walleij return 1; 719b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 720eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 721037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij default: 722037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij return 0; 723b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 724b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 1; 725eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 726eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 727eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* Device Property pack/unpack */ 728eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 729eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_dpd_DevicePropertyCode 0 730eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_dpd_DataType 2 731eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_dpd_GetSet 4 732eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_dpd_FactoryDefaultValue 5 733eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 734b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline int 735b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_DPD (PTPParams *params, unsigned char* data, PTPDevicePropDesc *dpd, unsigned int dpdlen) 736eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 737b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij int offset=0, ret; 738eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 739b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij memset (dpd, 0, sizeof(*dpd)); 740eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij dpd->DevicePropertyCode=dtoh16a(&data[PTP_dpd_DevicePropertyCode]); 741eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij dpd->DataType=dtoh16a(&data[PTP_dpd_DataType]); 742eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij dpd->GetSet=dtoh8a(&data[PTP_dpd_GetSet]); 743deddc3490b3084b802737017982285bfa58b382fLinus Walleij dpd->FormFlag=PTP_DPFF_None; 744b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 745b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij offset = PTP_dpd_FactoryDefaultValue; 746b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->FactoryDefaultValue, dpd->DataType); 747b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 748deddc3490b3084b802737017982285bfa58b382fLinus Walleij if ((dpd->DataType == PTP_DTC_STR) && (offset == dpdlen)) 749deddc3490b3084b802737017982285bfa58b382fLinus Walleij return 1; 750b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->CurrentValue, dpd->DataType); 751b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 752b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 753b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij /* if offset==0 then Data Type format is not supported by this 754b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij code or the Data Type is a string (with two empty strings as 755b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij values). In both cases Form Flag should be set to 0x00 and FORM is 756b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij not present. */ 757b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 758b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (offset==PTP_dpd_FactoryDefaultValue) 759b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 1; 760b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 761b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpd->FormFlag=dtoh8a(&data[offset]); 762b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij offset+=sizeof(uint8_t); 763eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 764eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij switch (dpd->FormFlag) { 765b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DPFF_Range: 766b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->FORM.Range.MinimumValue, dpd->DataType); 767b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 768b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->FORM.Range.MaximumValue, dpd->DataType); 769b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 770b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->FORM.Range.StepSize, dpd->DataType); 771b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 772eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij break; 773b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DPFF_Enumeration: { 774b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij int i; 775eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define N dpd->FORM.Enum.NumberOfValues 776b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij N = dtoh16a(&data[offset]); 777b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij offset+=sizeof(uint16_t); 778b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpd->FORM.Enum.SupportedValue = malloc(N*sizeof(dpd->FORM.Enum.SupportedValue[0])); 779b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!dpd->FORM.Enum.SupportedValue) 780b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij goto outofmemory; 781b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 782b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij memset (dpd->FORM.Enum.SupportedValue,0 , N*sizeof(dpd->FORM.Enum.SupportedValue[0])); 783b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<N;i++) { 784b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->FORM.Enum.SupportedValue[i], dpd->DataType); 785b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 786b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij /* Slightly different handling here. The HP PhotoSmart 120 787b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij * specifies an enumeration with N in wrong endian 788b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij * 00 01 instead of 01 00, so we count the enum just until the 789b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij * the end of the packet. 790b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij */ 791b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) { 792b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!i) 793b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij goto outofmemory; 794b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpd->FORM.Enum.NumberOfValues = i; 795b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 796eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 797b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 798eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 799eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 800b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#undef N 801b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 1; 802b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijoutofmemory: 803b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ptp_free_devicepropdesc(dpd); 804b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 0; 805eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 806eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 807b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij/* (MTP) Object Property pack/unpack */ 808b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_opd_ObjectPropertyCode 0 809b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_opd_DataType 2 810b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_opd_GetSet 4 811b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_opd_FactoryDefaultValue 5 812eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 813b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline int 814b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_OPD (PTPParams *params, unsigned char* data, PTPObjectPropDesc *opd, unsigned int opdlen) 815eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 816b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij int offset=0, ret; 817b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 818b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij memset (opd, 0, sizeof(*opd)); 819b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij opd->ObjectPropertyCode=dtoh16a(&data[PTP_opd_ObjectPropertyCode]); 820b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij opd->DataType=dtoh16a(&data[PTP_opd_DataType]); 821b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij opd->GetSet=dtoh8a(&data[PTP_opd_GetSet]); 822b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 823b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij offset = PTP_opd_FactoryDefaultValue; 824b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, opdlen, &opd->FactoryDefaultValue, opd->DataType); 825b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 826b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 827b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij opd->GroupCode=dtoh32a(&data[offset]); 828b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij offset+=sizeof(uint32_t); 829b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 830b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij opd->FormFlag=dtoh8a(&data[offset]); 831b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij offset+=sizeof(uint8_t); 832b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 833b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij switch (opd->FormFlag) { 834b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_OPFF_Range: 835b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, opdlen, &opd->FORM.Range.MinimumValue, opd->DataType); 836b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 837b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, opdlen, &opd->FORM.Range.MaximumValue, opd->DataType); 838b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 839b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, opdlen, &opd->FORM.Range.StepSize, opd->DataType); 840b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 841b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 842b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_OPFF_Enumeration: { 843b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij int i; 844b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define N opd->FORM.Enum.NumberOfValues 845b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij N = dtoh16a(&data[offset]); 846b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij offset+=sizeof(uint16_t); 847b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij opd->FORM.Enum.SupportedValue = malloc(N*sizeof(opd->FORM.Enum.SupportedValue[0])); 848b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!opd->FORM.Enum.SupportedValue) 849b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij goto outofmemory; 850b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 851b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij memset (opd->FORM.Enum.SupportedValue,0 , N*sizeof(opd->FORM.Enum.SupportedValue[0])); 852b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<N;i++) { 853b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, opdlen, &opd->FORM.Enum.SupportedValue[i], opd->DataType); 854b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 855b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij /* Slightly different handling here. The HP PhotoSmart 120 856b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij * specifies an enumeration with N in wrong endian 857b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij * 00 01 instead of 01 00, so we count the enum just until the 858b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij * the end of the packet. 859b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij */ 860b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) { 861b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!i) 862b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij goto outofmemory; 863b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij opd->FORM.Enum.NumberOfValues = i; 864b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 865b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 866b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 867b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#undef N 868b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 869eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 870b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 1; 871b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijoutofmemory: 872b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ptp_free_objectpropdesc(opd); 873b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 0; 874eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 875eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 876eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 877b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint32_t 878b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_pack_DPV (PTPParams *params, PTPPropertyValue* value, unsigned char** dpvptr, uint16_t datatype) 879eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 880b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij unsigned char* dpv=NULL; 881eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint32_t size=0; 882b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij int i; 883eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 884eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij switch (datatype) { 885b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_INT8: 886b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(int8_t); 887b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 888b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod8a(dpv,value->i8); 889b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 890b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_UINT8: 891b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint8_t); 892b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 893b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod8a(dpv,value->u8); 894b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 895b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_INT16: 896b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(int16_t); 897b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 898b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(dpv,value->i16); 899b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 900b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_UINT16: 901b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint16_t); 902b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 903b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(dpv,value->u16); 904b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 905b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_INT32: 906b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(int32_t); 907b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 908b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(dpv,value->i32); 909b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 910b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_UINT32: 911b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint32_t); 912b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 913b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(dpv,value->u32); 914b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 915abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij case PTP_DTC_INT64: 916abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij size=sizeof(int64_t); 917abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij dpv=malloc(size); 918abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij htod64a(dpv,value->i64); 919abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij break; 920abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij case PTP_DTC_UINT64: 921abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij size=sizeof(uint64_t); 922abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij dpv=malloc(size); 923abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij htod64a(dpv,value->u64); 924abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij break; 925b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AUINT8: 926b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint32_t)+value->a.count*sizeof(uint8_t); 927b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 928b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(dpv,value->a.count); 929b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<value->a.count;i++) 930cc2659036a503fce161cb77d9b0af17a52d7437bRichard Low htod8a(&dpv[sizeof(uint32_t)+i*sizeof(uint8_t)],value->a.v[i].u8); 931b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 932b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AINT8: 933b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint32_t)+value->a.count*sizeof(int8_t); 934b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 935b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(dpv,value->a.count); 936b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<value->a.count;i++) 937cc2659036a503fce161cb77d9b0af17a52d7437bRichard Low htod8a(&dpv[sizeof(uint32_t)+i*sizeof(int8_t)],value->a.v[i].i8); 938b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 939b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AUINT16: 940b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint32_t)+value->a.count*sizeof(uint16_t); 941b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 942b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(dpv,value->a.count); 943b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<value->a.count;i++) 944cc2659036a503fce161cb77d9b0af17a52d7437bRichard Low htod16a(&dpv[sizeof(uint32_t)+i*sizeof(uint16_t)],value->a.v[i].u16); 945b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 946b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AINT16: 947b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint32_t)+value->a.count*sizeof(int16_t); 948b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 949b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(dpv,value->a.count); 950b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<value->a.count;i++) 951cc2659036a503fce161cb77d9b0af17a52d7437bRichard Low htod16a(&dpv[sizeof(uint32_t)+i*sizeof(int16_t)],value->a.v[i].i16); 952b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 953b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AUINT32: 954b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint32_t)+value->a.count*sizeof(uint32_t); 955b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 956b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(dpv,value->a.count); 957b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<value->a.count;i++) 958cc2659036a503fce161cb77d9b0af17a52d7437bRichard Low htod32a(&dpv[sizeof(uint32_t)+i*sizeof(uint32_t)],value->a.v[i].u32); 959b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 960b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AINT32: 961b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint32_t)+value->a.count*sizeof(int32_t); 962b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 963b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(dpv,value->a.count); 964b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<value->a.count;i++) 965cc2659036a503fce161cb77d9b0af17a52d7437bRichard Low htod32a(&dpv[sizeof(uint32_t)+i*sizeof(int32_t)],value->a.v[i].i32); 966b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 967abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij case PTP_DTC_AUINT64: 968abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij size=sizeof(uint32_t)+value->a.count*sizeof(uint64_t); 969abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij dpv=malloc(size); 970abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij htod32a(dpv,value->a.count); 971abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij for (i=0;i<value->a.count;i++) 972cc2659036a503fce161cb77d9b0af17a52d7437bRichard Low htod64a(&dpv[sizeof(uint32_t)+i*sizeof(uint64_t)],value->a.v[i].u64); 973abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij break; 974abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij case PTP_DTC_AINT64: 975abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij size=sizeof(uint32_t)+value->a.count*sizeof(int64_t); 976abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij dpv=malloc(size); 977abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij htod32a(dpv,value->a.count); 978abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij for (i=0;i<value->a.count;i++) 979cc2659036a503fce161cb77d9b0af17a52d7437bRichard Low htod64a(&dpv[sizeof(uint32_t)+i*sizeof(int64_t)],value->a.v[i].i64); 980abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij break; 981b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij /* XXX: other int types are unimplemented */ 982b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_STR: { 983735f41692934a716158cf051d76e988febeca7eeLinus Walleij dpv=ptp_get_packed_stringcopy(params, value->str, &size); 984eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij break; 985b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 986eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 987eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij *dpvptr=dpv; 988eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return size; 98999310d4445697da39f22dff35457c75e35e97171Linus Walleij} 99099310d4445697da39f22dff35457c75e35e97171Linus Walleij 99199310d4445697da39f22dff35457c75e35e97171Linus Walleij#define MAX_MTP_PROPS 127 99299310d4445697da39f22dff35457c75e35e97171Linus Walleijstatic inline uint32_t 9931e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleijptp_pack_OPL (PTPParams *params, MTPProperties *props, int nrofprops, unsigned char** opldataptr) 99499310d4445697da39f22dff35457c75e35e97171Linus Walleij{ 99599310d4445697da39f22dff35457c75e35e97171Linus Walleij unsigned char* opldata; 9961e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij MTPProperties *propitr; 99799310d4445697da39f22dff35457c75e35e97171Linus Walleij unsigned char *packedprops[MAX_MTP_PROPS]; 99899310d4445697da39f22dff35457c75e35e97171Linus Walleij uint32_t packedpropslens[MAX_MTP_PROPS]; 99939b9374f23451201dece736db13f0f648584dc32Linus Walleij uint32_t packedobjecthandles[MAX_MTP_PROPS]; 100099310d4445697da39f22dff35457c75e35e97171Linus Walleij uint16_t packedpropsids[MAX_MTP_PROPS]; 100199310d4445697da39f22dff35457c75e35e97171Linus Walleij uint16_t packedpropstypes[MAX_MTP_PROPS]; 100299310d4445697da39f22dff35457c75e35e97171Linus Walleij uint32_t totalsize = 0; 100399310d4445697da39f22dff35457c75e35e97171Linus Walleij uint32_t bufp = 0; 100499310d4445697da39f22dff35457c75e35e97171Linus Walleij uint32_t noitems = 0; 100599310d4445697da39f22dff35457c75e35e97171Linus Walleij uint32_t i; 100699310d4445697da39f22dff35457c75e35e97171Linus Walleij 100799310d4445697da39f22dff35457c75e35e97171Linus Walleij totalsize = sizeof(uint32_t); /* 4 bytes to store the number of elements */ 10081e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij propitr = props; 10091e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij while (nrofprops-- && noitems < MAX_MTP_PROPS) { 10106c0a6ce803cf79802b1c48339adf0964db30ec83Richard Low /* Object Handle */ 101139b9374f23451201dece736db13f0f648584dc32Linus Walleij packedobjecthandles[noitems]=propitr->ObjectHandle; 101299310d4445697da39f22dff35457c75e35e97171Linus Walleij totalsize += sizeof(uint32_t); /* Object ID */ 101399310d4445697da39f22dff35457c75e35e97171Linus Walleij /* Metadata type */ 101499310d4445697da39f22dff35457c75e35e97171Linus Walleij packedpropsids[noitems]=propitr->property; 101599310d4445697da39f22dff35457c75e35e97171Linus Walleij totalsize += sizeof(uint16_t); 101699310d4445697da39f22dff35457c75e35e97171Linus Walleij /* Data type */ 101799310d4445697da39f22dff35457c75e35e97171Linus Walleij packedpropstypes[noitems]= propitr->datatype; 101899310d4445697da39f22dff35457c75e35e97171Linus Walleij totalsize += sizeof(uint16_t); 101999310d4445697da39f22dff35457c75e35e97171Linus Walleij /* Add each property to be sent. */ 102099310d4445697da39f22dff35457c75e35e97171Linus Walleij packedpropslens[noitems] = ptp_pack_DPV (params, &propitr->propval, &packedprops[noitems], propitr->datatype); 102199310d4445697da39f22dff35457c75e35e97171Linus Walleij totalsize += packedpropslens[noitems]; 102299310d4445697da39f22dff35457c75e35e97171Linus Walleij noitems ++; 10231e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij propitr ++; 102499310d4445697da39f22dff35457c75e35e97171Linus Walleij } 102599310d4445697da39f22dff35457c75e35e97171Linus Walleij 102699310d4445697da39f22dff35457c75e35e97171Linus Walleij /* Allocate memory for the packed property list */ 102799310d4445697da39f22dff35457c75e35e97171Linus Walleij opldata = malloc(totalsize); 102899310d4445697da39f22dff35457c75e35e97171Linus Walleij 102999310d4445697da39f22dff35457c75e35e97171Linus Walleij htod32a(&opldata[bufp],noitems); 103099310d4445697da39f22dff35457c75e35e97171Linus Walleij bufp += 4; 103199310d4445697da39f22dff35457c75e35e97171Linus Walleij 103299310d4445697da39f22dff35457c75e35e97171Linus Walleij /* Copy into a nice packed list */ 103399310d4445697da39f22dff35457c75e35e97171Linus Walleij for (i = 0; i < noitems; i++) { 103499310d4445697da39f22dff35457c75e35e97171Linus Walleij /* Object ID */ 10356c0a6ce803cf79802b1c48339adf0964db30ec83Richard Low htod32a(&opldata[bufp],packedobjecthandles[i]); 103699310d4445697da39f22dff35457c75e35e97171Linus Walleij bufp += sizeof(uint32_t); 103799310d4445697da39f22dff35457c75e35e97171Linus Walleij htod16a(&opldata[bufp],packedpropsids[i]); 103899310d4445697da39f22dff35457c75e35e97171Linus Walleij bufp += sizeof(uint16_t); 103999310d4445697da39f22dff35457c75e35e97171Linus Walleij htod16a(&opldata[bufp],packedpropstypes[i]); 104099310d4445697da39f22dff35457c75e35e97171Linus Walleij bufp += sizeof(uint16_t); 104199310d4445697da39f22dff35457c75e35e97171Linus Walleij /* The copy the actual property */ 104299310d4445697da39f22dff35457c75e35e97171Linus Walleij memcpy(&opldata[bufp], packedprops[i], packedpropslens[i]); 104399310d4445697da39f22dff35457c75e35e97171Linus Walleij bufp += packedpropslens[i]; 104499310d4445697da39f22dff35457c75e35e97171Linus Walleij free(packedprops[i]); 104599310d4445697da39f22dff35457c75e35e97171Linus Walleij } 104699310d4445697da39f22dff35457c75e35e97171Linus Walleij *opldataptr = opldata; 104799310d4445697da39f22dff35457c75e35e97171Linus Walleij return totalsize; 1048eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 1049eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 10501e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleijstatic int 10511e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij_compare_func(const void* x, const void *y) { 10521e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij const MTPProperties *px = x; 10531e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij const MTPProperties *py = y; 10541e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij 10551e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij return px->ObjectHandle - py->ObjectHandle; 10561e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij} 10571e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij 10588d82d2f4b0794e41ec26289045867eebb3496b8cRichard Lowstatic inline int 10591e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleijptp_unpack_OPL (PTPParams *params, unsigned char* data, MTPProperties **pprops, unsigned int len) 10608d82d2f4b0794e41ec26289045867eebb3496b8cRichard Low{ 1061277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij uint32_t prop_count = dtoh32a(data); 10621e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij MTPProperties *props = NULL; 1063277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij int offset = 0, i; 1064277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij 1065277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij if (prop_count == 0) { 10661e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij *pprops = NULL; 1067277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij return 0; 1068277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij } 1069d49955b02710fd4bb1eda73b8bd6abb3f17f7c15Linus Walleij ptp_debug (params ,"Unpacking MTP OPL, size %d (prop_count %d)", len, prop_count); 1070277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij data += sizeof(uint32_t); 10713bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij len -= sizeof(uint32_t); 10721e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij props = malloc(prop_count * sizeof(MTPProperties)); 10731e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij if (!props) return 0; 1074277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij for (i = 0; i < prop_count; i++) { 10753bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij if (len <= 0) { 1076d49955b02710fd4bb1eda73b8bd6abb3f17f7c15Linus Walleij ptp_debug (params ,"short MTP Object Property List at property %d (of %d)", i, prop_count); 10773bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij ptp_debug (params ,"device probably needs DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST_ALL", i); 10783bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij ptp_debug (params ,"or even DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST", i); 1079d49955b02710fd4bb1eda73b8bd6abb3f17f7c15Linus Walleij qsort (props, i, sizeof(MTPProperties),_compare_func); 1080d49955b02710fd4bb1eda73b8bd6abb3f17f7c15Linus Walleij *pprops = props; 10813bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij return i; 10823bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij } 10831e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij props[i].ObjectHandle = dtoh32a(data); 1084277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij data += sizeof(uint32_t); 1085277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij len -= sizeof(uint32_t); 1086277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij 10871e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij props[i].property = dtoh16a(data); 1088277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij data += sizeof(uint16_t); 1089277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij len -= sizeof(uint16_t); 1090277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij 10911e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij props[i].datatype = dtoh16a(data); 1092277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij data += sizeof(uint16_t); 1093277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij len -= sizeof(uint16_t); 1094277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij 1095277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij offset = 0; 10961e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij ptp_unpack_DPV(params, data, &offset, len, &props[i].propval, props[i].datatype); 1097277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij data += offset; 1098277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij len -= offset; 1099277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij } 11001e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij qsort (props, prop_count, sizeof(MTPProperties),_compare_func); 11011e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij *pprops = props; 1102277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij return prop_count; 11038d82d2f4b0794e41ec26289045867eebb3496b8cRichard Low} 11048d82d2f4b0794e41ec26289045867eebb3496b8cRichard Low 1105eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* 1106eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP USB Event container unpack 1107eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij Copyright (c) 2003 Nikolai Kopanygin 1108eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij*/ 1109eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 1110eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_ec_Length 0 1111eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_ec_Type 4 1112eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_ec_Code 6 1113eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_ec_TransId 8 1114eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_ec_Param1 12 1115eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_ec_Param2 16 1116eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_ec_Param3 20 1117eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 1118b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 11197e75653e64021908ca66b155eeb950d8304c87d8Linus Walleijptp_unpack_EC (PTPParams *params, unsigned char* data, PTPContainer *ec, unsigned int len) 1120eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 11217e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij int length; 11227e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij int type; 11237e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij 1124eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij if (data==NULL) 1125eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return; 11267e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij memset(ec,0,sizeof(*ec)); 11277e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij length=dtoh32a(&data[PTP_ec_Length]); 11287e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij type = dtoh16a(&data[PTP_ec_Type]); 1129b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 11307e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij ec->Code=dtoh16a(&data[PTP_ec_Code]); 11317e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij ec->Transaction_ID=dtoh32a(&data[PTP_ec_TransId]); 11327e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij 11337e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij if (type!=PTP_USB_CONTAINER_EVENT) { 11347e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij ptp_debug (params, "Unknown canon event type %d (code=%x,tid=%x), please report!",type,ec->Code,ec->Transaction_ID); 11357e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij return; 11367e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij } 11377e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij if (length>=(PTP_ec_Param1+4)) { 11387e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij ec->Param1=dtoh32a(&data[PTP_ec_Param1]); 11397e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij ec->Nparam=1; 11407e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij } 11417e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij if (length>=(PTP_ec_Param2+4)) { 11427e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij ec->Param2=dtoh32a(&data[PTP_ec_Param2]); 11437e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij ec->Nparam=2; 11447e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij } 11457e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij if (length>=(PTP_ec_Param3+4)) { 11467e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij ec->Param3=dtoh32a(&data[PTP_ec_Param3]); 11477e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij ec->Nparam=3; 11487e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij } 1149eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 1150eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 1151eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* 1152eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP Canon Folder Entry unpack 1153eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij Copyright (c) 2003 Nikolai Kopanygin 1154eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij*/ 1155eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_cfe_ObjectHandle 0 1156eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_cfe_ObjectFormatCode 4 1157eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_cfe_Flags 6 1158eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_cfe_ObjectSize 7 1159eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_cfe_Time 11 1160eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_cfe_Filename 15 1161eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 1162b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 1163b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_Canon_FE (PTPParams *params, unsigned char* data, PTPCANONFolderEntry *fe) 1164eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 1165eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij int i; 1166eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij if (data==NULL) 1167eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return; 1168eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij fe->ObjectHandle=dtoh32a(&data[PTP_cfe_ObjectHandle]); 1169eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij fe->ObjectFormatCode=dtoh16a(&data[PTP_cfe_ObjectFormatCode]); 1170eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij fe->Flags=dtoh8a(&data[PTP_cfe_Flags]); 1171b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij fe->ObjectSize=dtoh32a((unsigned char*)&data[PTP_cfe_ObjectSize]); 1172eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij fe->Time=(time_t)dtoh32a(&data[PTP_cfe_Time]); 1173eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij for (i=0; i<PTP_CANON_FilenameBufferLen; i++) 1174b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij fe->Filename[i]=(char)dtoh8a(&data[PTP_cfe_Filename+i]); 1175b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij} 1176b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 117796aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij/* 117896aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij PTP Canon EOS Folder Entry unpack 117996aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij0: 00 00 08 a0 objectid 118096aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij4: 01 00 02 00 storageid 118196aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij8: 01 30 00 00 ofc 118296aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij12: 01 00 118396aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij14: 00 00 118496aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij16: 11 00 00 00 118596aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij20: 00 00 00 00 118696aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij24: 00 00 00 80 118796aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij28: 00 00 08 a0 118896aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij32: 4d 49 53 43-00 00 00 00 00 00 00 00 name 118996aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij00 00 00 00 119096aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij84 bc 74 46 objectime 119196aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij 119296aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij 119396aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij(normal PTP GetObjectInfo) 119496aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus WalleijObjectInfo for 'IMG_0199.JPG': 119596aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij Object ID: 0x92740c72 119696aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij StorageID: 0x00020001 119796aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij ObjectFormat: 0x3801 119896aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij ProtectionStatus: 0x0000 119996aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij ObjectCompressedSize: 2217241 120096aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij ThumbFormat: 0x3808 120196aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij ThumbCompressedSize: 5122 120296aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij ThumbPixWidth: 160 120396aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij ThumbPixHeight: 120 120496aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij ImagePixWidth: 4000 120596aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij ImagePixHeight: 3000 120696aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij ImageBitDepth: 24 120796aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij ParentObject: 0x92740000 120896aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij AssociationType: 0x0000 120996aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij AssociationDesc: 0x00000000 121096aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij SequenceNumber: 0x00000000 121196aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij ModificationDate: 0x4d985ff0 121296aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij CaptureDate: 0x4d985ff0 121396aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij 121496aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij0010 38 00 00 00 Size of this entry 121596aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij0014 72 0c 74 92 OID 121696aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij0018 01 00 02 00 StorageID 121796aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij001c 01 38 00 00 OFC 121896aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij0020 00 00 00 00 00 00 00 00 ? 121996aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij0028 19 d5 21 00 Size 122096aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij002c 00 00 74 92 ? 122196aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij0030 70 0c 74 92 OID 122296aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij0034 49 4d 47 5f-30 31 39 39 2e 4a 50 47 IMG_0199.JPG 122396aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij0040 00 00 00 00 122496aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij0044 10 7c 98 4d Time 122596aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij 122696aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij 122796aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij*/ 122896aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij#define PTP_cefe_ObjectHandle 0 122996aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij#define PTP_cefe_StorageID 4 123096aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij#define PTP_cefe_ObjectFormatCode 8 123196aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij#define PTP_cefe_Flags 12 123296aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij#define PTP_cefe_ObjectSize 20 123396aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij#define PTP_cefe_Filename 32 123496aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij#define PTP_cefe_Time 48 123596aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij 123696aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleijstatic inline void 123796aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleijptp_unpack_Canon_EOS_FE (PTPParams *params, unsigned char* data, PTPCANONFolderEntry *fe) 123896aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij{ 123996aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij int i; 124096aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij 124196aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij fe->ObjectHandle=dtoh32a(&data[PTP_cefe_ObjectHandle]); 124296aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij fe->ObjectFormatCode=dtoh16a(&data[PTP_cefe_ObjectFormatCode]); 124396aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij fe->Flags=dtoh8a(&data[PTP_cefe_Flags]); 124496aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij fe->ObjectSize=dtoh32a((unsigned char*)&data[PTP_cefe_ObjectSize]); 124596aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij fe->Time=(time_t)dtoh32a(&data[PTP_cefe_Time]); 124696aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij for (i=0; i<PTP_CANON_FilenameBufferLen; i++) 124796aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij fe->Filename[i]=(char)data[PTP_cefe_Filename+i]; 124896aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij} 124996aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij 125096aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij 12511a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleijstatic inline uint16_t 12521a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleijptp_unpack_EOS_ImageFormat (PTPParams* params, unsigned char** data ) 12531a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij{ 12541a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij /* 12550546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner EOS ImageFormat entries (of at least the 5DM2 and the 400D) look like this: 12561a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij uint32: number of entries / generated files (1 or 2) 12571a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij uint32: size of this entry in bytes (most likely allways 0x10) 12581a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij uint32: image type (1 == JPG, 6 == RAW) 12590546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner uint32: image size (0 == Large, 1 == Medium, 2 == Small, 0xe == S1, 0xf == S2, 0x10 == S3) 12601a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij uint32: image compression (2 == Standard/JPG, 3 == Fine/JPG, 4 == Lossles/RAW) 12610546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner If the number of entries is 2 the last 4 uint32 repeat. 12621a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 12631a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij example: 12641a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 0: 0x 1 12651a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 1: 0x 10 12661a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 2: 0x 6 12671a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 3: 0x 1 12681a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 4: 0x 4 12691a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 12700546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner The idea is to simply 'condense' these values to just one uint16 to be able to conveniently 12711a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij use the available enumeration facilities (look-up table). The image size and compression 12721a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij values fully describe the image format. Hence we generate a uint16 with the four nibles set 12731a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij as follows: entry 1 size | entry 1 compression | entry 2 size | entry 2 compression. 12741a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij The above example would result in the value 0x1400. 12750546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner 12760546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner The EOS 5D Mark III (and possibly other high-end EOS as well) added the extra fancy S1, S2 12770546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner and S3 JPEG options. S1 replaces the old Small. -1 the S1/S2/S3 to prevent the 0x10 overflow. 12781a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij */ 12791a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 12801a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij const unsigned char* d = *data; 12811a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij uint32_t n = dtoh32a( d ); 12821a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij uint32_t l, s1, c1, s2 = 0, c2 = 0; 12831a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 12841a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij if (n != 1 && n !=2) { 12851a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij ptp_debug (params, "parsing EOS ImageFormat property failed (n != 1 && n != 2: %d)", n); 12861a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij return 0; 12871a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij } 12881a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 12891a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij l = dtoh32a( d+=4 ); 12901a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij if (l != 0x10) { 12911a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij ptp_debug (params, "parsing EOS ImageFormat property failed (l != 0x10: 0x%x)", l); 12921a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij return 0; 12931a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij } 12941a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 12951a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij d+=4; /* skip type */ 12961a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij s1 = dtoh32a( d+=4 ); 12971a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij c1 = dtoh32a( d+=4 ); 12981a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 12991a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij if (n == 2) { 13001a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij l = dtoh32a( d+=4 ); 13011a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij if (l != 0x10) { 13021a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij ptp_debug (params, "parsing EOS ImageFormat property failed (l != 0x10: 0x%x)", l); 13031a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij return 0; 13041a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij } 13051a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij d+=4; /* skip type */ 13061a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij s2 = dtoh32a( d+=4 ); 13071a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij c2 = dtoh32a( d+=4 ); 13081a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij } 13091a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 13101a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij *data = (unsigned char*) d+4; 13111a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 13120546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner /* deal with S1/S2/S3 JPEG sizes, see above. */ 13130546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner if( s1 >= 0xe ) 13140546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner s1--; 13150546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner if( s2 >= 0xe ) 13160546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner s2--; 13170546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner 13181a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij return ((s1 & 0xF) << 12) | ((c1 & 0xF) << 8) | ((s2 & 0xF) << 4) | ((c2 & 0xF) << 0); 13191a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij} 13201a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 13211a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleijstatic inline uint32_t 13221a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleijptp_pack_EOS_ImageFormat (PTPParams* params, unsigned char* data, uint16_t value) 13231a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij{ 13241a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij uint32_t n = (value & 0xFF) ? 2 : 1; 13251a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij uint32_t s = 4 + 0x10 * n; 13261a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 13271a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij if( !data ) 13281a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij return s; 13291a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 13300546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner#define PACK_5DM3_SMALL_JPEG_SIZE( X ) (X) >= 0xd ? (X)+1 : (X) 13310546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner 13321a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij htod32a(data+=0, n); 13331a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij htod32a(data+=4, 0x10); 13341a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij htod32a(data+=4, ((value >> 8) & 0xF) == 4 ? 6 : 1); 13350546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner htod32a(data+=4, PACK_5DM3_SMALL_JPEG_SIZE((value >> 12) & 0xF)); 13361a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij htod32a(data+=4, (value >> 8) & 0xF); 13371a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 13381a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij if (n==2) { 13391a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij htod32a(data+=4, 0x10); 13401a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij htod32a(data+=4, ((value >> 0) & 0xF) == 4 ? 6 : 1); 13410546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner htod32a(data+=4, PACK_5DM3_SMALL_JPEG_SIZE((value >> 4) & 0xF)); 13421a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij htod32a(data+=4, (value >> 0) & 0xF); 13431a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij } 13441a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 13450546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner#undef PACK_5DM3_SMALL_JPEG_SIZE 13460546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner 13470546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner return s; 13480546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner} 13490546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner 13500546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissnerstatic inline char* 13510546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissnerptp_unpack_EOS_CustomFuncEx (PTPParams* params, unsigned char** data ) 13520546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner{ 13530546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner uint32_t s = dtoh32a( *data ); 13540546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner uint32_t n = s/4, i; 13550546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner char* str = (char*)malloc( s ); // n is size in uint32, average len(itoa(i)) < 4 -> alloc n chars 13560546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner if (!str) 13570546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner return str; 13580546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner char* p = str; 13590546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner 13600546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner for (i=0; i < n; ++i) 13610546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner p += sprintf(p, "%x,", dtoh32a( *data + 4*i )); 13620546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner 13630546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner return str; 13640546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner} 13650546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner 13660546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissnerstatic inline uint32_t 13670546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissnerptp_pack_EOS_CustomFuncEx (PTPParams* params, unsigned char* data, char* str) 13680546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner{ 13690546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner uint32_t s = strtoul(str, NULL, 16); 13700546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner uint32_t n = s/4, i, v; 13710546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner 13720546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner if (!data) 13730546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner return s; 13740546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner 13750546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner for (i=0; i<n; i++) 13760546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner { 13770546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner v = strtoul(str, &str, 16); 13780546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner str++; // skip the ',' delimiter 13790546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner htod32a(data + i*4, v); 13800546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner } 13810546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner 13821a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij return s; 13831a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij} 13841a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 1385b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij/* 1386f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij PTP EOS Changes Entry unpack 1387f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij*/ 1388f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij#define PTP_ece_Size 0 1389f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij#define PTP_ece_Type 4 1390f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij 1391f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij#define PTP_ece_Prop_Subtype 8 /* only for properties */ 1392f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij#define PTP_ece_Prop_Val_Data 0xc /* only for properties */ 1393f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij#define PTP_ece_Prop_Desc_Type 0xc /* only for property descs */ 1394f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij#define PTP_ece_Prop_Desc_Count 0x10 /* only for property descs */ 1395f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij#define PTP_ece_Prop_Desc_Data 0x14 /* only for property descs */ 1396f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij 1397d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij/* for PTP_EC_CANON_EOS_RequestObjectTransfer */ 1398d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij#define PTP_ece_OI_ObjectID 8 1399d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij#define PTP_ece_OI_OFC 0x0c 1400d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij#define PTP_ece_OI_Size 0x14 1401d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij#define PTP_ece_OI_Name 0x1c 1402d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij 1403d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij/* for PTP_EC_CANON_EOS_ObjectAddedEx */ 1404d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij#define PTP_ece_OA_ObjectID 8 1405d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij#define PTP_ece_OA_StorageID 0x0c 1406d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij#define PTP_ece_OA_OFC 0x10 1407d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij#define PTP_ece_OA_Size 0x1c 1408d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij#define PTP_ece_OA_Parent 0x20 1409d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij#define PTP_ece_OA_Name 0x28 1410f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij 1411f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleijstatic inline int 1412f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleijptp_unpack_CANON_changes (PTPParams *params, unsigned char* data, int datasize, PTPCanon_changes_entry **ce) 1413f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij{ 1414f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij int i = 0, entries = 0; 1415f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij unsigned char *curdata = data; 1416f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij 1417f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if (data==NULL) 1418f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij return 0; 1419f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij while (curdata - data < datasize) { 1420f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij uint32_t size = dtoh32a(&curdata[PTP_ece_Size]); 1421f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij uint32_t type = dtoh32a(&curdata[PTP_ece_Type]); 1422f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij 1423f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij curdata += size; 1424f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if ((size == 8) && (type == 0)) 1425f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1426f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij entries++; 1427f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 14289d22ce0e3214f38d30435fb9ec8ff2c8c6c4191eLinus Walleij *ce = malloc (sizeof(PTPCanon_changes_entry)*(entries+1)); 1429f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if (!*ce) return 0; 1430f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij 1431f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij curdata = data; 1432f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij while (curdata - data < datasize) { 1433f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij uint32_t size = dtoh32a(&curdata[PTP_ece_Size]); 1434f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij uint32_t type = dtoh32a(&curdata[PTP_ece_Type]); 1435f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij 1436d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij (*ce)[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN; 1437d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij (*ce)[i].u.info = NULL; 1438f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij switch (type) { 1439d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_EC_CANON_EOS_ObjectAddedEx: 1440f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij (*ce)[i].type = PTP_CANON_EOS_CHANGES_TYPE_OBJECTINFO; 1441d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij (*ce)[i].u.object.oid = dtoh32a(&curdata[PTP_ece_OA_ObjectID]); 1442d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij (*ce)[i].u.object.oi.StorageID = dtoh32a(&curdata[PTP_ece_OA_StorageID]); 1443d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij (*ce)[i].u.object.oi.ParentObject = dtoh32a(&curdata[PTP_ece_OA_Parent]); 1444d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij (*ce)[i].u.object.oi.ObjectFormat = dtoh16a(&curdata[PTP_ece_OA_OFC]); 1445d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij (*ce)[i].u.object.oi.ObjectCompressedSize= dtoh32a(&curdata[PTP_ece_OA_Size]); 1446d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij (*ce)[i].u.object.oi.Filename = strdup(((char*)&curdata[PTP_ece_OA_Name])); 1447d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij ptp_debug (params, "event %d: objectinfo added oid %08lx, parent %08lx, ofc %04x, size %d, filename %s", i, (*ce)[i].u.object.oid, (*ce)[i].u.object.oi.ParentObject, (*ce)[i].u.object.oi.ObjectFormat, (*ce)[i].u.object.oi.ObjectCompressedSize, (*ce)[i].u.object.oi.Filename); 1448d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij break; 1449d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_EC_CANON_EOS_RequestObjectTransfer: 1450d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij (*ce)[i].type = PTP_CANON_EOS_CHANGES_TYPE_OBJECTTRANSFER; 1451f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij (*ce)[i].u.object.oid = dtoh32a(&curdata[PTP_ece_OI_ObjectID]); 1452d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij (*ce)[i].u.object.oi.StorageID = 0; /* use as marker */ 1453f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij (*ce)[i].u.object.oi.ObjectFormat = dtoh16a(&curdata[PTP_ece_OI_OFC]); 1454d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij (*ce)[i].u.object.oi.ParentObject = 0; /* check, but use as marker */ 1455f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij (*ce)[i].u.object.oi.ObjectCompressedSize = dtoh32a(&curdata[PTP_ece_OI_Size]); 1456f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij (*ce)[i].u.object.oi.Filename = strdup(((char*)&curdata[PTP_ece_OI_Name])); 14573bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij 1458d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij ptp_debug (params, "event %d: request object transfer oid %08lx, ofc %04x, size %d, filename %s", i, (*ce)[i].u.object.oid, (*ce)[i].u.object.oi.ObjectFormat, (*ce)[i].u.object.oi.ObjectCompressedSize, (*ce)[i].u.object.oi.Filename); 1459f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 14607e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_EC_CANON_EOS_AvailListChanged: { /* property desc */ 1461f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij uint32_t proptype = dtoh32a(&curdata[PTP_ece_Prop_Subtype]); 1462f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij uint32_t propxtype = dtoh32a(&curdata[PTP_ece_Prop_Desc_Type]); 1463f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij uint32_t propxcnt = dtoh32a(&curdata[PTP_ece_Prop_Desc_Count]); 1464e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij unsigned char *xdata = &curdata[PTP_ece_Prop_Desc_Data]; 1465f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij int j; 1466f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij PTPDevicePropDesc *dpd; 1467f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij 14687e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij ptp_debug (params, "event %d: EOS prop %04x desc record, datasize %d, propxtype %d", i, proptype, size-PTP_ece_Prop_Desc_Data, propxtype); 1469f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij for (j=0;j<params->nrofcanon_props;j++) 1470f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if (params->canon_props[j].proptype == proptype) 1471f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1472f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if (j==params->nrofcanon_props) { 14733bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij ptp_debug (params, "event %d: propdesc %x, default value not found.", i, proptype); 1474f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1475f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 1476f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij dpd = ¶ms->canon_props[j].dpd; 14777e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij /* 1 - uint16 ? 14787e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij * 3 - uint16 14797e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij * 7 - string? 14807e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij */ 1481f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if (propxtype != 3) { 14823bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij ptp_debug (params, "event %d: propxtype is %x for %04x, unhandled.", i, propxtype, proptype); 14833bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij for (j=0;j<size-PTP_ece_Prop_Desc_Data;j++) 1484e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij ptp_debug (params, " %d: %02x", j, xdata[j]); 1485f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1486f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 14871a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij if (! propxcnt) 14881a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij break; 14891a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 14901a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij ptp_debug (params, "event %d: propxtype is %x, prop is 0x%04x, data type is 0x%04x, propxcnt is %d.", 14911a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij i, propxtype, proptype, dpd->DataType, propxcnt); 14921a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij dpd->FormFlag = PTP_DPFF_Enumeration; 14931a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij dpd->FORM.Enum.NumberOfValues = propxcnt; 14940d762ccc39331608119dd0267021b165e22de499Linus Walleij if (dpd->FORM.Enum.SupportedValue) free (dpd->FORM.Enum.SupportedValue); 14951a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij dpd->FORM.Enum.SupportedValue = malloc (sizeof (PTPPropertyValue)*propxcnt); 14961a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 14971a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij switch (proptype) { 14981a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DPC_CANON_EOS_ImageFormat: 14991a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DPC_CANON_EOS_ImageFormatCF: 15001a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DPC_CANON_EOS_ImageFormatSD: 15011a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DPC_CANON_EOS_ImageFormatExtHD: 15021a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij /* special handling of ImageFormat properties */ 1503f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij for (j=0;j<propxcnt;j++) { 15041a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij dpd->FORM.Enum.SupportedValue[j].u16 = 1505e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij dtoh16( ptp_unpack_EOS_ImageFormat( params, &xdata ) ); 15061a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij ptp_debug (params, "event %d: suppval[%d] of %x is 0x%x.", i, j, proptype, dpd->FORM.Enum.SupportedValue[j].u16); 15071a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij } 15081a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij break; 15091a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij default: 15101a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij /* 'normal' enumerated types */ 15111a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij switch (dpd->DataType) { 15121a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij#define XX( TYPE, CONV )\ 15131a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij for (j=0;j<propxcnt;j++) { \ 1514e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij dpd->FORM.Enum.SupportedValue[j].TYPE = CONV(xdata); \ 1515e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij ptp_debug (params, "event %d: suppval[%d] of %x is 0x%x.", i, j, proptype, CONV(xdata)); \ 1516e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij xdata += 4; /* might only be for propxtype 3 */ \ 15171a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij } \ 15181a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij break; 15191a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 15201a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DTC_INT16: XX( i16, dtoh16a ); 15211a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DTC_UINT32: XX( u32, dtoh32a ); 15221a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DTC_UINT16: XX( u16, dtoh16a ); 15231a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DTC_UINT8: XX( u8, dtoh8a ); 15241a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij#undef XX 15251a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij default: 1526e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij ptp_debug (params ,"event %d: data type 0x%04x of %x unhandled, raw values:", i, dpd->DataType, proptype, dtoh32a(xdata)); 1527e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij for (j=0;j<(size-PTP_ece_Prop_Desc_Data)/4;j++, xdata+=4) /* 4 is good for propxtype 3 */ 1528e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij ptp_debug (params, " %3d: 0x%8x", j, dtoh32a(xdata)); 15291a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij break; 1530f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 1531f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 1532f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1533f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 15347e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_EC_CANON_EOS_PropValueChanged: 1535f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if (size >= 0xc) { /* property info */ 1536f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij int j; 1537f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij uint32_t proptype = dtoh32a(&curdata[PTP_ece_Prop_Subtype]); 1538e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij unsigned char *xdata = &curdata[PTP_ece_Prop_Val_Data]; 1539f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij PTPDevicePropDesc *dpd; 1540f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij 15411a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij ptp_debug (params, "event %d: EOS prop %04x info record, datasize is %d", i, proptype, size-PTP_ece_Prop_Val_Data); 1542f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij for (j=0;j<params->nrofcanon_props;j++) 1543f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if (params->canon_props[j].proptype == proptype) 1544f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1545f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if (j<params->nrofcanon_props) { 1546f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if ( (params->canon_props[j].size != size) || 1547e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij (memcmp(params->canon_props[j].data,xdata,size-PTP_ece_Prop_Val_Data))) { 1548f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij params->canon_props[j].data = realloc(params->canon_props[j].data,size-PTP_ece_Prop_Val_Data); 1549e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij memcpy (params->canon_props[j].data,xdata,size-PTP_ece_Prop_Val_Data); 1550f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 1551f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } else { 1552f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if (j) 1553f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij params->canon_props = realloc(params->canon_props, sizeof(params->canon_props[0])*(j+1)); 1554f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij else 1555f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij params->canon_props = malloc(sizeof(params->canon_props[0])); 1556f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij params->canon_props[j].type = type; 1557f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij params->canon_props[j].proptype = proptype; 1558f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij params->canon_props[j].size = size; 1559f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij params->canon_props[j].data = malloc(size-PTP_ece_Prop_Val_Data); 1560e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij memcpy(params->canon_props[j].data, xdata, size-PTP_ece_Prop_Val_Data); 1561f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij memset (¶ms->canon_props[j].dpd,0,sizeof(params->canon_props[j].dpd)); 1562f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij params->canon_props[j].dpd.GetSet = 1; 1563f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij params->canon_props[j].dpd.FormFlag = PTP_DPFF_None; 1564f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij params->nrofcanon_props = j+1; 1565f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 1566f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij dpd = ¶ms->canon_props[j].dpd; 15671a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 1568d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij (*ce)[i].type = PTP_CANON_EOS_CHANGES_TYPE_PROPERTY; 1569d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij (*ce)[i].u.propid = proptype; 1570d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij 15711a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij /* fix GetSet value */ 15721a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij switch (proptype) { 15731a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij#define XX(x) case PTP_DPC_CANON_##x: 15741a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_FocusMode) 15751a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_BatteryPower) 15761a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_BatterySelect) 15771a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_ModelID) 15781a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_PTPExtensionVersion) 15791a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_DPOFVersion) 15801a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_AvailableShots) 15811a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_CurrentStorage) 15821a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_CurrentFolder) 15831a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_MyMenu) 15841a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_MyMenuList) 15851a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_HDDirectoryStructure) 15861a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_BatteryInfo) 15871a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_AdapterInfo) 15881a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_LensStatus) 15891a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_CardExtension) 15901a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_TempStatus) 15911a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_ShutterCounter) 15921a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_SerialNumber) 15931a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_DepthOfFieldPreview) 15941a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_EVFRecordStatus) 15951a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_LvAfSystem) 15961a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_FocusInfoEx) 15971a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_DepthOfField) 15981a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_Brightness) 15991a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_EFComp) 16001a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_LensName) 16011a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_LensID) 16021a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij#undef XX 16031a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij dpd->GetSet = PTP_DPGS_Get; 16041a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij break; 16051a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij } 16061a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 16071a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij /* set DataType */ 1608f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij switch (proptype) { 1609ac052c1ac330b94932d2b4f774e0053e78e91216Linus Walleij case PTP_DPC_CANON_EOS_CameraTime: 1610d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_AvailableShots: 1611d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_CaptureDestination: 1612d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_WhiteBalanceXA: 1613d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_WhiteBalanceXB: 1614d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_CurrentStorage: 1615d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_CurrentFolder: 1616d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_ShutterCounter: 1617d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_ModelID: 1618d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_LensID: 1619d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_StroboFiring: 1620ac052c1ac330b94932d2b4f774e0053e78e91216Linus Walleij dpd->DataType = PTP_DTC_UINT32; 1621ac052c1ac330b94932d2b4f774e0053e78e91216Linus Walleij break; 16220d762ccc39331608119dd0267021b165e22de499Linus Walleij /* enumeration for AEM is never provided, but is available to set */ 16230d762ccc39331608119dd0267021b165e22de499Linus Walleij case PTP_DPC_CANON_EOS_AutoExposureMode: 16240d762ccc39331608119dd0267021b165e22de499Linus Walleij dpd->DataType = PTP_DTC_UINT16; 16250d762ccc39331608119dd0267021b165e22de499Linus Walleij dpd->FormFlag = PTP_DPFF_Enumeration; 16260d762ccc39331608119dd0267021b165e22de499Linus Walleij dpd->FORM.Enum.NumberOfValues = 0; 16270d762ccc39331608119dd0267021b165e22de499Linus Walleij break; 1628f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case PTP_DPC_CANON_EOS_Aperture: 1629f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case PTP_DPC_CANON_EOS_ShutterSpeed: 1630f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case PTP_DPC_CANON_EOS_ISOSpeed: 16317e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_FocusMode: 16327e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_ColorSpace: 16337e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_BatteryPower: 1634e29ca68e54b8dd04e54499d6b5fa8668770a20cfLinus Walleij case PTP_DPC_CANON_EOS_BatterySelect: 1635d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_PTPExtensionVersion: 16361a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DPC_CANON_EOS_DriveMode: 16371a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DPC_CANON_EOS_AEB: 1638e29ca68e54b8dd04e54499d6b5fa8668770a20cfLinus Walleij case PTP_DPC_CANON_EOS_BracketMode: 1639e29ca68e54b8dd04e54499d6b5fa8668770a20cfLinus Walleij case PTP_DPC_CANON_EOS_QuickReviewTime: 16400d762ccc39331608119dd0267021b165e22de499Linus Walleij case PTP_DPC_CANON_EOS_EVFMode: 16410d762ccc39331608119dd0267021b165e22de499Linus Walleij case PTP_DPC_CANON_EOS_EVFOutputDevice: 1642f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij dpd->DataType = PTP_DTC_UINT16; 1643f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1644f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case PTP_DPC_CANON_EOS_PictureStyle: 1645f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case PTP_DPC_CANON_EOS_WhiteBalance: 1646f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case PTP_DPC_CANON_EOS_MeteringMode: 16477e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_ExpCompensation: /* actually int8 if you calculate */ 1648f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij dpd->DataType = PTP_DTC_UINT8; 1649f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1650f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case PTP_DPC_CANON_EOS_Owner: 16511a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DPC_CANON_EOS_Artist: 16521a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DPC_CANON_EOS_Copyright: 16531a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DPC_CANON_EOS_SerialNumber: 16541a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DPC_CANON_EOS_LensName: 1655f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij dpd->DataType = PTP_DTC_STR; 1656f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 16577e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_WhiteBalanceAdjustA: 16587e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_WhiteBalanceAdjustB: 16597e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij dpd->DataType = PTP_DTC_INT16; 16607e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij break; 16617e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij /* unknown props, listed from dump.... all 16 bit, but vals might be smaller */ 16627e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case 0xd114: 16637e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_DPOFVersion: 16641a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij dpd->DataType = PTP_DTC_UINT16; 16651a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij ptp_debug (params, "event %d: Unknown EOS property %04x, datasize is %d, using uint16", i ,proptype, size-PTP_ece_Prop_Val_Data); 16661a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij for (j=0;j<size-PTP_ece_Prop_Val_Data;j++) 1667e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij ptp_debug (params, " %d: %02x", j, xdata[j]); 16681a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij break; 16697e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_CustomFunc1: 16707e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_CustomFunc2: 16717e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_CustomFunc3: 16727e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_CustomFunc4: 16737e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_CustomFunc5: 16747e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_CustomFunc6: 16757e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_CustomFunc7: 16767e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_CustomFunc8: 16777e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_CustomFunc9: 16787e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_CustomFunc10: 16797e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_CustomFunc11: 16801a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij dpd->DataType = PTP_DTC_UINT8; 16811a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij ptp_debug (params, "event %d: Unknown EOS property %04x, datasize is %d, using uint8", i ,proptype, size-PTP_ece_Prop_Val_Data); 16827e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij for (j=0;j<size-PTP_ece_Prop_Val_Data;j++) 1683e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij ptp_debug (params, " %d: %02x", j, xdata[j]); 16841a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij /* custom func entries look like this on the 400D: '5 0 0 0 ?' = 4 bytes size + 1 byte data */ 1685e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij xdata += 4; 16867e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij break; 16877e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij /* yet unknown 32bit props */ 16887e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_ColorTemperature: 16897e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_WftStatus: 16907e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_LensStatus: 16917e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_CardExtension: 16927e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_TempStatus: 16937e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_PhotoStudioMode: 16947e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_DepthOfFieldPreview: 16957e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_EVFSharpness: 16967e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_EVFWBMode: 16977e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_EVFClickWBCoeffs: 16987e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_EVFColorTemp: 1699d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_EVFRecordStatus: 1700d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_ExposureSimMode: 1701d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_LvAfSystem: 1702d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_MovSize: 1703d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_DepthOfField: 1704d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_LvViewTypeSelect: 17050d762ccc39331608119dd0267021b165e22de499Linus Walleij dpd->DataType = PTP_DTC_UINT32; 17067e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij ptp_debug (params, "event %d: Unknown EOS property %04x, datasize is %d, using uint32", i ,proptype, size-PTP_ece_Prop_Val_Data); 17071a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij if ((size-PTP_ece_Prop_Val_Data) % sizeof(uint32_t) != 0) 17081a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij ptp_debug (params, "event %d: Warning: datasize modulo sizeof(uint32) is not 0: ", i, (size-PTP_ece_Prop_Val_Data) % sizeof(uint32_t) ); 17091a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij for (j=0;j<(size-PTP_ece_Prop_Val_Data)/sizeof(uint32_t);j++) 1710e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij ptp_debug (params, " %d: 0x%8x", j, ((uint32_t*)xdata)[j]); 17117e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij break; 1712d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij /* ImageFormat properties have to be ignored here, see special handling below */ 1713d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij case PTP_DPC_CANON_EOS_ImageFormat: 1714d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij case PTP_DPC_CANON_EOS_ImageFormatCF: 1715d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij case PTP_DPC_CANON_EOS_ImageFormatSD: 1716d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij case PTP_DPC_CANON_EOS_ImageFormatExtHD: 17170546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner case PTP_DPC_CANON_EOS_CustomFuncEx: 1718d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij break; 1719f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij default: 17203bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij ptp_debug (params, "event %d: Unknown EOS property %04x, datasize is %d", i ,proptype, size-PTP_ece_Prop_Val_Data); 17213bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij for (j=0;j<size-PTP_ece_Prop_Val_Data;j++) 1722e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij ptp_debug (params, " %d: %02x", j, xdata[j]); 1723f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1724f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 1725f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij switch (dpd->DataType) { 1726ac052c1ac330b94932d2b4f774e0053e78e91216Linus Walleij case PTP_DTC_UINT32: 1727e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij dpd->FactoryDefaultValue.u32 = dtoh32a(xdata); 1728e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij dpd->CurrentValue.u32 = dtoh32a(xdata); 17293bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij ptp_debug (params ,"event %d: currentvalue of %x is %x", i, proptype, dpd->CurrentValue.u32); 1730ac052c1ac330b94932d2b4f774e0053e78e91216Linus Walleij break; 1731f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case PTP_DTC_UINT16: 1732e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij dpd->FactoryDefaultValue.u16 = dtoh16a(xdata); 1733e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij dpd->CurrentValue.u16 = dtoh16a(xdata); 17343bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij ptp_debug (params,"event %d: currentvalue of %x is %x", i, proptype, dpd->CurrentValue.u16); 1735f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1736f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case PTP_DTC_UINT8: 1737e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij dpd->FactoryDefaultValue.u8 = dtoh8a(xdata); 1738e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij dpd->CurrentValue.u8 = dtoh8a(xdata); 17393bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij ptp_debug (params,"event %d: currentvalue of %x is %x", i, proptype, dpd->CurrentValue.u8); 1740f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1741f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case PTP_DTC_STR: { 17421a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij#if 0 /* 5D MII and 400D aktually store plain ASCII in their string properties */ 1743f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij uint8_t len = 0; 1744f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij dpd->FactoryDefaultValue.str = ptp_unpack_string(params, data, 0, &len); 1745f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij dpd->CurrentValue.str = ptp_unpack_string(params, data, 0, &len); 17461a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij#else 17470d762ccc39331608119dd0267021b165e22de499Linus Walleij if (dpd->FactoryDefaultValue.str) free (dpd->FactoryDefaultValue.str); 1748e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij dpd->FactoryDefaultValue.str = strdup( (char*)xdata ); 17490d762ccc39331608119dd0267021b165e22de499Linus Walleij 17500d762ccc39331608119dd0267021b165e22de499Linus Walleij if (dpd->CurrentValue.str) free (dpd->CurrentValue.str); 1751e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij dpd->CurrentValue.str = strdup( (char*)xdata ); 17521a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij#endif 17537e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij ptp_debug (params,"event %d: currentvalue of %x is %s", i, proptype, dpd->CurrentValue.str); 1754f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1755f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 1756f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij default: 1757f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij /* debug is printed in switch above this one */ 1758f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1759f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 17601a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 17610546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner /* ImageFormat and customFuncEx special handling (WARNING: dont move this in front of the dpd->DataType switch!) */ 1762d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij switch (proptype) { 1763d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij case PTP_DPC_CANON_EOS_ImageFormat: 1764d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij case PTP_DPC_CANON_EOS_ImageFormatCF: 1765d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij case PTP_DPC_CANON_EOS_ImageFormatSD: 1766d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij case PTP_DPC_CANON_EOS_ImageFormatExtHD: 1767d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij dpd->DataType = PTP_DTC_UINT16; 1768e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij dpd->FactoryDefaultValue.u16 = ptp_unpack_EOS_ImageFormat( params, &xdata ); 1769d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij dpd->CurrentValue.u16 = dpd->FactoryDefaultValue.u16; 1770d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij ptp_debug (params,"event %d: decoded imageformat, currentvalue of %x is %x", i, proptype, dpd->CurrentValue.u16); 1771d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij break; 17720546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner case PTP_DPC_CANON_EOS_CustomFuncEx: 17730546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner dpd->DataType = PTP_DTC_STR; 17740546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner if (dpd->FactoryDefaultValue.str) free (dpd->FactoryDefaultValue.str); 17750546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner if (dpd->CurrentValue.str) free (dpd->CurrentValue.str); 17760546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner dpd->FactoryDefaultValue.str = ptp_unpack_EOS_CustomFuncEx( params, &data ); 17770546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner dpd->CurrentValue.str = strdup( (char*)dpd->FactoryDefaultValue.str ); 17780546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner ptp_debug (params,"event %d: decoded custom function, currentvalue of %x is %s", i, proptype, dpd->CurrentValue.str); 17790546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner break; 1780d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij } 1781d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij 1782f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1783f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 1784d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij case PTP_EC_CANON_EOS_CameraStatusChanged: 1785d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij ptp_debug (params, "event %d: EOS event CameraStatusChanged (size %d)", i, size); 1786d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij (*ce)[i].type = PTP_CANON_EOS_CHANGES_TYPE_CAMERASTATUS; 1787d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij (*ce)[i].u.status = dtoh32a(curdata+8); 17889e09ad0e32cbdac88637d4ee2cc02ca3b771ca40Linus Walleij params->eos_camerastatus = dtoh32a(curdata+8); 1789d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij break; 17907e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case 0: /* end marker */ 17917e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij if (size == 8) /* no output */ 17927e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij break; 17937e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij ptp_debug (params, "event %d: EOS event 0, but size %d", i, size); 17947e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij break; 179596aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij case PTP_EC_CANON_EOS_BulbExposureTime: 179696aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij (*ce)[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN; 179796aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij (*ce)[i].u.info = malloc(strlen("BulbExposureTime 123456789")); 179896aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij sprintf ((*ce)[i].u.info, "BulbExposureTime %d", dtoh32a(curdata+8)); 179996aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij break; 1800f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij default: 1801d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij switch (type) { 1802d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij#define XX(x) case PTP_EC_CANON_EOS_##x: \ 1803d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij ptp_debug (params, "event %d: unhandled EOS event "#x" (size %d)", i, size); \ 1804d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij (*ce)[i].u.info = malloc(strlen("unhandled EOS event "#x" (size 123456789)")); \ 1805d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij sprintf ((*ce)[i].u.info, "unhandled EOS event "#x" (size %d)", size); \ 1806d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij break; 1807d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(RequestGetEvent) 1808d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(ObjectRemoved) 1809d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(RequestGetObjectInfoEx) 1810d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(StorageStatusChanged) 1811d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(StorageInfoChanged) 1812d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(ObjectInfoChangedEx) 1813d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(ObjectContentChanged) 1814d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(WillSoonShutdown) 1815d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(ShutdownTimerUpdated) 1816d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(RequestCancelTransfer) 1817d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(RequestObjectTransferDT) 1818d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(RequestCancelTransferDT) 1819d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(StoreAdded) 1820d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(StoreRemoved) 1821d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(BulbExposureTime) 1822d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(RecordingTime) 1823d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(RequestObjectTransferTS) 1824d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(AfResult) 1825d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij#undef XX 1826d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij default: 1827d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij ptp_debug (params, "event %d: unknown EOS event %04x", i, type); 1828d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij break; 1829d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij } 18307e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij if (size >= 0x8) { /* event info */ 18317e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij int j; 1832d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij for (j=8;j<size;j++) 1833d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij ptp_debug (params, " %d: %02x", j, curdata[j]); 18347e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij } 1835f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij (*ce)[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN; 1836f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1837f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 1838f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij curdata += size; 1839f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij i++; 18409d22ce0e3214f38d30435fb9ec8ff2c8c6c4191eLinus Walleij if ((size == 8) && (type == 0)) 18419d22ce0e3214f38d30435fb9ec8ff2c8c6c4191eLinus Walleij break; 1842f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 18430d762ccc39331608119dd0267021b165e22de499Linus Walleij if (!entries) { 18440d762ccc39331608119dd0267021b165e22de499Linus Walleij free (*ce); 18450d762ccc39331608119dd0267021b165e22de499Linus Walleij *ce = NULL; 18460d762ccc39331608119dd0267021b165e22de499Linus Walleij } 1847f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij return entries; 1848f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij} 1849f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij 1850f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij/* 1851b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij PTP USB Event container unpack for Nikon events. 1852b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij*/ 1853b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_nikon_ec_Length 0 1854b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_nikon_ec_Code 2 1855b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_nikon_ec_Param1 4 1856b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_nikon_ec_Size 6 1857b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 18587e75653e64021908ca66b155eeb950d8304c87d8Linus Walleijptp_unpack_Nikon_EC (PTPParams *params, unsigned char* data, unsigned int len, PTPContainer **ec, int *cnt) 1859b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij{ 1860b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij int i; 1861b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 1862b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij *ec = NULL; 1863b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (data == NULL) 1864b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return; 1865b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (len < PTP_nikon_ec_Code) 1866b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return; 1867b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij *cnt = dtoh16a(&data[PTP_nikon_ec_Length]); 1868b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (*cnt > (len-PTP_nikon_ec_Code)/PTP_nikon_ec_Size) /* broken cnt? */ 1869b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return; 18700d762ccc39331608119dd0267021b165e22de499Linus Walleij if (!*cnt) 18710d762ccc39331608119dd0267021b165e22de499Linus Walleij return; 18720d762ccc39331608119dd0267021b165e22de499Linus Walleij 18737e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij *ec = malloc(sizeof(PTPContainer)*(*cnt)); 1874b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 1875b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<*cnt;i++) { 18767e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij memset(&(*ec)[i],0,sizeof(PTPContainer)); 18777e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij (*ec)[i].Code = dtoh16a(&data[PTP_nikon_ec_Code+PTP_nikon_ec_Size*i]); 18787e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij (*ec)[i].Param1 = dtoh32a(&data[PTP_nikon_ec_Param1+PTP_nikon_ec_Size*i]); 18797e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij (*ec)[i].Nparam = 1; 1880b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 1881eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 1882eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 1883eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 1884b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint32_t 1885b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_pack_EK_text(PTPParams *params, PTPEKTextParams *text, unsigned char **data) { 1886b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij int i, len = 0; 1887b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij uint8_t retlen; 1888b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij unsigned char *curdata; 1889b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 1890b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij len = 2*(strlen(text->title)+1)+1+ 1891b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 2*(strlen(text->line[0])+1)+1+ 1892b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 2*(strlen(text->line[1])+1)+1+ 1893b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 2*(strlen(text->line[2])+1)+1+ 1894b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 2*(strlen(text->line[3])+1)+1+ 1895b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 2*(strlen(text->line[4])+1)+1+ 1896b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 4*2+2*4+2+4+2+5*4*2; 1897b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij *data = malloc(len); 1898b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!*data) return 0; 1899b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 1900b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij curdata = *data; 1901b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,100);curdata+=2; 1902b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,1);curdata+=2; 1903b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,0);curdata+=2; 1904b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,1000);curdata+=2; 1905b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 1906b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(curdata,0);curdata+=4; 1907b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(curdata,0);curdata+=4; 1908b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 1909b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,6);curdata+=2; 1910b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(curdata,0);curdata+=4; 1911b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 1912b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ptp_pack_string(params, text->title, curdata, 0, &retlen); curdata+=2*retlen+1;htod16a(curdata,0);curdata+=2; 1913b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,0x10);curdata+=2; 1914b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 1915b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<5;i++) { 1916b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ptp_pack_string(params, text->line[i], curdata, 0, &retlen); curdata+=2*retlen+1;htod16a(curdata,0);curdata+=2; 1917b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,0x10);curdata+=2; 1918b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,0x01);curdata+=2; 1919b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,0x02);curdata+=2; 1920b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,0x06);curdata+=2; 1921b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 1922b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return len; 1923b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij} 19247347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij 19257347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_version 0x00 19267347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_ofc 0x02 19277347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_unk1 0x04 19287347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_objectid 0x08 19297347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_parentid 0x0c 19307347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_previd 0x10 /* in same dir */ 19317347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_nextid 0x14 /* in same dir */ 19327347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_nextchild 0x18 /* down one dir */ 19337347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_storageid 0x1c /* only in storage entry */ 19347347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_name 0x20 19357347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_flags 0x2c 19367347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_size 0x30 19377347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_unixtime 0x34 19387347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_year 0x38 19397347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_month 0x39 19407347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_mday 0x3a 19417347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_hour 0x3b 19427347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_minute 0x3c 19437347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_second 0x3d 19447347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_unk2 0x3e 19457347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_thumbsize 0x40 19467347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_width 0x44 19477347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_height 0x48 19487347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij 19497347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleijstatic inline uint16_t 19507347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleijptp_unpack_canon_directory ( 19517347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij PTPParams *params, 19527347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij unsigned char *dir, 19537347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij uint32_t cnt, 19547347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij PTPObjectHandles *handles, 19557347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij PTPObjectInfo **oinfos, /* size(handles->n) */ 19567347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij uint32_t **flags /* size(handles->n) */ 19577347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij) { 19587347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij unsigned int i, j, nrofobs = 0, curob = 0; 19597347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij 19607347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ISOBJECT(ptr) (dtoh32a((ptr)+ptp_canon_dir_storageid) == 0xffffffff) 19617347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij for (i=0;i<cnt;i++) 19627347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (ISOBJECT(dir+i*0x4c)) nrofobs++; 19637347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij handles->n = nrofobs; 19647347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij handles->Handler = calloc(sizeof(handles->Handler[0]),nrofobs); 19657347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (!handles->Handler) return PTP_RC_GeneralError; 19667347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij *oinfos = calloc(sizeof((*oinfos)[0]),nrofobs); 19677347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (!*oinfos) return PTP_RC_GeneralError; 19687347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij *flags = calloc(sizeof((*flags)[0]),nrofobs); 19697347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (!*flags) return PTP_RC_GeneralError; 19707347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij 19717347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij /* Migrate data into objects ids, handles into 19727347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij * the object handler array. 19737347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij */ 19747347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij curob = 0; 19757347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij for (i=0;i<cnt;i++) { 19767347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij unsigned char *cur = dir+i*0x4c; 19777347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij PTPObjectInfo *oi = (*oinfos)+curob; 19787347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij 19797347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (!ISOBJECT(cur)) 19807347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij continue; 19817347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij 19827347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij handles->Handler[curob] = dtoh32a(cur + ptp_canon_dir_objectid); 19837347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij oi->StorageID = 0xffffffff; 19847347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij oi->ObjectFormat = dtoh16a(cur + ptp_canon_dir_ofc); 19857347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij oi->ParentObject = dtoh32a(cur + ptp_canon_dir_parentid); 19867347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij oi->Filename = strdup((char*)(cur + ptp_canon_dir_name)); 19877347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij oi->ObjectCompressedSize= dtoh32a(cur + ptp_canon_dir_size); 19887347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij oi->ThumbCompressedSize = dtoh32a(cur + ptp_canon_dir_thumbsize); 19897347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij oi->ImagePixWidth = dtoh32a(cur + ptp_canon_dir_width); 19907347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij oi->ImagePixHeight = dtoh32a(cur + ptp_canon_dir_height); 19917347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij oi->CaptureDate = oi->ModificationDate = dtoh32a(cur + ptp_canon_dir_unixtime); 19927347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij (*flags)[curob] = dtoh32a(cur + ptp_canon_dir_flags); 19937347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij curob++; 19947347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 19957347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij /* Walk over Storage ID entries and distribute the IDs to 19967347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij * the parent objects. */ 19977347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij for (i=0;i<cnt;i++) { 19987347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij unsigned char *cur = dir+i*0x4c; 19997347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij uint32_t nextchild = dtoh32a(cur + ptp_canon_dir_nextchild); 20007347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij 20017347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (ISOBJECT(cur)) 20027347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij continue; 20037347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij for (j=0;j<handles->n;j++) if (nextchild == handles->Handler[j]) break; 20047347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (j == handles->n) continue; 20057347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij (*oinfos)[j].StorageID = dtoh32a(cur + ptp_canon_dir_storageid); 20067347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 20077347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij /* Walk over all objects and distribute the storage ids */ 20087347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij while (1) { 20097347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij int changed = 0; 20107347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij for (i=0;i<cnt;i++) { 20117347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij unsigned char *cur = dir+i*0x4c; 20127347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij uint32_t oid = dtoh32a(cur + ptp_canon_dir_objectid); 20137347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij uint32_t nextoid = dtoh32a(cur + ptp_canon_dir_nextid); 20147347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij uint32_t nextchild = dtoh32a(cur + ptp_canon_dir_nextchild); 20157347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij uint32_t storageid; 20167347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij 20177347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (!ISOBJECT(cur)) 20187347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij continue; 20197347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij for (j=0;j<handles->n;j++) if (oid == handles->Handler[j]) break; 20207347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (j == handles->n) { 20217347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij /*fprintf(stderr,"did not find oid in lookup pass for current oid\n");*/ 20227347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij continue; 20237347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 20247347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij storageid = (*oinfos)[j].StorageID; 20257347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (storageid == 0xffffffff) continue; 20267347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (nextoid != 0xffffffff) { 20277347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij for (j=0;j<handles->n;j++) if (nextoid == handles->Handler[j]) break; 20287347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (j == handles->n) { 20297347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij /*fprintf(stderr,"did not find oid in lookup pass for next oid\n");*/ 20307347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij continue; 20317347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 20327347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if ((*oinfos)[j].StorageID == 0xffffffff) { 20337347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij (*oinfos)[j].StorageID = storageid; 20347347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij changed++; 20357347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 20367347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 20377347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (nextchild != 0xffffffff) { 20387347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij for (j=0;j<handles->n;j++) if (nextchild == handles->Handler[j]) break; 20397347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (j == handles->n) { 20407347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij /*fprintf(stderr,"did not find oid in lookup pass for next child\n");*/ 20417347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij continue; 20427347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 20437347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if ((*oinfos)[j].StorageID == 0xffffffff) { 20447347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij (*oinfos)[j].StorageID = storageid; 20457347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij changed++; 20467347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 20477347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 20487347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 20497347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij /* Check if we: 20507347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij * - changed no entry (nothing more to do) 20517347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij * - changed all of them at once (usually happens) 20527347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij * break if we do. 20537347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij */ 20547347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (!changed || (changed==nrofobs-1)) 20557347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij break; 20567347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 20577347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#undef ISOBJECT 20587347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij return PTP_RC_OK; 20597347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij} 2060