ptp-pack.c revision d6f25baf36fba05e3d8b2fa6d3cd4c026e2e6d33
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{ 148a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij int length; 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{ 159a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij int packedlen; 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 167d6f25baf36fba05e3d8b2fa6d3cd4c026e2e6d33Linus 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 1776db174f4d18af574fab991309e11010aa0eb4543Linus Walleij#else 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 } 1856db174f4d18af574fab991309e11010aa0eb4543Linus Walleij#endif 186a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij /* 187a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij * XXX: isn't packedlen just ( (uint16_t *)ucs2strp - ucs2str )? 188a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij * why do we need ucs2strlen()? 189a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij */ 190a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij packedlen = ucs2strlen(ucs2str); 191a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij if (packedlen > PTP_MAXSTRLEN-1) { 192a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij *len=0; 193a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij return; 194a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij } 195958441f8ed3e704cf07c9f600730f90a80a0d424Linus Walleij 1967f2343824550452974d78f5dbd94e64844355c33Linus Walleij /* number of characters including terminating 0 (PTP standard confirmed) */ 197a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij htod8a(&data[offset],packedlen+1); 198a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij memcpy(&data[offset+1], &ucs2str[0], packedlen * sizeof(ucs2str[0])); 199a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij htod16a(&data[offset+packedlen*2+1], 0x0000); /* terminate 0 */ 200958441f8ed3e704cf07c9f600730f90a80a0d424Linus Walleij 201958441f8ed3e704cf07c9f600730f90a80a0d424Linus Walleij /* The returned length is in number of characters */ 202048d938dc4889b74b258a786d5f53142b059fc32Linus Walleij *len = (uint8_t) packedlen+1; 203eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 204eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 205a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleijstatic inline unsigned char * 206735f41692934a716158cf051d76e988febeca7eeLinus Walleijptp_get_packed_stringcopy(PTPParams *params, char *string, uint32_t *packed_size) 207a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij{ 2088b42ca3d3baeb7c8f3e5eca88c613adb612e4ec0Richard Low uint8_t packed[PTP_MAXSTRLEN*2+3], len; 209a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij size_t plen; 210a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij unsigned char *retcopy = NULL; 211d47b9218023a6b943a93faa743712ae072cba85cRichard Low 212d47b9218023a6b943a93faa743712ae072cba85cRichard Low if (string == NULL) 213d47b9218023a6b943a93faa743712ae072cba85cRichard Low ptp_pack_string(params, "", (unsigned char*) packed, 0, &len); 214d47b9218023a6b943a93faa743712ae072cba85cRichard Low else 215d47b9218023a6b943a93faa743712ae072cba85cRichard Low ptp_pack_string(params, string, (unsigned char*) packed, 0, &len); 216d47b9218023a6b943a93faa743712ae072cba85cRichard Low 217958441f8ed3e704cf07c9f600730f90a80a0d424Linus Walleij /* returned length is in characters, then one byte for string length */ 218958441f8ed3e704cf07c9f600730f90a80a0d424Linus Walleij plen = len*2 + 1; 219048d938dc4889b74b258a786d5f53142b059fc32Linus Walleij 220a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij retcopy = malloc(plen); 221735f41692934a716158cf051d76e988febeca7eeLinus Walleij if (!retcopy) { 222735f41692934a716158cf051d76e988febeca7eeLinus Walleij *packed_size = 0; 223a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij return NULL; 224735f41692934a716158cf051d76e988febeca7eeLinus Walleij } 225a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij memcpy(retcopy, packed, plen); 226735f41692934a716158cf051d76e988febeca7eeLinus Walleij *packed_size = plen; 227a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij return (retcopy); 228a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij} 229a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij 230b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint32_t 231b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_uint32_t_array(PTPParams *params, unsigned char* data, uint16_t offset, uint32_t **array) 232eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 233eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint32_t n, i=0; 234eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 235eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij n=dtoh32a(&data[offset]); 236eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij *array = malloc (n*sizeof(uint32_t)); 237eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij while (n>i) { 238eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij (*array)[i]=dtoh32a(&data[offset+(sizeof(uint32_t)*(i+1))]); 239eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij i++; 240eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 241eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return n; 242eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 243eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 244b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint32_t 245f67bca9bde733f456ad341c0d852147124ab388aLinus Walleijptp_pack_uint32_t_array(PTPParams *params, uint32_t *array, uint32_t arraylen, unsigned char **data ) 246f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij{ 247f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij uint32_t i=0; 248f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij 249f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij *data = malloc ((arraylen+1)*sizeof(uint32_t)); 250f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij htod32a(&(*data)[0],arraylen); 251f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij for (i=0;i<arraylen;i++) 252f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij htod32a(&(*data)[sizeof(uint32_t)*(i+1)], array[i]); 253f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij return (arraylen+1)*sizeof(uint32_t); 254f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij} 255f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij 256f67bca9bde733f456ad341c0d852147124ab388aLinus Walleijstatic inline uint32_t 257b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_uint16_t_array(PTPParams *params, unsigned char* data, uint16_t offset, uint16_t **array) 258eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 259eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint32_t n, i=0; 260eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 261eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij n=dtoh32a(&data[offset]); 262eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij *array = malloc (n*sizeof(uint16_t)); 263eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij while (n>i) { 264eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij (*array)[i]=dtoh16a(&data[offset+(sizeof(uint16_t)*(i+2))]); 265eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij i++; 266eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 267eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return n; 268eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 269eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 270eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* DeviceInfo pack/unpack */ 271eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 272eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_di_StandardVersion 0 273eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_di_VendorExtensionID 2 274eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_di_VendorExtensionVersion 6 275eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_di_VendorExtensionDesc 8 276eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_di_FunctionalMode 8 277eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_di_OperationsSupported 10 278eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 279b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 280b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_DI (PTPParams *params, unsigned char* data, PTPDeviceInfo *di, unsigned int datalen) 281eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 282eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint8_t len; 283eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij unsigned int totallen; 2847e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij 285d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij if (!data) return; 286d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij if (datalen < 12) return; 2877347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij di->StandardVersion = dtoh16a(&data[PTP_di_StandardVersion]); 288eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->VendorExtensionID = 289eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij dtoh32a(&data[PTP_di_VendorExtensionID]); 290eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->VendorExtensionVersion = 291eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij dtoh16a(&data[PTP_di_VendorExtensionVersion]); 292eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->VendorExtensionDesc = 293eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij ptp_unpack_string(params, data, 294eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_VendorExtensionDesc, &len); 295eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen=len*2+1; 296eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->FunctionalMode = 297eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij dtoh16a(&data[PTP_di_FunctionalMode+totallen]); 298eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->OperationsSupported_len = ptp_unpack_uint16_t_array(params, data, 299eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 300eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &di->OperationsSupported); 301eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen=totallen+di->OperationsSupported_len*sizeof(uint16_t)+sizeof(uint32_t); 302eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->EventsSupported_len = ptp_unpack_uint16_t_array(params, data, 303eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 304eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &di->EventsSupported); 305eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen=totallen+di->EventsSupported_len*sizeof(uint16_t)+sizeof(uint32_t); 306eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->DevicePropertiesSupported_len = 307eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij ptp_unpack_uint16_t_array(params, data, 308eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 309eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &di->DevicePropertiesSupported); 310eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen=totallen+di->DevicePropertiesSupported_len*sizeof(uint16_t)+sizeof(uint32_t); 311eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->CaptureFormats_len = ptp_unpack_uint16_t_array(params, data, 312eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 313eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &di->CaptureFormats); 314eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen=totallen+di->CaptureFormats_len*sizeof(uint16_t)+sizeof(uint32_t); 315eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->ImageFormats_len = ptp_unpack_uint16_t_array(params, data, 316eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 317eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &di->ImageFormats); 318eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen=totallen+di->ImageFormats_len*sizeof(uint16_t)+sizeof(uint32_t); 319eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->Manufacturer = ptp_unpack_string(params, data, 320eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 321eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &len); 322eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen+=len*2+1; 323eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->Model = ptp_unpack_string(params, data, 324eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 325eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &len); 326eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen+=len*2+1; 327eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->DeviceVersion = ptp_unpack_string(params, data, 328eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 329eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &len); 330eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen+=len*2+1; 331eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->SerialNumber = ptp_unpack_string(params, data, 332eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 333eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &len); 334eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 335a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij 336e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleijstatic void inline 337a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleijptp_free_DI (PTPDeviceInfo *di) { 338a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij if (di->SerialNumber) free (di->SerialNumber); 339a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij if (di->DeviceVersion) free (di->DeviceVersion); 340a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij if (di->Model) free (di->Model); 341a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij if (di->Manufacturer) free (di->Manufacturer); 342a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij if (di->ImageFormats) free (di->ImageFormats); 343a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij if (di->CaptureFormats) free (di->CaptureFormats); 344a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij if (di->VendorExtensionDesc) free (di->VendorExtensionDesc); 345a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij if (di->OperationsSupported) free (di->OperationsSupported); 346a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij if (di->EventsSupported) free (di->EventsSupported); 347a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij if (di->DevicePropertiesSupported) free (di->DevicePropertiesSupported); 348a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij} 3497e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij 3507e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij/* EOS Device Info unpack */ 3517e75653e64021908ca66b155eeb950d8304c87d8Linus Walleijstatic inline void 3527e75653e64021908ca66b155eeb950d8304c87d8Linus Walleijptp_unpack_EOS_DI (PTPParams *params, unsigned char* data, PTPCanonEOSDeviceInfo *di, unsigned int datalen) 3537e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij{ 3547e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij int totallen = 4; 3557e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij if (datalen < 8) return; 3567e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij 3577e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij /* uint32_t struct len - ignore */ 3587e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij di->EventsSupported_len = ptp_unpack_uint32_t_array(params, data, 3597e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij totallen, &di->EventsSupported); 3607e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij if (!di->EventsSupported) return; 3617e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij totallen += di->EventsSupported_len*sizeof(uint32_t)+4; 3627e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij if (totallen >= datalen) return; 3637e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij 3647e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij di->DevicePropertiesSupported_len = ptp_unpack_uint32_t_array(params, data, 3657e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij totallen, &di->DevicePropertiesSupported); 3667e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij if (!di->DevicePropertiesSupported) return; 3677e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij totallen += di->DevicePropertiesSupported_len*sizeof(uint32_t)+4; 3687e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij if (totallen >= datalen) return; 3697e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij 3707e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij di->unk_len = ptp_unpack_uint32_t_array(params, data, 3717e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij totallen, &di->unk); 3727e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij if (!di->unk) return; 3737e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij totallen += di->unk_len*sizeof(uint32_t)+4; 3747e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij return; 3757e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij} 3760d762ccc39331608119dd0267021b165e22de499Linus Walleij 3770d762ccc39331608119dd0267021b165e22de499Linus Walleijstatic inline void 3780d762ccc39331608119dd0267021b165e22de499Linus Walleijptp_free_EOS_DI (PTPCanonEOSDeviceInfo *di) 3790d762ccc39331608119dd0267021b165e22de499Linus Walleij{ 3800d762ccc39331608119dd0267021b165e22de499Linus Walleij free (di->EventsSupported); 3810d762ccc39331608119dd0267021b165e22de499Linus Walleij free (di->DevicePropertiesSupported); 3820d762ccc39331608119dd0267021b165e22de499Linus Walleij free (di->unk); 3830d762ccc39331608119dd0267021b165e22de499Linus Walleij} 384eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 385eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* ObjectHandles array pack/unpack */ 386eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 387eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oh 0 388eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 389b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 390b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_OH (PTPParams *params, unsigned char* data, PTPObjectHandles *oh, unsigned int len) 391eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 392f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if (len) { 393f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij oh->n = ptp_unpack_uint32_t_array(params, data, PTP_oh, &oh->Handler); 394f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } else { 395f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij oh->n = 0; 396f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij oh->Handler = NULL; 397f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 398eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 399eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 400eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* StoreIDs array pack/unpack */ 401eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 402eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_sids 0 403eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 404b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 405b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_SIDs (PTPParams *params, unsigned char* data, PTPStorageIDs *sids, unsigned int len) 406eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 407eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij sids->n = ptp_unpack_uint32_t_array(params, data, PTP_sids, 408eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &sids->Storage); 409eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 410eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 411eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* StorageInfo pack/unpack */ 412eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 413eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_si_StorageType 0 414eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_si_FilesystemType 2 415eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_si_AccessCapability 4 416eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_si_MaxCapability 6 417eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_si_FreeSpaceInBytes 14 418eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_si_FreeSpaceInImages 22 419eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_si_StorageDescription 26 420eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 421b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 422b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_SI (PTPParams *params, unsigned char* data, PTPStorageInfo *si, unsigned int len) 423eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 424eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint8_t storagedescriptionlen; 425eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 426eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->StorageType=dtoh16a(&data[PTP_si_StorageType]); 427eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->FilesystemType=dtoh16a(&data[PTP_si_FilesystemType]); 428eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->AccessCapability=dtoh16a(&data[PTP_si_AccessCapability]); 429eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->MaxCapability=dtoh64a(&data[PTP_si_MaxCapability]); 430eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->FreeSpaceInBytes=dtoh64a(&data[PTP_si_FreeSpaceInBytes]); 431eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->FreeSpaceInImages=dtoh32a(&data[PTP_si_FreeSpaceInImages]); 432eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->StorageDescription=ptp_unpack_string(params, data, 433eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_si_StorageDescription, &storagedescriptionlen); 434eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->VolumeLabel=ptp_unpack_string(params, data, 435eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_si_StorageDescription+storagedescriptionlen*2+1, 436eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &storagedescriptionlen); 437eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 438eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 439eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* ObjectInfo pack/unpack */ 440eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 441eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_StorageID 0 442eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ObjectFormat 4 443eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ProtectionStatus 6 444eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ObjectCompressedSize 8 445eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ThumbFormat 12 446eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ThumbCompressedSize 14 447eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ThumbPixWidth 18 448eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ThumbPixHeight 22 449eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ImagePixWidth 26 450eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ImagePixHeight 30 451eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ImageBitDepth 34 452eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ParentObject 38 453eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_AssociationType 42 454eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_AssociationDesc 44 455eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_SequenceNumber 48 456eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_filenamelen 52 457eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_Filename 53 458eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 459a032327c7485548c42f8162f87469dc0e0dd2126Linus Walleij/* the max length assuming zero length dates. We have need 3 */ 460a032327c7485548c42f8162f87469dc0e0dd2126Linus Walleij/* bytes for these. */ 461a679b1c4d273f210abb6befc5d9954a25427c329Richard Low#define PTP_oi_MaxLen PTP_oi_Filename+(PTP_MAXSTRLEN+1)*2+3 462a679b1c4d273f210abb6befc5d9954a25427c329Richard Low 463b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint32_t 464b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_pack_OI (PTPParams *params, PTPObjectInfo *oi, unsigned char** oidataptr) 465eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 466b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij unsigned char* oidata; 467eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint8_t filenamelen; 468eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint8_t capturedatelen=0; 469a679b1c4d273f210abb6befc5d9954a25427c329Richard Low /* let's allocate some memory first; correct assuming zero length dates */ 470a679b1c4d273f210abb6befc5d9954a25427c329Richard Low oidata=malloc(PTP_oi_MaxLen); 471eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij /* the caller should free it after use! */ 472eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#if 0 473eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij char *capture_date="20020101T010101"; /* XXX Fake date */ 474eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#endif 475a679b1c4d273f210abb6befc5d9954a25427c329Richard Low memset (oidata, 0, PTP_oi_MaxLen); 476eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_StorageID],oi->StorageID); 477eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod16a(&oidata[PTP_oi_ObjectFormat],oi->ObjectFormat); 478eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod16a(&oidata[PTP_oi_ProtectionStatus],oi->ProtectionStatus); 479eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ObjectCompressedSize],oi->ObjectCompressedSize); 480eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod16a(&oidata[PTP_oi_ThumbFormat],oi->ThumbFormat); 481eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ThumbCompressedSize],oi->ThumbCompressedSize); 482eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ThumbPixWidth],oi->ThumbPixWidth); 483eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ThumbPixHeight],oi->ThumbPixHeight); 484eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ImagePixWidth],oi->ImagePixWidth); 485eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ImagePixHeight],oi->ImagePixHeight); 486eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ImageBitDepth],oi->ImageBitDepth); 487eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ParentObject],oi->ParentObject); 488eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod16a(&oidata[PTP_oi_AssociationType],oi->AssociationType); 489eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_AssociationDesc],oi->AssociationDesc); 490eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_SequenceNumber],oi->SequenceNumber); 491eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 492eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij ptp_pack_string(params, oi->Filename, oidata, PTP_oi_filenamelen, &filenamelen); 493eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* 494eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij filenamelen=(uint8_t)strlen(oi->Filename); 495eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod8a(&req->data[PTP_oi_filenamelen],filenamelen+1); 496eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij for (i=0;i<filenamelen && i< PTP_MAXSTRLEN; i++) { 497eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij req->data[PTP_oi_Filename+i*2]=oi->Filename[i]; 498eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 499eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij*/ 500eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij /* 501eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij *XXX Fake date. 502eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij * for example Kodak sets Capture date on the basis of EXIF data. 503eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij * Spec says that this field is from perspective of Initiator. 504eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij */ 505eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#if 0 /* seems now we don't need any data packed in OI dataset... for now ;)*/ 506eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij capturedatelen=strlen(capture_date); 507eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod8a(&data[PTP_oi_Filename+(filenamelen+1)*2], 508eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij capturedatelen+1); 509eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij for (i=0;i<capturedatelen && i< PTP_MAXSTRLEN; i++) { 510eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij data[PTP_oi_Filename+(i+filenamelen+1)*2+1]=capture_date[i]; 511eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 512eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod8a(&data[PTP_oi_Filename+(filenamelen+capturedatelen+2)*2+1], 513eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij capturedatelen+1); 514eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij for (i=0;i<capturedatelen && i< PTP_MAXSTRLEN; i++) { 515eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij data[PTP_oi_Filename+(i+filenamelen+capturedatelen+2)*2+2]= 516eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij capture_date[i]; 517eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 518eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#endif 519eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij /* XXX this function should return dataset length */ 520eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 521eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij *oidataptr=oidata; 522a679b1c4d273f210abb6befc5d9954a25427c329Richard Low return (PTP_oi_Filename+filenamelen*2+(capturedatelen+1)*3); 523eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 524eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 5253bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleijstatic time_t 5266db174f4d18af574fab991309e11010aa0eb4543Linus Walleijptp_unpack_PTPTIME (const char *str) { 5273bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij char ptpdate[40]; 5283bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij char tmp[5]; 5293bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij int ptpdatelen; 5303bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij struct tm tm; 5313bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij 5323bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij if (!str) 5333bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij return 0; 5343bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij ptpdatelen = strlen(str); 5357e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij if (ptpdatelen >= sizeof (ptpdate)) { 5366db174f4d18af574fab991309e11010aa0eb4543Linus Walleij /*ptp_debug (params ,"datelen is larger then size of buffer", ptpdatelen, (int)sizeof(ptpdate));*/ 5373bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij return 0; 5387e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij } 5393bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij strcpy (ptpdate, str); 5407e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij if (ptpdatelen<15) { 5416db174f4d18af574fab991309e11010aa0eb4543Linus Walleij /*ptp_debug (params ,"datelen is less than 15 (%d)", ptpdatelen);*/ 5423bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij return 0; 5437e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij } 5443bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij 5453bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij memset(&tm,0,sizeof(tm)); 5463bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij strncpy (tmp, ptpdate, 4); 5473bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij tmp[4] = 0; 5483bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij tm.tm_year=atoi (tmp) - 1900; 5493bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij strncpy (tmp, ptpdate + 4, 2); 5503bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij tmp[2] = 0; 5513bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij tm.tm_mon = atoi (tmp) - 1; 5523bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij strncpy (tmp, ptpdate + 6, 2); 5533bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij tmp[2] = 0; 5543bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij tm.tm_mday = atoi (tmp); 5553bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij strncpy (tmp, ptpdate + 9, 2); 5563bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij tmp[2] = 0; 5573bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij tm.tm_hour = atoi (tmp); 5583bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij strncpy (tmp, ptpdate + 11, 2); 5593bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij tmp[2] = 0; 5603bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij tm.tm_min = atoi (tmp); 5613bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij strncpy (tmp, ptpdate + 13, 2); 5623bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij tmp[2] = 0; 5633bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij tm.tm_sec = atoi (tmp); 564e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij tm.tm_isdst = -1; 5653bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij return mktime (&tm); 5663bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij} 5673bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij 568b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 569b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_OI (PTPParams *params, unsigned char* data, PTPObjectInfo *oi, unsigned int len) 570eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 571eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint8_t filenamelen; 572eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint8_t capturedatelen; 573eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij char *capture_date; 574eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 575eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->StorageID=dtoh32a(&data[PTP_oi_StorageID]); 576eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ObjectFormat=dtoh16a(&data[PTP_oi_ObjectFormat]); 577eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ProtectionStatus=dtoh16a(&data[PTP_oi_ProtectionStatus]); 578eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ObjectCompressedSize=dtoh32a(&data[PTP_oi_ObjectCompressedSize]); 579eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ThumbFormat=dtoh16a(&data[PTP_oi_ThumbFormat]); 580eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ThumbCompressedSize=dtoh32a(&data[PTP_oi_ThumbCompressedSize]); 581eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ThumbPixWidth=dtoh32a(&data[PTP_oi_ThumbPixWidth]); 582eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ThumbPixHeight=dtoh32a(&data[PTP_oi_ThumbPixHeight]); 583eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ImagePixWidth=dtoh32a(&data[PTP_oi_ImagePixWidth]); 584eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ImagePixHeight=dtoh32a(&data[PTP_oi_ImagePixHeight]); 585eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ImageBitDepth=dtoh32a(&data[PTP_oi_ImageBitDepth]); 586eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ParentObject=dtoh32a(&data[PTP_oi_ParentObject]); 587eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->AssociationType=dtoh16a(&data[PTP_oi_AssociationType]); 588eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->AssociationDesc=dtoh32a(&data[PTP_oi_AssociationDesc]); 589eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->SequenceNumber=dtoh32a(&data[PTP_oi_SequenceNumber]); 590eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->Filename= ptp_unpack_string(params, data, PTP_oi_filenamelen, &filenamelen); 591eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 592eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij capture_date = ptp_unpack_string(params, data, 593eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_oi_filenamelen+filenamelen*2+1, &capturedatelen); 594eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij /* subset of ISO 8601, without '.s' tenths of second and 595eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij * time zone 596eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij */ 5976db174f4d18af574fab991309e11010aa0eb4543Linus Walleij oi->CaptureDate = ptp_unpack_PTPTIME(capture_date); 598eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij free(capture_date); 599eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 6003bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij /* now the modification date ... */ 601eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij capture_date = ptp_unpack_string(params, data, 602eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_oi_filenamelen+filenamelen*2 603eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij +capturedatelen*2+2,&capturedatelen); 6046db174f4d18af574fab991309e11010aa0eb4543Linus Walleij oi->ModificationDate = ptp_unpack_PTPTIME(capture_date); 605eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij free(capture_date); 606eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 607eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 608eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* Custom Type Value Assignement (without Length) macro frequently used below */ 609b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define CTVAL(target,func) { \ 610b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (total - *offset < sizeof(target)) \ 611b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 0; \ 612b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij target = func(&data[*offset]); \ 613b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij *offset += sizeof(target); \ 614eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 615eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 616b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define RARR(val,member,func) { \ 617b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij int n,j; \ 618b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (total - *offset < sizeof(uint32_t)) \ 619b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 0; \ 620b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij n = dtoh32a (&data[*offset]); \ 621b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij *offset += sizeof(uint32_t); \ 622b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij \ 623b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij val->a.count = n; \ 624b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij val->a.v = malloc(sizeof(val->a.v[0])*n); \ 625b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!val->a.v) return 0; \ 626b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (j=0;j<n;j++) \ 627b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij CTVAL(val->a.v[j].member, func); \ 628b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij} 629eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 630b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline int 631b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_DPV ( 632b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij PTPParams *params, unsigned char* data, int *offset, int total, 633b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij PTPPropertyValue* value, uint16_t datatype 634b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij) { 635eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij switch (datatype) { 636b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_INT8: 637b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij CTVAL(value->i8,dtoh8a); 638b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 639b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_UINT8: 640b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij CTVAL(value->u8,dtoh8a); 641b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 642b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_INT16: 643b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij CTVAL(value->i16,dtoh16a); 644b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 645b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_UINT16: 646b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij CTVAL(value->u16,dtoh16a); 647b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 648b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_INT32: 649b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij CTVAL(value->i32,dtoh32a); 650b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 651b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_UINT32: 652b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij CTVAL(value->u32,dtoh32a); 653b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 654abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij case PTP_DTC_INT64: 655abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij CTVAL(value->i64,dtoh64a); 656abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij break; 657abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij case PTP_DTC_UINT64: 658abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij CTVAL(value->u64,dtoh64a); 659abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij break; 660abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij 661037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij case PTP_DTC_UINT128: 662037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij *offset += 16; 663037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij /*fprintf(stderr,"unhandled unpack of uint128n");*/ 664037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij break; 665037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij case PTP_DTC_INT128: 666037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij *offset += 16; 667037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij /*fprintf(stderr,"unhandled unpack of int128n");*/ 668037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij break; 669037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij 670037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij 671037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij 672b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AINT8: 673b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij RARR(value,i8,dtoh8a); 674b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 675b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AUINT8: 676b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij RARR(value,u8,dtoh8a); 677b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 678b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AUINT16: 679b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij RARR(value,u16,dtoh16a); 680b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 681b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AINT16: 682b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij RARR(value,i16,dtoh16a); 683b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 684b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AUINT32: 685b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij RARR(value,u32,dtoh32a); 686b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 687b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AINT32: 688b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij RARR(value,i32,dtoh32a); 689b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 690abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij case PTP_DTC_AUINT64: 691abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij RARR(value,u64,dtoh64a); 692abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij break; 693abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij case PTP_DTC_AINT64: 694abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij RARR(value,i64,dtoh64a); 695abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij break; 696b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij /* XXX: other int types are unimplemented */ 697b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij /* XXX: other int arrays are unimplemented also */ 698b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_STR: { 699b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij uint8_t len; 700b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij /* XXX: max size */ 701b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij value->str = ptp_unpack_string(params,data,*offset,&len); 702b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij *offset += len*2+1; 703b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!value->str) 704deddc3490b3084b802737017982285bfa58b382fLinus Walleij return 1; 705b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 706eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 707037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij default: 708037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij return 0; 709b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 710b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 1; 711eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 712eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 713eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* Device Property pack/unpack */ 714eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 715eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_dpd_DevicePropertyCode 0 716eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_dpd_DataType 2 717eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_dpd_GetSet 4 718eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_dpd_FactoryDefaultValue 5 719eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 720b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline int 721b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_DPD (PTPParams *params, unsigned char* data, PTPDevicePropDesc *dpd, unsigned int dpdlen) 722eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 723b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij int offset=0, ret; 724eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 725b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij memset (dpd, 0, sizeof(*dpd)); 726eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij dpd->DevicePropertyCode=dtoh16a(&data[PTP_dpd_DevicePropertyCode]); 727eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij dpd->DataType=dtoh16a(&data[PTP_dpd_DataType]); 728eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij dpd->GetSet=dtoh8a(&data[PTP_dpd_GetSet]); 729deddc3490b3084b802737017982285bfa58b382fLinus Walleij dpd->FormFlag=PTP_DPFF_None; 730b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 731b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij offset = PTP_dpd_FactoryDefaultValue; 732b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->FactoryDefaultValue, dpd->DataType); 733b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 734deddc3490b3084b802737017982285bfa58b382fLinus Walleij if ((dpd->DataType == PTP_DTC_STR) && (offset == dpdlen)) 735deddc3490b3084b802737017982285bfa58b382fLinus Walleij return 1; 736b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->CurrentValue, dpd->DataType); 737b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 738b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 739b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij /* if offset==0 then Data Type format is not supported by this 740b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij code or the Data Type is a string (with two empty strings as 741b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij values). In both cases Form Flag should be set to 0x00 and FORM is 742b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij not present. */ 743b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 744b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (offset==PTP_dpd_FactoryDefaultValue) 745b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 1; 746b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 747b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpd->FormFlag=dtoh8a(&data[offset]); 748b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij offset+=sizeof(uint8_t); 749eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 750eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij switch (dpd->FormFlag) { 751b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DPFF_Range: 752b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->FORM.Range.MinimumValue, dpd->DataType); 753b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 754b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->FORM.Range.MaximumValue, dpd->DataType); 755b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 756b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->FORM.Range.StepSize, dpd->DataType); 757b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 758eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij break; 759b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DPFF_Enumeration: { 760b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij int i; 761eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define N dpd->FORM.Enum.NumberOfValues 762b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij N = dtoh16a(&data[offset]); 763b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij offset+=sizeof(uint16_t); 764b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpd->FORM.Enum.SupportedValue = malloc(N*sizeof(dpd->FORM.Enum.SupportedValue[0])); 765b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!dpd->FORM.Enum.SupportedValue) 766b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij goto outofmemory; 767b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 768b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij memset (dpd->FORM.Enum.SupportedValue,0 , N*sizeof(dpd->FORM.Enum.SupportedValue[0])); 769b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<N;i++) { 770b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->FORM.Enum.SupportedValue[i], dpd->DataType); 771b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 772b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij /* Slightly different handling here. The HP PhotoSmart 120 773b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij * specifies an enumeration with N in wrong endian 774b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij * 00 01 instead of 01 00, so we count the enum just until the 775b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij * the end of the packet. 776b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij */ 777b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) { 778b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!i) 779b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij goto outofmemory; 780b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpd->FORM.Enum.NumberOfValues = i; 781b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 782eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 783b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 784eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 785eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 786b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#undef N 787b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 1; 788b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijoutofmemory: 789b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ptp_free_devicepropdesc(dpd); 790b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 0; 791eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 792eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 793b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij/* (MTP) Object Property pack/unpack */ 794b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_opd_ObjectPropertyCode 0 795b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_opd_DataType 2 796b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_opd_GetSet 4 797b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_opd_FactoryDefaultValue 5 798eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 799b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline int 800b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_OPD (PTPParams *params, unsigned char* data, PTPObjectPropDesc *opd, unsigned int opdlen) 801eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 802b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij int offset=0, ret; 803b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 804b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij memset (opd, 0, sizeof(*opd)); 805b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij opd->ObjectPropertyCode=dtoh16a(&data[PTP_opd_ObjectPropertyCode]); 806b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij opd->DataType=dtoh16a(&data[PTP_opd_DataType]); 807b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij opd->GetSet=dtoh8a(&data[PTP_opd_GetSet]); 808b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 809b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij offset = PTP_opd_FactoryDefaultValue; 810b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, opdlen, &opd->FactoryDefaultValue, opd->DataType); 811b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 812b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 813b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij opd->GroupCode=dtoh32a(&data[offset]); 814b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij offset+=sizeof(uint32_t); 815b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 816b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij opd->FormFlag=dtoh8a(&data[offset]); 817b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij offset+=sizeof(uint8_t); 818b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 819b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij switch (opd->FormFlag) { 820b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_OPFF_Range: 821b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, opdlen, &opd->FORM.Range.MinimumValue, opd->DataType); 822b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 823b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, opdlen, &opd->FORM.Range.MaximumValue, opd->DataType); 824b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 825b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, opdlen, &opd->FORM.Range.StepSize, opd->DataType); 826b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 827b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 828b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_OPFF_Enumeration: { 829b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij int i; 830b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define N opd->FORM.Enum.NumberOfValues 831b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij N = dtoh16a(&data[offset]); 832b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij offset+=sizeof(uint16_t); 833b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij opd->FORM.Enum.SupportedValue = malloc(N*sizeof(opd->FORM.Enum.SupportedValue[0])); 834b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!opd->FORM.Enum.SupportedValue) 835b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij goto outofmemory; 836b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 837b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij memset (opd->FORM.Enum.SupportedValue,0 , N*sizeof(opd->FORM.Enum.SupportedValue[0])); 838b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<N;i++) { 839b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, opdlen, &opd->FORM.Enum.SupportedValue[i], opd->DataType); 840b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 841b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij /* Slightly different handling here. The HP PhotoSmart 120 842b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij * specifies an enumeration with N in wrong endian 843b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij * 00 01 instead of 01 00, so we count the enum just until the 844b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij * the end of the packet. 845b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij */ 846b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) { 847b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!i) 848b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij goto outofmemory; 849b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij opd->FORM.Enum.NumberOfValues = i; 850b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 851b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 852b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 853b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#undef N 854b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 855eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 856b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 1; 857b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijoutofmemory: 858b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ptp_free_objectpropdesc(opd); 859b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 0; 860eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 861eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 862eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 863b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint32_t 864b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_pack_DPV (PTPParams *params, PTPPropertyValue* value, unsigned char** dpvptr, uint16_t datatype) 865eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 866b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij unsigned char* dpv=NULL; 867eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint32_t size=0; 868b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij int i; 869eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 870eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij switch (datatype) { 871b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_INT8: 872b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(int8_t); 873b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 874b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod8a(dpv,value->i8); 875b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 876b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_UINT8: 877b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint8_t); 878b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 879b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod8a(dpv,value->u8); 880b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 881b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_INT16: 882b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(int16_t); 883b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 884b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(dpv,value->i16); 885b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 886b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_UINT16: 887b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint16_t); 888b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 889b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(dpv,value->u16); 890b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 891b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_INT32: 892b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(int32_t); 893b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 894b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(dpv,value->i32); 895b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 896b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_UINT32: 897b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint32_t); 898b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 899b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(dpv,value->u32); 900b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 901abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij case PTP_DTC_INT64: 902abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij size=sizeof(int64_t); 903abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij dpv=malloc(size); 904abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij htod64a(dpv,value->i64); 905abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij break; 906abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij case PTP_DTC_UINT64: 907abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij size=sizeof(uint64_t); 908abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij dpv=malloc(size); 909abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij htod64a(dpv,value->u64); 910abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij break; 911b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AUINT8: 912b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint32_t)+value->a.count*sizeof(uint8_t); 913b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 914b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(dpv,value->a.count); 915b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<value->a.count;i++) 916cc2659036a503fce161cb77d9b0af17a52d7437bRichard Low htod8a(&dpv[sizeof(uint32_t)+i*sizeof(uint8_t)],value->a.v[i].u8); 917b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 918b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AINT8: 919b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint32_t)+value->a.count*sizeof(int8_t); 920b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 921b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(dpv,value->a.count); 922b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<value->a.count;i++) 923cc2659036a503fce161cb77d9b0af17a52d7437bRichard Low htod8a(&dpv[sizeof(uint32_t)+i*sizeof(int8_t)],value->a.v[i].i8); 924b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 925b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AUINT16: 926b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint32_t)+value->a.count*sizeof(uint16_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 htod16a(&dpv[sizeof(uint32_t)+i*sizeof(uint16_t)],value->a.v[i].u16); 931b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 932b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AINT16: 933b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint32_t)+value->a.count*sizeof(int16_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 htod16a(&dpv[sizeof(uint32_t)+i*sizeof(int16_t)],value->a.v[i].i16); 938b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 939b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AUINT32: 940b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint32_t)+value->a.count*sizeof(uint32_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 htod32a(&dpv[sizeof(uint32_t)+i*sizeof(uint32_t)],value->a.v[i].u32); 945b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 946b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AINT32: 947b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint32_t)+value->a.count*sizeof(int32_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 htod32a(&dpv[sizeof(uint32_t)+i*sizeof(int32_t)],value->a.v[i].i32); 952b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 953abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij case PTP_DTC_AUINT64: 954abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij size=sizeof(uint32_t)+value->a.count*sizeof(uint64_t); 955abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij dpv=malloc(size); 956abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij htod32a(dpv,value->a.count); 957abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij for (i=0;i<value->a.count;i++) 958cc2659036a503fce161cb77d9b0af17a52d7437bRichard Low htod64a(&dpv[sizeof(uint32_t)+i*sizeof(uint64_t)],value->a.v[i].u64); 959abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij break; 960abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij case PTP_DTC_AINT64: 961abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij size=sizeof(uint32_t)+value->a.count*sizeof(int64_t); 962abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij dpv=malloc(size); 963abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij htod32a(dpv,value->a.count); 964abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij for (i=0;i<value->a.count;i++) 965cc2659036a503fce161cb77d9b0af17a52d7437bRichard Low htod64a(&dpv[sizeof(uint32_t)+i*sizeof(int64_t)],value->a.v[i].i64); 966abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij break; 967b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij /* XXX: other int types are unimplemented */ 968b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_STR: { 969735f41692934a716158cf051d76e988febeca7eeLinus Walleij dpv=ptp_get_packed_stringcopy(params, value->str, &size); 970eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij break; 971b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 972eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 973eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij *dpvptr=dpv; 974eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return size; 97599310d4445697da39f22dff35457c75e35e97171Linus Walleij} 97699310d4445697da39f22dff35457c75e35e97171Linus Walleij 97799310d4445697da39f22dff35457c75e35e97171Linus Walleij#define MAX_MTP_PROPS 127 97899310d4445697da39f22dff35457c75e35e97171Linus Walleijstatic inline uint32_t 9791e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleijptp_pack_OPL (PTPParams *params, MTPProperties *props, int nrofprops, unsigned char** opldataptr) 98099310d4445697da39f22dff35457c75e35e97171Linus Walleij{ 98199310d4445697da39f22dff35457c75e35e97171Linus Walleij unsigned char* opldata; 9821e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij MTPProperties *propitr; 98399310d4445697da39f22dff35457c75e35e97171Linus Walleij unsigned char *packedprops[MAX_MTP_PROPS]; 98499310d4445697da39f22dff35457c75e35e97171Linus Walleij uint32_t packedpropslens[MAX_MTP_PROPS]; 98539b9374f23451201dece736db13f0f648584dc32Linus Walleij uint32_t packedobjecthandles[MAX_MTP_PROPS]; 98699310d4445697da39f22dff35457c75e35e97171Linus Walleij uint16_t packedpropsids[MAX_MTP_PROPS]; 98799310d4445697da39f22dff35457c75e35e97171Linus Walleij uint16_t packedpropstypes[MAX_MTP_PROPS]; 98899310d4445697da39f22dff35457c75e35e97171Linus Walleij uint32_t totalsize = 0; 98999310d4445697da39f22dff35457c75e35e97171Linus Walleij uint32_t bufp = 0; 99099310d4445697da39f22dff35457c75e35e97171Linus Walleij uint32_t noitems = 0; 99199310d4445697da39f22dff35457c75e35e97171Linus Walleij uint32_t i; 99299310d4445697da39f22dff35457c75e35e97171Linus Walleij 99399310d4445697da39f22dff35457c75e35e97171Linus Walleij totalsize = sizeof(uint32_t); /* 4 bytes to store the number of elements */ 9941e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij propitr = props; 9951e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij while (nrofprops-- && noitems < MAX_MTP_PROPS) { 9966c0a6ce803cf79802b1c48339adf0964db30ec83Richard Low /* Object Handle */ 99739b9374f23451201dece736db13f0f648584dc32Linus Walleij packedobjecthandles[noitems]=propitr->ObjectHandle; 99899310d4445697da39f22dff35457c75e35e97171Linus Walleij totalsize += sizeof(uint32_t); /* Object ID */ 99999310d4445697da39f22dff35457c75e35e97171Linus Walleij /* Metadata type */ 100099310d4445697da39f22dff35457c75e35e97171Linus Walleij packedpropsids[noitems]=propitr->property; 100199310d4445697da39f22dff35457c75e35e97171Linus Walleij totalsize += sizeof(uint16_t); 100299310d4445697da39f22dff35457c75e35e97171Linus Walleij /* Data type */ 100399310d4445697da39f22dff35457c75e35e97171Linus Walleij packedpropstypes[noitems]= propitr->datatype; 100499310d4445697da39f22dff35457c75e35e97171Linus Walleij totalsize += sizeof(uint16_t); 100599310d4445697da39f22dff35457c75e35e97171Linus Walleij /* Add each property to be sent. */ 100699310d4445697da39f22dff35457c75e35e97171Linus Walleij packedpropslens[noitems] = ptp_pack_DPV (params, &propitr->propval, &packedprops[noitems], propitr->datatype); 100799310d4445697da39f22dff35457c75e35e97171Linus Walleij totalsize += packedpropslens[noitems]; 100899310d4445697da39f22dff35457c75e35e97171Linus Walleij noitems ++; 10091e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij propitr ++; 101099310d4445697da39f22dff35457c75e35e97171Linus Walleij } 101199310d4445697da39f22dff35457c75e35e97171Linus Walleij 101299310d4445697da39f22dff35457c75e35e97171Linus Walleij /* Allocate memory for the packed property list */ 101399310d4445697da39f22dff35457c75e35e97171Linus Walleij opldata = malloc(totalsize); 101499310d4445697da39f22dff35457c75e35e97171Linus Walleij 101599310d4445697da39f22dff35457c75e35e97171Linus Walleij htod32a(&opldata[bufp],noitems); 101699310d4445697da39f22dff35457c75e35e97171Linus Walleij bufp += 4; 101799310d4445697da39f22dff35457c75e35e97171Linus Walleij 101899310d4445697da39f22dff35457c75e35e97171Linus Walleij /* Copy into a nice packed list */ 101999310d4445697da39f22dff35457c75e35e97171Linus Walleij for (i = 0; i < noitems; i++) { 102099310d4445697da39f22dff35457c75e35e97171Linus Walleij /* Object ID */ 10216c0a6ce803cf79802b1c48339adf0964db30ec83Richard Low htod32a(&opldata[bufp],packedobjecthandles[i]); 102299310d4445697da39f22dff35457c75e35e97171Linus Walleij bufp += sizeof(uint32_t); 102399310d4445697da39f22dff35457c75e35e97171Linus Walleij htod16a(&opldata[bufp],packedpropsids[i]); 102499310d4445697da39f22dff35457c75e35e97171Linus Walleij bufp += sizeof(uint16_t); 102599310d4445697da39f22dff35457c75e35e97171Linus Walleij htod16a(&opldata[bufp],packedpropstypes[i]); 102699310d4445697da39f22dff35457c75e35e97171Linus Walleij bufp += sizeof(uint16_t); 102799310d4445697da39f22dff35457c75e35e97171Linus Walleij /* The copy the actual property */ 102899310d4445697da39f22dff35457c75e35e97171Linus Walleij memcpy(&opldata[bufp], packedprops[i], packedpropslens[i]); 102999310d4445697da39f22dff35457c75e35e97171Linus Walleij bufp += packedpropslens[i]; 103099310d4445697da39f22dff35457c75e35e97171Linus Walleij free(packedprops[i]); 103199310d4445697da39f22dff35457c75e35e97171Linus Walleij } 103299310d4445697da39f22dff35457c75e35e97171Linus Walleij *opldataptr = opldata; 103399310d4445697da39f22dff35457c75e35e97171Linus Walleij return totalsize; 1034eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 1035eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 10361e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleijstatic int 10371e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij_compare_func(const void* x, const void *y) { 10381e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij const MTPProperties *px = x; 10391e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij const MTPProperties *py = y; 10401e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij 10411e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij return px->ObjectHandle - py->ObjectHandle; 10421e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij} 10431e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij 10448d82d2f4b0794e41ec26289045867eebb3496b8cRichard Lowstatic inline int 10451e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleijptp_unpack_OPL (PTPParams *params, unsigned char* data, MTPProperties **pprops, unsigned int len) 10468d82d2f4b0794e41ec26289045867eebb3496b8cRichard Low{ 1047277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij uint32_t prop_count = dtoh32a(data); 10481e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij MTPProperties *props = NULL; 1049277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij int offset = 0, i; 1050277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij 1051277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij if (prop_count == 0) { 10521e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij *pprops = NULL; 1053277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij return 0; 1054277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij } 1055d49955b02710fd4bb1eda73b8bd6abb3f17f7c15Linus Walleij ptp_debug (params ,"Unpacking MTP OPL, size %d (prop_count %d)", len, prop_count); 1056277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij data += sizeof(uint32_t); 10573bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij len -= sizeof(uint32_t); 10581e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij props = malloc(prop_count * sizeof(MTPProperties)); 10591e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij if (!props) return 0; 1060277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij for (i = 0; i < prop_count; i++) { 10613bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij if (len <= 0) { 1062d49955b02710fd4bb1eda73b8bd6abb3f17f7c15Linus Walleij ptp_debug (params ,"short MTP Object Property List at property %d (of %d)", i, prop_count); 10633bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij ptp_debug (params ,"device probably needs DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST_ALL", i); 10643bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij ptp_debug (params ,"or even DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST", i); 1065d49955b02710fd4bb1eda73b8bd6abb3f17f7c15Linus Walleij qsort (props, i, sizeof(MTPProperties),_compare_func); 1066d49955b02710fd4bb1eda73b8bd6abb3f17f7c15Linus Walleij *pprops = props; 10673bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij return i; 10683bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij } 10691e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij props[i].ObjectHandle = dtoh32a(data); 1070277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij data += sizeof(uint32_t); 1071277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij len -= sizeof(uint32_t); 1072277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij 10731e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij props[i].property = dtoh16a(data); 1074277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij data += sizeof(uint16_t); 1075277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij len -= sizeof(uint16_t); 1076277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij 10771e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij props[i].datatype = dtoh16a(data); 1078277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij data += sizeof(uint16_t); 1079277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij len -= sizeof(uint16_t); 1080277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij 1081277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij offset = 0; 10821e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij ptp_unpack_DPV(params, data, &offset, len, &props[i].propval, props[i].datatype); 1083277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij data += offset; 1084277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij len -= offset; 1085277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij } 10861e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij qsort (props, prop_count, sizeof(MTPProperties),_compare_func); 10871e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij *pprops = props; 1088277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij return prop_count; 10898d82d2f4b0794e41ec26289045867eebb3496b8cRichard Low} 10908d82d2f4b0794e41ec26289045867eebb3496b8cRichard Low 1091eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* 1092eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP USB Event container unpack 1093eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij Copyright (c) 2003 Nikolai Kopanygin 1094eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij*/ 1095eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 1096eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_ec_Length 0 1097eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_ec_Type 4 1098eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_ec_Code 6 1099eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_ec_TransId 8 1100eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_ec_Param1 12 1101eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_ec_Param2 16 1102eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_ec_Param3 20 1103eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 1104b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 11057e75653e64021908ca66b155eeb950d8304c87d8Linus Walleijptp_unpack_EC (PTPParams *params, unsigned char* data, PTPContainer *ec, unsigned int len) 1106eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 11077e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij int length; 11087e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij int type; 11097e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij 1110eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij if (data==NULL) 1111eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return; 11127e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij memset(ec,0,sizeof(*ec)); 11137e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij length=dtoh32a(&data[PTP_ec_Length]); 11147e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij type = dtoh16a(&data[PTP_ec_Type]); 1115b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 11167e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij ec->Code=dtoh16a(&data[PTP_ec_Code]); 11177e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij ec->Transaction_ID=dtoh32a(&data[PTP_ec_TransId]); 11187e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij 11197e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij if (type!=PTP_USB_CONTAINER_EVENT) { 11207e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij ptp_debug (params, "Unknown canon event type %d (code=%x,tid=%x), please report!",type,ec->Code,ec->Transaction_ID); 11217e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij return; 11227e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij } 11237e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij if (length>=(PTP_ec_Param1+4)) { 11247e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij ec->Param1=dtoh32a(&data[PTP_ec_Param1]); 11257e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij ec->Nparam=1; 11267e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij } 11277e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij if (length>=(PTP_ec_Param2+4)) { 11287e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij ec->Param2=dtoh32a(&data[PTP_ec_Param2]); 11297e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij ec->Nparam=2; 11307e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij } 11317e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij if (length>=(PTP_ec_Param3+4)) { 11327e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij ec->Param3=dtoh32a(&data[PTP_ec_Param3]); 11337e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij ec->Nparam=3; 11347e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij } 1135eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 1136eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 1137eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* 1138eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP Canon Folder Entry unpack 1139eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij Copyright (c) 2003 Nikolai Kopanygin 1140eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij*/ 1141eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_cfe_ObjectHandle 0 1142eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_cfe_ObjectFormatCode 4 1143eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_cfe_Flags 6 1144eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_cfe_ObjectSize 7 1145eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_cfe_Time 11 1146eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_cfe_Filename 15 1147eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 1148b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 1149b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_Canon_FE (PTPParams *params, unsigned char* data, PTPCANONFolderEntry *fe) 1150eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 1151eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij int i; 1152eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij if (data==NULL) 1153eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return; 1154eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij fe->ObjectHandle=dtoh32a(&data[PTP_cfe_ObjectHandle]); 1155eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij fe->ObjectFormatCode=dtoh16a(&data[PTP_cfe_ObjectFormatCode]); 1156eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij fe->Flags=dtoh8a(&data[PTP_cfe_Flags]); 1157b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij fe->ObjectSize=dtoh32a((unsigned char*)&data[PTP_cfe_ObjectSize]); 1158eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij fe->Time=(time_t)dtoh32a(&data[PTP_cfe_Time]); 1159eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij for (i=0; i<PTP_CANON_FilenameBufferLen; i++) 1160b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij fe->Filename[i]=(char)dtoh8a(&data[PTP_cfe_Filename+i]); 1161b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij} 1162b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 11631a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleijstatic inline uint16_t 11641a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleijptp_unpack_EOS_ImageFormat (PTPParams* params, unsigned char** data ) 11651a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij{ 11661a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij /* 11671a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij EOS ImageFormat entries (of at least the 5DMII and the 400D ) look like this: 11681a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij uint32: number of entries / generated files (1 or 2) 11691a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij uint32: size of this entry in bytes (most likely allways 0x10) 11701a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij uint32: image type (1 == JPG, 6 == RAW) 11711a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij uint32: image size (0 == Large, 1 == Medium, 2 == Small) 11721a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij uint32: image compression (2 == Standard/JPG, 3 == Fine/JPG, 4 == Lossles/RAW) 11731a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij If number of entries is 2 the last uint32 repeat. 11741a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 11751a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij example: 11761a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 0: 0x 1 11771a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 1: 0x 10 11781a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 2: 0x 6 11791a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 3: 0x 1 11801a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 4: 0x 4 11811a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 11821a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij The idea is to simply 'condense' these values to just one uint16 to be able to conveniontly 11831a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij use the available enumeration facilities (look-up table). The image size and compression 11841a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij values fully describe the image format. Hence we generate a uint16 with the four nibles set 11851a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij as follows: entry 1 size | entry 1 compression | entry 2 size | entry 2 compression. 11861a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij The above example would result in the value 0x1400. 11871a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij */ 11881a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 11891a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij const unsigned char* d = *data; 11901a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij uint32_t n = dtoh32a( d ); 11911a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij uint32_t l, s1, c1, s2 = 0, c2 = 0; 11921a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 11931a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij if (n != 1 && n !=2) { 11941a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij ptp_debug (params, "parsing EOS ImageFormat property failed (n != 1 && n != 2: %d)", n); 11951a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij return 0; 11961a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij } 11971a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 11981a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij l = dtoh32a( d+=4 ); 11991a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij if (l != 0x10) { 12001a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij ptp_debug (params, "parsing EOS ImageFormat property failed (l != 0x10: 0x%x)", l); 12011a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij return 0; 12021a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij } 12031a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 12041a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij d+=4; /* skip type */ 12051a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij s1 = dtoh32a( d+=4 ); 12061a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij c1 = dtoh32a( d+=4 ); 12071a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 12081a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij if (n == 2) { 12091a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij l = dtoh32a( d+=4 ); 12101a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij if (l != 0x10) { 12111a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij ptp_debug (params, "parsing EOS ImageFormat property failed (l != 0x10: 0x%x)", l); 12121a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij return 0; 12131a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij } 12141a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij d+=4; /* skip type */ 12151a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij s2 = dtoh32a( d+=4 ); 12161a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij c2 = dtoh32a( d+=4 ); 12171a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij } 12181a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 12191a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij *data = (unsigned char*) d+4; 12201a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 12211a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij return ((s1 & 0xF) << 12) | ((c1 & 0xF) << 8) | ((s2 & 0xF) << 4) | ((c2 & 0xF) << 0); 12221a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij} 12231a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 12241a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleijstatic inline uint32_t 12251a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleijptp_pack_EOS_ImageFormat (PTPParams* params, unsigned char* data, uint16_t value) 12261a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij{ 12271a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij uint32_t n = (value & 0xFF) ? 2 : 1; 12281a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij uint32_t s = 4 + 0x10 * n; 12291a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 12301a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij if( !data ) 12311a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij return s; 12321a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 12331a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij htod32a(data+=0, n); 12341a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij htod32a(data+=4, 0x10); 12351a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij htod32a(data+=4, ((value >> 8) & 0xF) == 4 ? 6 : 1); 12361a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij htod32a(data+=4, (value >> 12) & 0xF); 12371a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij htod32a(data+=4, (value >> 8) & 0xF); 12381a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 12391a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij if (n==2) { 12401a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij htod32a(data+=4, 0x10); 12411a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij htod32a(data+=4, ((value >> 0) & 0xF) == 4 ? 6 : 1); 12421a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij htod32a(data+=4, (value >> 4) & 0xF); 12431a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij htod32a(data+=4, (value >> 0) & 0xF); 12441a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij } 12451a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 12461a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij return s; 12471a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij} 12481a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 1249b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij/* 1250f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij PTP EOS Changes Entry unpack 1251f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij*/ 1252f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij#define PTP_ece_Size 0 1253f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij#define PTP_ece_Type 4 1254f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij 1255f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij#define PTP_ece_Prop_Subtype 8 /* only for properties */ 1256f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij#define PTP_ece_Prop_Val_Data 0xc /* only for properties */ 1257f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij#define PTP_ece_Prop_Desc_Type 0xc /* only for property descs */ 1258f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij#define PTP_ece_Prop_Desc_Count 0x10 /* only for property descs */ 1259f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij#define PTP_ece_Prop_Desc_Data 0x14 /* only for property descs */ 1260f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij 1261d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij/* for PTP_EC_CANON_EOS_RequestObjectTransfer */ 1262d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij#define PTP_ece_OI_ObjectID 8 1263d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij#define PTP_ece_OI_OFC 0x0c 1264d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij#define PTP_ece_OI_Size 0x14 1265d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij#define PTP_ece_OI_Name 0x1c 1266d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij 1267d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij/* for PTP_EC_CANON_EOS_ObjectAddedEx */ 1268d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij#define PTP_ece_OA_ObjectID 8 1269d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij#define PTP_ece_OA_StorageID 0x0c 1270d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij#define PTP_ece_OA_OFC 0x10 1271d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij#define PTP_ece_OA_Size 0x1c 1272d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij#define PTP_ece_OA_Parent 0x20 1273d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij#define PTP_ece_OA_Name 0x28 1274f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij 1275f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleijstatic inline int 1276f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleijptp_unpack_CANON_changes (PTPParams *params, unsigned char* data, int datasize, PTPCanon_changes_entry **ce) 1277f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij{ 1278f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij int i = 0, entries = 0; 1279f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij unsigned char *curdata = data; 1280f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij 1281f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if (data==NULL) 1282f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij return 0; 1283f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij while (curdata - data < datasize) { 1284f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij uint32_t size = dtoh32a(&curdata[PTP_ece_Size]); 1285f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij uint32_t type = dtoh32a(&curdata[PTP_ece_Type]); 1286f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij 1287f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij curdata += size; 1288f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if ((size == 8) && (type == 0)) 1289f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1290f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij entries++; 1291f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 12929d22ce0e3214f38d30435fb9ec8ff2c8c6c4191eLinus Walleij *ce = malloc (sizeof(PTPCanon_changes_entry)*(entries+1)); 1293f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if (!*ce) return 0; 1294f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij 1295f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij curdata = data; 1296f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij while (curdata - data < datasize) { 1297f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij uint32_t size = dtoh32a(&curdata[PTP_ece_Size]); 1298f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij uint32_t type = dtoh32a(&curdata[PTP_ece_Type]); 1299f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij 1300d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij (*ce)[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN; 1301d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij (*ce)[i].u.info = NULL; 1302f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij switch (type) { 1303d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_EC_CANON_EOS_ObjectAddedEx: 1304f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij (*ce)[i].type = PTP_CANON_EOS_CHANGES_TYPE_OBJECTINFO; 1305d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij (*ce)[i].u.object.oid = dtoh32a(&curdata[PTP_ece_OA_ObjectID]); 1306d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij (*ce)[i].u.object.oi.StorageID = dtoh32a(&curdata[PTP_ece_OA_StorageID]); 1307d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij (*ce)[i].u.object.oi.ParentObject = dtoh32a(&curdata[PTP_ece_OA_Parent]); 1308d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij (*ce)[i].u.object.oi.ObjectFormat = dtoh16a(&curdata[PTP_ece_OA_OFC]); 1309d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij (*ce)[i].u.object.oi.ObjectCompressedSize= dtoh32a(&curdata[PTP_ece_OA_Size]); 1310d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij (*ce)[i].u.object.oi.Filename = strdup(((char*)&curdata[PTP_ece_OA_Name])); 1311d4637506d9551957a152cab2cfb80fdfed029424Linus 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); 1312d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij break; 1313d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_EC_CANON_EOS_RequestObjectTransfer: 1314d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij (*ce)[i].type = PTP_CANON_EOS_CHANGES_TYPE_OBJECTTRANSFER; 1315f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij (*ce)[i].u.object.oid = dtoh32a(&curdata[PTP_ece_OI_ObjectID]); 1316d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij (*ce)[i].u.object.oi.StorageID = 0; /* use as marker */ 1317f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij (*ce)[i].u.object.oi.ObjectFormat = dtoh16a(&curdata[PTP_ece_OI_OFC]); 1318d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij (*ce)[i].u.object.oi.ParentObject = 0; /* check, but use as marker */ 1319f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij (*ce)[i].u.object.oi.ObjectCompressedSize = dtoh32a(&curdata[PTP_ece_OI_Size]); 1320f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij (*ce)[i].u.object.oi.Filename = strdup(((char*)&curdata[PTP_ece_OI_Name])); 13213bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij 1322d4637506d9551957a152cab2cfb80fdfed029424Linus 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); 1323f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 13247e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_EC_CANON_EOS_AvailListChanged: { /* property desc */ 1325f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij uint32_t proptype = dtoh32a(&curdata[PTP_ece_Prop_Subtype]); 1326f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij uint32_t propxtype = dtoh32a(&curdata[PTP_ece_Prop_Desc_Type]); 1327f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij uint32_t propxcnt = dtoh32a(&curdata[PTP_ece_Prop_Desc_Count]); 1328e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij unsigned char *xdata = &curdata[PTP_ece_Prop_Desc_Data]; 1329f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij int j; 1330f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij PTPDevicePropDesc *dpd; 1331f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij 13327e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij ptp_debug (params, "event %d: EOS prop %04x desc record, datasize %d, propxtype %d", i, proptype, size-PTP_ece_Prop_Desc_Data, propxtype); 1333f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij for (j=0;j<params->nrofcanon_props;j++) 1334f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if (params->canon_props[j].proptype == proptype) 1335f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1336f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if (j==params->nrofcanon_props) { 13373bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij ptp_debug (params, "event %d: propdesc %x, default value not found.", i, proptype); 1338f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1339f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 1340f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij dpd = ¶ms->canon_props[j].dpd; 13417e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij /* 1 - uint16 ? 13427e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij * 3 - uint16 13437e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij * 7 - string? 13447e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij */ 1345f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if (propxtype != 3) { 13463bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij ptp_debug (params, "event %d: propxtype is %x for %04x, unhandled.", i, propxtype, proptype); 13473bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij for (j=0;j<size-PTP_ece_Prop_Desc_Data;j++) 1348e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij ptp_debug (params, " %d: %02x", j, xdata[j]); 1349f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1350f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 13511a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij if (! propxcnt) 13521a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij break; 13531a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 13541a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij ptp_debug (params, "event %d: propxtype is %x, prop is 0x%04x, data type is 0x%04x, propxcnt is %d.", 13551a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij i, propxtype, proptype, dpd->DataType, propxcnt); 13561a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij dpd->FormFlag = PTP_DPFF_Enumeration; 13571a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij dpd->FORM.Enum.NumberOfValues = propxcnt; 13580d762ccc39331608119dd0267021b165e22de499Linus Walleij if (dpd->FORM.Enum.SupportedValue) free (dpd->FORM.Enum.SupportedValue); 13591a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij dpd->FORM.Enum.SupportedValue = malloc (sizeof (PTPPropertyValue)*propxcnt); 13601a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 13611a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij switch (proptype) { 13621a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DPC_CANON_EOS_ImageFormat: 13631a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DPC_CANON_EOS_ImageFormatCF: 13641a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DPC_CANON_EOS_ImageFormatSD: 13651a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DPC_CANON_EOS_ImageFormatExtHD: 13661a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij /* special handling of ImageFormat properties */ 1367f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij for (j=0;j<propxcnt;j++) { 13681a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij dpd->FORM.Enum.SupportedValue[j].u16 = 1369e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij dtoh16( ptp_unpack_EOS_ImageFormat( params, &xdata ) ); 13701a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij ptp_debug (params, "event %d: suppval[%d] of %x is 0x%x.", i, j, proptype, dpd->FORM.Enum.SupportedValue[j].u16); 13711a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij } 13721a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij break; 13731a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij default: 13741a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij /* 'normal' enumerated types */ 13751a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij switch (dpd->DataType) { 13761a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij#define XX( TYPE, CONV )\ 13771a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij for (j=0;j<propxcnt;j++) { \ 1378e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij dpd->FORM.Enum.SupportedValue[j].TYPE = CONV(xdata); \ 1379e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij ptp_debug (params, "event %d: suppval[%d] of %x is 0x%x.", i, j, proptype, CONV(xdata)); \ 1380e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij xdata += 4; /* might only be for propxtype 3 */ \ 13811a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij } \ 13821a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij break; 13831a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 13841a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DTC_INT16: XX( i16, dtoh16a ); 13851a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DTC_UINT32: XX( u32, dtoh32a ); 13861a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DTC_UINT16: XX( u16, dtoh16a ); 13871a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DTC_UINT8: XX( u8, dtoh8a ); 13881a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij#undef XX 13891a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij default: 1390e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij ptp_debug (params ,"event %d: data type 0x%04x of %x unhandled, raw values:", i, dpd->DataType, proptype, dtoh32a(xdata)); 1391e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij for (j=0;j<(size-PTP_ece_Prop_Desc_Data)/4;j++, xdata+=4) /* 4 is good for propxtype 3 */ 1392e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij ptp_debug (params, " %3d: 0x%8x", j, dtoh32a(xdata)); 13931a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij break; 1394f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 1395f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 1396f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1397f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 13987e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_EC_CANON_EOS_PropValueChanged: 1399f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if (size >= 0xc) { /* property info */ 1400f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij int j; 1401f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij uint32_t proptype = dtoh32a(&curdata[PTP_ece_Prop_Subtype]); 1402e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij unsigned char *xdata = &curdata[PTP_ece_Prop_Val_Data]; 1403f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij PTPDevicePropDesc *dpd; 1404f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij 14051a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij ptp_debug (params, "event %d: EOS prop %04x info record, datasize is %d", i, proptype, size-PTP_ece_Prop_Val_Data); 1406f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij for (j=0;j<params->nrofcanon_props;j++) 1407f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if (params->canon_props[j].proptype == proptype) 1408f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1409f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if (j<params->nrofcanon_props) { 1410f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if ( (params->canon_props[j].size != size) || 1411e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij (memcmp(params->canon_props[j].data,xdata,size-PTP_ece_Prop_Val_Data))) { 1412f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij params->canon_props[j].data = realloc(params->canon_props[j].data,size-PTP_ece_Prop_Val_Data); 1413e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij memcpy (params->canon_props[j].data,xdata,size-PTP_ece_Prop_Val_Data); 1414f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 1415f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } else { 1416f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if (j) 1417f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij params->canon_props = realloc(params->canon_props, sizeof(params->canon_props[0])*(j+1)); 1418f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij else 1419f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij params->canon_props = malloc(sizeof(params->canon_props[0])); 1420f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij params->canon_props[j].type = type; 1421f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij params->canon_props[j].proptype = proptype; 1422f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij params->canon_props[j].size = size; 1423f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij params->canon_props[j].data = malloc(size-PTP_ece_Prop_Val_Data); 1424e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij memcpy(params->canon_props[j].data, xdata, size-PTP_ece_Prop_Val_Data); 1425f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij memset (¶ms->canon_props[j].dpd,0,sizeof(params->canon_props[j].dpd)); 1426f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij params->canon_props[j].dpd.GetSet = 1; 1427f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij params->canon_props[j].dpd.FormFlag = PTP_DPFF_None; 1428f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij params->nrofcanon_props = j+1; 1429f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 1430f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij dpd = ¶ms->canon_props[j].dpd; 14311a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 1432d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij (*ce)[i].type = PTP_CANON_EOS_CHANGES_TYPE_PROPERTY; 1433d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij (*ce)[i].u.propid = proptype; 1434d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij 14351a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij /* fix GetSet value */ 14361a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij switch (proptype) { 14371a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij#define XX(x) case PTP_DPC_CANON_##x: 14381a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_FocusMode) 14391a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_BatteryPower) 14401a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_BatterySelect) 14411a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_ModelID) 14421a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_PTPExtensionVersion) 14431a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_DPOFVersion) 14441a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_AvailableShots) 14451a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_CurrentStorage) 14461a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_CurrentFolder) 14471a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_MyMenu) 14481a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_MyMenuList) 14491a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_HDDirectoryStructure) 14501a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_BatteryInfo) 14511a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_AdapterInfo) 14521a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_LensStatus) 14531a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_CardExtension) 14541a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_TempStatus) 14551a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_ShutterCounter) 14561a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_SerialNumber) 14571a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_DepthOfFieldPreview) 14581a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_EVFRecordStatus) 14591a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_LvAfSystem) 14601a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_FocusInfoEx) 14611a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_DepthOfField) 14621a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_Brightness) 14631a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_EFComp) 14641a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_LensName) 14651a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_LensID) 14661a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij#undef XX 14671a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij dpd->GetSet = PTP_DPGS_Get; 14681a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij break; 14691a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij } 14701a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 14711a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij /* set DataType */ 1472f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij switch (proptype) { 1473ac052c1ac330b94932d2b4f774e0053e78e91216Linus Walleij case PTP_DPC_CANON_EOS_CameraTime: 1474d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_AvailableShots: 1475d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_CaptureDestination: 1476d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_WhiteBalanceXA: 1477d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_WhiteBalanceXB: 1478d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_CurrentStorage: 1479d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_CurrentFolder: 1480d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_ShutterCounter: 1481d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_ModelID: 1482d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_LensID: 1483d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_StroboFiring: 1484ac052c1ac330b94932d2b4f774e0053e78e91216Linus Walleij dpd->DataType = PTP_DTC_UINT32; 1485ac052c1ac330b94932d2b4f774e0053e78e91216Linus Walleij break; 14860d762ccc39331608119dd0267021b165e22de499Linus Walleij /* enumeration for AEM is never provided, but is available to set */ 14870d762ccc39331608119dd0267021b165e22de499Linus Walleij case PTP_DPC_CANON_EOS_AutoExposureMode: 14880d762ccc39331608119dd0267021b165e22de499Linus Walleij dpd->DataType = PTP_DTC_UINT16; 14890d762ccc39331608119dd0267021b165e22de499Linus Walleij dpd->FormFlag = PTP_DPFF_Enumeration; 14900d762ccc39331608119dd0267021b165e22de499Linus Walleij dpd->FORM.Enum.NumberOfValues = 0; 14910d762ccc39331608119dd0267021b165e22de499Linus Walleij break; 1492f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case PTP_DPC_CANON_EOS_Aperture: 1493f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case PTP_DPC_CANON_EOS_ShutterSpeed: 1494f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case PTP_DPC_CANON_EOS_ISOSpeed: 14957e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_FocusMode: 14967e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_ColorSpace: 14977e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_BatteryPower: 1498e29ca68e54b8dd04e54499d6b5fa8668770a20cfLinus Walleij case PTP_DPC_CANON_EOS_BatterySelect: 1499d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_PTPExtensionVersion: 15001a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DPC_CANON_EOS_DriveMode: 15011a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DPC_CANON_EOS_AEB: 1502e29ca68e54b8dd04e54499d6b5fa8668770a20cfLinus Walleij case PTP_DPC_CANON_EOS_BracketMode: 1503e29ca68e54b8dd04e54499d6b5fa8668770a20cfLinus Walleij case PTP_DPC_CANON_EOS_QuickReviewTime: 15040d762ccc39331608119dd0267021b165e22de499Linus Walleij case PTP_DPC_CANON_EOS_EVFMode: 15050d762ccc39331608119dd0267021b165e22de499Linus Walleij case PTP_DPC_CANON_EOS_EVFOutputDevice: 1506f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij dpd->DataType = PTP_DTC_UINT16; 1507f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1508f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case PTP_DPC_CANON_EOS_PictureStyle: 1509f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case PTP_DPC_CANON_EOS_WhiteBalance: 1510f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case PTP_DPC_CANON_EOS_MeteringMode: 15117e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_ExpCompensation: /* actually int8 if you calculate */ 1512f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij dpd->DataType = PTP_DTC_UINT8; 1513f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1514f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case PTP_DPC_CANON_EOS_Owner: 15151a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DPC_CANON_EOS_Artist: 15161a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DPC_CANON_EOS_Copyright: 15171a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DPC_CANON_EOS_SerialNumber: 15181a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DPC_CANON_EOS_LensName: 1519f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij dpd->DataType = PTP_DTC_STR; 1520f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 15217e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_WhiteBalanceAdjustA: 15227e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_WhiteBalanceAdjustB: 15237e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij dpd->DataType = PTP_DTC_INT16; 15247e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij break; 15257e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij /* unknown props, listed from dump.... all 16 bit, but vals might be smaller */ 15267e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case 0xd114: 15277e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_DPOFVersion: 15281a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij dpd->DataType = PTP_DTC_UINT16; 15291a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij ptp_debug (params, "event %d: Unknown EOS property %04x, datasize is %d, using uint16", i ,proptype, size-PTP_ece_Prop_Val_Data); 15301a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij for (j=0;j<size-PTP_ece_Prop_Val_Data;j++) 1531e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij ptp_debug (params, " %d: %02x", j, xdata[j]); 15321a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij break; 15337e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_CustomFunc1: 15347e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_CustomFunc2: 15357e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_CustomFunc3: 15367e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_CustomFunc4: 15377e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_CustomFunc5: 15387e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_CustomFunc6: 15397e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_CustomFunc7: 15407e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_CustomFunc8: 15417e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_CustomFunc9: 15427e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_CustomFunc10: 15437e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_CustomFunc11: 15441a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij dpd->DataType = PTP_DTC_UINT8; 15451a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij ptp_debug (params, "event %d: Unknown EOS property %04x, datasize is %d, using uint8", i ,proptype, size-PTP_ece_Prop_Val_Data); 15467e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij for (j=0;j<size-PTP_ece_Prop_Val_Data;j++) 1547e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij ptp_debug (params, " %d: %02x", j, xdata[j]); 15481a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij /* custom func entries look like this on the 400D: '5 0 0 0 ?' = 4 bytes size + 1 byte data */ 1549e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij xdata += 4; 15507e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij break; 15517e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij /* yet unknown 32bit props */ 15527e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_ColorTemperature: 15537e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_WftStatus: 15547e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_LensStatus: 15557e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_CardExtension: 15567e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_TempStatus: 15577e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_PhotoStudioMode: 15587e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_DepthOfFieldPreview: 15597e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_EVFSharpness: 15607e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_EVFWBMode: 15617e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_EVFClickWBCoeffs: 15627e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_EVFColorTemp: 1563d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_EVFRecordStatus: 1564d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_ExposureSimMode: 1565d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_LvAfSystem: 1566d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_MovSize: 1567d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_DepthOfField: 1568d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_LvViewTypeSelect: 15691a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DPC_CANON_EOS_CustomFuncEx: 15700d762ccc39331608119dd0267021b165e22de499Linus Walleij dpd->DataType = PTP_DTC_UINT32; 15717e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij ptp_debug (params, "event %d: Unknown EOS property %04x, datasize is %d, using uint32", i ,proptype, size-PTP_ece_Prop_Val_Data); 15721a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij if ((size-PTP_ece_Prop_Val_Data) % sizeof(uint32_t) != 0) 15731a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij ptp_debug (params, "event %d: Warning: datasize modulo sizeof(uint32) is not 0: ", i, (size-PTP_ece_Prop_Val_Data) % sizeof(uint32_t) ); 15741a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij for (j=0;j<(size-PTP_ece_Prop_Val_Data)/sizeof(uint32_t);j++) 1575e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij ptp_debug (params, " %d: 0x%8x", j, ((uint32_t*)xdata)[j]); 15767e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij break; 1577d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij /* ImageFormat properties have to be ignored here, see special handling below */ 1578d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij case PTP_DPC_CANON_EOS_ImageFormat: 1579d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij case PTP_DPC_CANON_EOS_ImageFormatCF: 1580d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij case PTP_DPC_CANON_EOS_ImageFormatSD: 1581d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij case PTP_DPC_CANON_EOS_ImageFormatExtHD: 1582d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij break; 1583f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij default: 15843bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij ptp_debug (params, "event %d: Unknown EOS property %04x, datasize is %d", i ,proptype, size-PTP_ece_Prop_Val_Data); 15853bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij for (j=0;j<size-PTP_ece_Prop_Val_Data;j++) 1586e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij ptp_debug (params, " %d: %02x", j, xdata[j]); 1587f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1588f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 1589f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij switch (dpd->DataType) { 1590ac052c1ac330b94932d2b4f774e0053e78e91216Linus Walleij case PTP_DTC_UINT32: 1591e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij dpd->FactoryDefaultValue.u32 = dtoh32a(xdata); 1592e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij dpd->CurrentValue.u32 = dtoh32a(xdata); 15933bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij ptp_debug (params ,"event %d: currentvalue of %x is %x", i, proptype, dpd->CurrentValue.u32); 1594ac052c1ac330b94932d2b4f774e0053e78e91216Linus Walleij break; 1595f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case PTP_DTC_UINT16: 1596e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij dpd->FactoryDefaultValue.u16 = dtoh16a(xdata); 1597e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij dpd->CurrentValue.u16 = dtoh16a(xdata); 15983bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij ptp_debug (params,"event %d: currentvalue of %x is %x", i, proptype, dpd->CurrentValue.u16); 1599f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1600f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case PTP_DTC_UINT8: 1601e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij dpd->FactoryDefaultValue.u8 = dtoh8a(xdata); 1602e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij dpd->CurrentValue.u8 = dtoh8a(xdata); 16033bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij ptp_debug (params,"event %d: currentvalue of %x is %x", i, proptype, dpd->CurrentValue.u8); 1604f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1605f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case PTP_DTC_STR: { 16061a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij#if 0 /* 5D MII and 400D aktually store plain ASCII in their string properties */ 1607f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij uint8_t len = 0; 1608f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij dpd->FactoryDefaultValue.str = ptp_unpack_string(params, data, 0, &len); 1609f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij dpd->CurrentValue.str = ptp_unpack_string(params, data, 0, &len); 16101a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij#else 16110d762ccc39331608119dd0267021b165e22de499Linus Walleij if (dpd->FactoryDefaultValue.str) free (dpd->FactoryDefaultValue.str); 1612e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij dpd->FactoryDefaultValue.str = strdup( (char*)xdata ); 16130d762ccc39331608119dd0267021b165e22de499Linus Walleij 16140d762ccc39331608119dd0267021b165e22de499Linus Walleij if (dpd->CurrentValue.str) free (dpd->CurrentValue.str); 1615e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij dpd->CurrentValue.str = strdup( (char*)xdata ); 16161a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij#endif 16177e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij ptp_debug (params,"event %d: currentvalue of %x is %s", i, proptype, dpd->CurrentValue.str); 1618f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1619f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 1620f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij default: 1621f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij /* debug is printed in switch above this one */ 1622f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1623f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 16241a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 1625d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij /* ImageFormat special handling (WARNING: dont move this in front of the dpd->DataType switch!) */ 1626d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij switch (proptype) { 1627d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij case PTP_DPC_CANON_EOS_ImageFormat: 1628d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij case PTP_DPC_CANON_EOS_ImageFormatCF: 1629d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij case PTP_DPC_CANON_EOS_ImageFormatSD: 1630d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij case PTP_DPC_CANON_EOS_ImageFormatExtHD: 1631d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij dpd->DataType = PTP_DTC_UINT16; 1632e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij dpd->FactoryDefaultValue.u16 = ptp_unpack_EOS_ImageFormat( params, &xdata ); 1633d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij dpd->CurrentValue.u16 = dpd->FactoryDefaultValue.u16; 1634d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij ptp_debug (params,"event %d: decoded imageformat, currentvalue of %x is %x", i, proptype, dpd->CurrentValue.u16); 1635d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij break; 1636d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij } 1637d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij 1638f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1639f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 1640d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij case PTP_EC_CANON_EOS_CameraStatusChanged: 1641d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij ptp_debug (params, "event %d: EOS event CameraStatusChanged (size %d)", i, size); 1642d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij (*ce)[i].type = PTP_CANON_EOS_CHANGES_TYPE_CAMERASTATUS; 1643d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij (*ce)[i].u.status = dtoh32a(curdata+8); 16449e09ad0e32cbdac88637d4ee2cc02ca3b771ca40Linus Walleij params->eos_camerastatus = dtoh32a(curdata+8); 1645d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij break; 16467e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case 0: /* end marker */ 16477e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij if (size == 8) /* no output */ 16487e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij break; 16497e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij ptp_debug (params, "event %d: EOS event 0, but size %d", i, size); 16507e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij break; 1651f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij default: 1652d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij switch (type) { 1653d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij#define XX(x) case PTP_EC_CANON_EOS_##x: \ 1654d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij ptp_debug (params, "event %d: unhandled EOS event "#x" (size %d)", i, size); \ 1655d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij (*ce)[i].u.info = malloc(strlen("unhandled EOS event "#x" (size 123456789)")); \ 1656d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij sprintf ((*ce)[i].u.info, "unhandled EOS event "#x" (size %d)", size); \ 1657d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij break; 1658d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(RequestGetEvent) 1659d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(ObjectRemoved) 1660d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(RequestGetObjectInfoEx) 1661d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(StorageStatusChanged) 1662d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(StorageInfoChanged) 1663d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(ObjectInfoChangedEx) 1664d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(ObjectContentChanged) 1665d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(WillSoonShutdown) 1666d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(ShutdownTimerUpdated) 1667d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(RequestCancelTransfer) 1668d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(RequestObjectTransferDT) 1669d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(RequestCancelTransferDT) 1670d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(StoreAdded) 1671d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(StoreRemoved) 1672d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(BulbExposureTime) 1673d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(RecordingTime) 1674d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(RequestObjectTransferTS) 1675d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(AfResult) 1676d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij#undef XX 1677d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij default: 1678d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij ptp_debug (params, "event %d: unknown EOS event %04x", i, type); 1679d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij break; 1680d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij } 16817e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij if (size >= 0x8) { /* event info */ 16827e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij int j; 1683d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij for (j=8;j<size;j++) 1684d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij ptp_debug (params, " %d: %02x", j, curdata[j]); 16857e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij } 1686f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij (*ce)[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN; 1687f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1688f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 1689f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij curdata += size; 1690f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij i++; 16919d22ce0e3214f38d30435fb9ec8ff2c8c6c4191eLinus Walleij if ((size == 8) && (type == 0)) 16929d22ce0e3214f38d30435fb9ec8ff2c8c6c4191eLinus Walleij break; 1693f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 16940d762ccc39331608119dd0267021b165e22de499Linus Walleij if (!entries) { 16950d762ccc39331608119dd0267021b165e22de499Linus Walleij free (*ce); 16960d762ccc39331608119dd0267021b165e22de499Linus Walleij *ce = NULL; 16970d762ccc39331608119dd0267021b165e22de499Linus Walleij } 1698f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij return entries; 1699f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij} 1700f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij 1701f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij/* 1702b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij PTP USB Event container unpack for Nikon events. 1703b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij*/ 1704b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_nikon_ec_Length 0 1705b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_nikon_ec_Code 2 1706b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_nikon_ec_Param1 4 1707b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_nikon_ec_Size 6 1708b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 17097e75653e64021908ca66b155eeb950d8304c87d8Linus Walleijptp_unpack_Nikon_EC (PTPParams *params, unsigned char* data, unsigned int len, PTPContainer **ec, int *cnt) 1710b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij{ 1711b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij int i; 1712b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 1713b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij *ec = NULL; 1714b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (data == NULL) 1715b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return; 1716b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (len < PTP_nikon_ec_Code) 1717b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return; 1718b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij *cnt = dtoh16a(&data[PTP_nikon_ec_Length]); 1719b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (*cnt > (len-PTP_nikon_ec_Code)/PTP_nikon_ec_Size) /* broken cnt? */ 1720b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return; 17210d762ccc39331608119dd0267021b165e22de499Linus Walleij if (!*cnt) 17220d762ccc39331608119dd0267021b165e22de499Linus Walleij return; 17230d762ccc39331608119dd0267021b165e22de499Linus Walleij 17247e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij *ec = malloc(sizeof(PTPContainer)*(*cnt)); 1725b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 1726b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<*cnt;i++) { 17277e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij memset(&(*ec)[i],0,sizeof(PTPContainer)); 17287e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij (*ec)[i].Code = dtoh16a(&data[PTP_nikon_ec_Code+PTP_nikon_ec_Size*i]); 17297e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij (*ec)[i].Param1 = dtoh32a(&data[PTP_nikon_ec_Param1+PTP_nikon_ec_Size*i]); 17307e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij (*ec)[i].Nparam = 1; 1731b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 1732eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 1733eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 1734eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 1735b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint32_t 1736b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_pack_EK_text(PTPParams *params, PTPEKTextParams *text, unsigned char **data) { 1737b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij int i, len = 0; 1738b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij uint8_t retlen; 1739b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij unsigned char *curdata; 1740b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 1741b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij len = 2*(strlen(text->title)+1)+1+ 1742b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 2*(strlen(text->line[0])+1)+1+ 1743b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 2*(strlen(text->line[1])+1)+1+ 1744b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 2*(strlen(text->line[2])+1)+1+ 1745b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 2*(strlen(text->line[3])+1)+1+ 1746b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 2*(strlen(text->line[4])+1)+1+ 1747b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 4*2+2*4+2+4+2+5*4*2; 1748b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij *data = malloc(len); 1749b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!*data) return 0; 1750b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 1751b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij curdata = *data; 1752b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,100);curdata+=2; 1753b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,1);curdata+=2; 1754b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,0);curdata+=2; 1755b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,1000);curdata+=2; 1756b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 1757b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(curdata,0);curdata+=4; 1758b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(curdata,0);curdata+=4; 1759b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 1760b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,6);curdata+=2; 1761b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(curdata,0);curdata+=4; 1762b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 1763b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ptp_pack_string(params, text->title, curdata, 0, &retlen); curdata+=2*retlen+1;htod16a(curdata,0);curdata+=2; 1764b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,0x10);curdata+=2; 1765b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 1766b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<5;i++) { 1767b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ptp_pack_string(params, text->line[i], curdata, 0, &retlen); curdata+=2*retlen+1;htod16a(curdata,0);curdata+=2; 1768b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,0x10);curdata+=2; 1769b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,0x01);curdata+=2; 1770b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,0x02);curdata+=2; 1771b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,0x06);curdata+=2; 1772b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 1773b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return len; 1774b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij} 17757347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij 17767347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_version 0x00 17777347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_ofc 0x02 17787347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_unk1 0x04 17797347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_objectid 0x08 17807347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_parentid 0x0c 17817347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_previd 0x10 /* in same dir */ 17827347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_nextid 0x14 /* in same dir */ 17837347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_nextchild 0x18 /* down one dir */ 17847347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_storageid 0x1c /* only in storage entry */ 17857347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_name 0x20 17867347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_flags 0x2c 17877347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_size 0x30 17887347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_unixtime 0x34 17897347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_year 0x38 17907347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_month 0x39 17917347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_mday 0x3a 17927347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_hour 0x3b 17937347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_minute 0x3c 17947347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_second 0x3d 17957347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_unk2 0x3e 17967347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_thumbsize 0x40 17977347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_width 0x44 17987347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_height 0x48 17997347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij 18007347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleijstatic inline uint16_t 18017347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleijptp_unpack_canon_directory ( 18027347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij PTPParams *params, 18037347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij unsigned char *dir, 18047347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij uint32_t cnt, 18057347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij PTPObjectHandles *handles, 18067347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij PTPObjectInfo **oinfos, /* size(handles->n) */ 18077347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij uint32_t **flags /* size(handles->n) */ 18087347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij) { 18097347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij unsigned int i, j, nrofobs = 0, curob = 0; 18107347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij 18117347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ISOBJECT(ptr) (dtoh32a((ptr)+ptp_canon_dir_storageid) == 0xffffffff) 18127347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij for (i=0;i<cnt;i++) 18137347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (ISOBJECT(dir+i*0x4c)) nrofobs++; 18147347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij handles->n = nrofobs; 18157347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij handles->Handler = calloc(sizeof(handles->Handler[0]),nrofobs); 18167347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (!handles->Handler) return PTP_RC_GeneralError; 18177347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij *oinfos = calloc(sizeof((*oinfos)[0]),nrofobs); 18187347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (!*oinfos) return PTP_RC_GeneralError; 18197347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij *flags = calloc(sizeof((*flags)[0]),nrofobs); 18207347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (!*flags) return PTP_RC_GeneralError; 18217347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij 18227347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij /* Migrate data into objects ids, handles into 18237347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij * the object handler array. 18247347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij */ 18257347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij curob = 0; 18267347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij for (i=0;i<cnt;i++) { 18277347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij unsigned char *cur = dir+i*0x4c; 18287347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij PTPObjectInfo *oi = (*oinfos)+curob; 18297347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij 18307347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (!ISOBJECT(cur)) 18317347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij continue; 18327347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij 18337347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij handles->Handler[curob] = dtoh32a(cur + ptp_canon_dir_objectid); 18347347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij oi->StorageID = 0xffffffff; 18357347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij oi->ObjectFormat = dtoh16a(cur + ptp_canon_dir_ofc); 18367347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij oi->ParentObject = dtoh32a(cur + ptp_canon_dir_parentid); 18377347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij oi->Filename = strdup((char*)(cur + ptp_canon_dir_name)); 18387347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij oi->ObjectCompressedSize= dtoh32a(cur + ptp_canon_dir_size); 18397347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij oi->ThumbCompressedSize = dtoh32a(cur + ptp_canon_dir_thumbsize); 18407347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij oi->ImagePixWidth = dtoh32a(cur + ptp_canon_dir_width); 18417347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij oi->ImagePixHeight = dtoh32a(cur + ptp_canon_dir_height); 18427347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij oi->CaptureDate = oi->ModificationDate = dtoh32a(cur + ptp_canon_dir_unixtime); 18437347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij (*flags)[curob] = dtoh32a(cur + ptp_canon_dir_flags); 18447347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij curob++; 18457347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 18467347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij /* Walk over Storage ID entries and distribute the IDs to 18477347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij * the parent objects. */ 18487347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij for (i=0;i<cnt;i++) { 18497347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij unsigned char *cur = dir+i*0x4c; 18507347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij uint32_t nextchild = dtoh32a(cur + ptp_canon_dir_nextchild); 18517347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij 18527347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (ISOBJECT(cur)) 18537347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij continue; 18547347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij for (j=0;j<handles->n;j++) if (nextchild == handles->Handler[j]) break; 18557347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (j == handles->n) continue; 18567347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij (*oinfos)[j].StorageID = dtoh32a(cur + ptp_canon_dir_storageid); 18577347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 18587347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij /* Walk over all objects and distribute the storage ids */ 18597347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij while (1) { 18607347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij int changed = 0; 18617347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij for (i=0;i<cnt;i++) { 18627347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij unsigned char *cur = dir+i*0x4c; 18637347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij uint32_t oid = dtoh32a(cur + ptp_canon_dir_objectid); 18647347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij uint32_t nextoid = dtoh32a(cur + ptp_canon_dir_nextid); 18657347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij uint32_t nextchild = dtoh32a(cur + ptp_canon_dir_nextchild); 18667347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij uint32_t storageid; 18677347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij 18687347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (!ISOBJECT(cur)) 18697347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij continue; 18707347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij for (j=0;j<handles->n;j++) if (oid == handles->Handler[j]) break; 18717347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (j == handles->n) { 18727347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij /*fprintf(stderr,"did not find oid in lookup pass for current oid\n");*/ 18737347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij continue; 18747347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 18757347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij storageid = (*oinfos)[j].StorageID; 18767347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (storageid == 0xffffffff) continue; 18777347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (nextoid != 0xffffffff) { 18787347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij for (j=0;j<handles->n;j++) if (nextoid == handles->Handler[j]) break; 18797347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (j == handles->n) { 18807347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij /*fprintf(stderr,"did not find oid in lookup pass for next oid\n");*/ 18817347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij continue; 18827347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 18837347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if ((*oinfos)[j].StorageID == 0xffffffff) { 18847347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij (*oinfos)[j].StorageID = storageid; 18857347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij changed++; 18867347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 18877347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 18887347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (nextchild != 0xffffffff) { 18897347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij for (j=0;j<handles->n;j++) if (nextchild == handles->Handler[j]) break; 18907347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (j == handles->n) { 18917347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij /*fprintf(stderr,"did not find oid in lookup pass for next child\n");*/ 18927347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij continue; 18937347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 18947347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if ((*oinfos)[j].StorageID == 0xffffffff) { 18957347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij (*oinfos)[j].StorageID = storageid; 18967347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij changed++; 18977347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 18987347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 18997347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 19007347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij /* Check if we: 19017347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij * - changed no entry (nothing more to do) 19027347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij * - changed all of them at once (usually happens) 19037347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij * break if we do. 19047347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij */ 19057347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (!changed || (changed==nrofobs-1)) 19067347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij break; 19077347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 19087347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#undef ISOBJECT 19097347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij return PTP_RC_OK; 19107347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij} 1911