ptp-pack.c revision cc2659036a503fce161cb77d9b0af17a52d7437b
1b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij/* currently this file is included into ptp.c */ 2eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 3a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij#include <iconv.h> 4a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij 5b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint16_t 6eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleijhtod16p (PTPParams *params, uint16_t var) 7eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 8eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return ((params->byteorder==PTP_DL_LE)?htole16(var):htobe16(var)); 9eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 10eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 11b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint32_t 12eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleijhtod32p (PTPParams *params, uint32_t var) 13eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 14eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return ((params->byteorder==PTP_DL_LE)?htole32(var):htobe32(var)); 15eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 16eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 17b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 18eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleijhtod16ap (PTPParams *params, unsigned char *a, uint16_t val) 19eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 20eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij if (params->byteorder==PTP_DL_LE) 21b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htole16a(a,val); 22b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij else 23eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htobe16a(a,val); 24eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 25eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 26b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 27eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleijhtod32ap (PTPParams *params, unsigned char *a, uint32_t val) 28eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 29eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij if (params->byteorder==PTP_DL_LE) 30b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htole32a(a,val); 31b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij else 32eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htobe32a(a,val); 33eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 34eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 35abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleijstatic inline void 36abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleijhtod64ap (PTPParams *params, unsigned char *a, uint64_t val) 37abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij{ 38abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij if (params->byteorder==PTP_DL_LE) 39abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij htole64a(a,val); 40abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij else 41abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij htobe64a(a,val); 42abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij} 43abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij 44b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint16_t 45eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleijdtoh16p (PTPParams *params, uint16_t var) 46eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 47eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return ((params->byteorder==PTP_DL_LE)?le16toh(var):be16toh(var)); 48eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 49eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 50b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint32_t 51eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleijdtoh32p (PTPParams *params, uint32_t var) 52eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 53eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return ((params->byteorder==PTP_DL_LE)?le32toh(var):be32toh(var)); 54eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 55eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 56abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleijstatic inline uint64_t 57abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleijdtoh64p (PTPParams *params, uint64_t var) 58abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij{ 59abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij return ((params->byteorder==PTP_DL_LE)?le64toh(var):be64toh(var)); 60abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij} 61abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij 62b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint16_t 63eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleijdtoh16ap (PTPParams *params, unsigned char *a) 64eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 65eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return ((params->byteorder==PTP_DL_LE)?le16atoh(a):be16atoh(a)); 66eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 67eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 68b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint32_t 69eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleijdtoh32ap (PTPParams *params, unsigned char *a) 70eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 71eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return ((params->byteorder==PTP_DL_LE)?le32atoh(a):be32atoh(a)); 72eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 73eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 74b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint64_t 75eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleijdtoh64ap (PTPParams *params, unsigned char *a) 76eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 77abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij return ((params->byteorder==PTP_DL_LE)?le64atoh(a):be64atoh(a)); 78abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij /* 79b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij uint64_t tmp = 0; 80b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij int i; 81b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 82b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (params->byteorder==PTP_DL_LE) { 83b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<8;i++) 84b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij tmp |= (((uint64_t)a[i]) << (8*i)); 85b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } else { 86b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<8;i++) 87b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij tmp |= (((uint64_t)a[i]) << (8*(7-i))); 88b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 89b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return tmp; 90abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij */ 91eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 92eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 93b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define htod8a(a,x) *(uint8_t*)(a) = x 94b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define htod16a(a,x) htod16ap(params,a,x) 95b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define htod32a(a,x) htod32ap(params,a,x) 96abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij#define htod64a(a,x) htod64ap(params,a,x) 97b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define htod16(x) htod16p(params,x) 98b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define htod32(x) htod32p(params,x) 99abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij#define htod64(x) htod64p(params,x) 100b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 101b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define dtoh8a(x) (*(uint8_t*)(x)) 102b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define dtoh16a(a) dtoh16ap(params,a) 103b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define dtoh32a(a) dtoh32ap(params,a) 104b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define dtoh64a(a) dtoh64ap(params,a) 105b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define dtoh16(x) dtoh16p(params,x) 106b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define dtoh32(x) dtoh32p(params,x) 107abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij#define dtoh64(x) dtoh64p(params,x) 108b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 109b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 110b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline char* 111b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_string(PTPParams *params, unsigned char* data, uint16_t offset, uint8_t *len) 112eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 113a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij uint8_t length; 114a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij uint16_t string[PTP_MAXSTRLEN+1]; 115a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij /* allow for UTF-8: max of 3 bytes per UCS-2 char, plus final null */ 116a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij char loclstr[PTP_MAXSTRLEN*3+1]; 117a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij size_t nconv, srclen, destlen; 118a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij char *src, *dest; 119a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij 120a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij length = dtoh8a(&data[offset]); /* PTP_MAXSTRLEN == 255, 8 bit len */ 121a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij *len = length; 122a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij if (length == 0) /* nothing to do? */ 123a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij return(NULL); 124a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij 125a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij /* copy to string[] to ensure correct alignment for iconv(3) */ 126a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij memcpy(string, &data[offset+1], length * sizeof(string[0])); 127a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij string[length] = 0x0000U; /* be paranoid! add a terminator. */ 128a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij loclstr[0] = '\0'; 129a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij 130a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij /* convert from camera UCS-2 to our locale */ 131a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij src = (char *)string; 132a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij srclen = length * sizeof(string[0]); 133a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij dest = loclstr; 134a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij destlen = sizeof(loclstr)-1; 135a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij nconv = iconv(params->cd_ucs2_to_locale, &src, &srclen, 136a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij &dest, &destlen); 137a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij if (nconv == (size_t) -1) { /* do it the hard way */ 138a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij int i; 139a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij /* try the old way, in case iconv is broken */ 140a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij for (i=0;i<length;i++) { 141a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij if (dtoh16a(&data[offset+1+2*i])>127) 142a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij loclstr[i] = '?'; 143a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij else 144a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij loclstr[i] = dtoh16a(&data[offset+1+2*i]); 145eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 146a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij dest = loclstr+length; 147eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 148a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij *dest = '\0'; 149a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij loclstr[sizeof(loclstr)-1] = '\0'; /* be safe? */ 150a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij return(strdup(loclstr)); 151a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij} 152a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij 153a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleijstatic inline int 154a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleijucs2strlen(uint16_t const * const unicstr) 155a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij{ 156a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij int length; 157a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij 158a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij /* Unicode strings are terminated with 2 * 0x00 */ 159a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij for(length = 0; unicstr[length] != 0x0000U; length ++); 160a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij return length; 161eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 162eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 163a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij 164b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 165b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_pack_string(PTPParams *params, char *string, unsigned char* data, uint16_t offset, uint8_t *len) 166eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 167a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij int packedlen; 168a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij uint16_t ucs2str[PTP_MAXSTRLEN+1]; 169a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij char *ucs2strp = (char *) ucs2str; 170a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij char *stringp = string; 171a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij size_t nconv; 172a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij size_t convlen = strlen(string); 173a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij size_t convmax = PTP_MAXSTRLEN * 2; /* Includes the terminator */ 174a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij 175a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij /* Cannot exceed 255 (PTP_MAXSTRLEN) since it is a single byte, duh ... */ 176a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij memset(ucs2strp, 0, sizeof(ucs2str)); /* XXX: necessary? */ 177a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij nconv = iconv(params->cd_locale_to_ucs2, &stringp, &convlen, 178a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij &ucs2strp, &convmax); 1794f40d11374a0ea3c4038f3b18a3601b3bbfe6dcfLinus Walleij if (nconv == (size_t) -1) 180a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij ucs2str[0] = 0x0000U; 181a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij /* 182a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij * XXX: isn't packedlen just ( (uint16_t *)ucs2strp - ucs2str )? 183a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij * why do we need ucs2strlen()? 184a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij */ 185a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij packedlen = ucs2strlen(ucs2str); 186a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij if (packedlen > PTP_MAXSTRLEN-1) { 187a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij *len=0; 188a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij return; 189a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij } 190958441f8ed3e704cf07c9f600730f90a80a0d424Linus Walleij 1917f2343824550452974d78f5dbd94e64844355c33Linus Walleij /* number of characters including terminating 0 (PTP standard confirmed) */ 192a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij htod8a(&data[offset],packedlen+1); 193a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij memcpy(&data[offset+1], &ucs2str[0], packedlen * sizeof(ucs2str[0])); 194a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij htod16a(&data[offset+packedlen*2+1], 0x0000); /* terminate 0 */ 195958441f8ed3e704cf07c9f600730f90a80a0d424Linus Walleij 196958441f8ed3e704cf07c9f600730f90a80a0d424Linus Walleij /* The returned length is in number of characters */ 197048d938dc4889b74b258a786d5f53142b059fc32Linus Walleij *len = (uint8_t) packedlen+1; 198eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 199eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 200a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleijstatic inline unsigned char * 201735f41692934a716158cf051d76e988febeca7eeLinus Walleijptp_get_packed_stringcopy(PTPParams *params, char *string, uint32_t *packed_size) 202a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij{ 2038b42ca3d3baeb7c8f3e5eca88c613adb612e4ec0Richard Low uint8_t packed[PTP_MAXSTRLEN*2+3], len; 204a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij size_t plen; 205a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij unsigned char *retcopy = NULL; 206a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij 207a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij ptp_pack_string(params, string, (unsigned char*) packed, 0, &len); 208958441f8ed3e704cf07c9f600730f90a80a0d424Linus Walleij /* returned length is in characters, then one byte for string length */ 209958441f8ed3e704cf07c9f600730f90a80a0d424Linus Walleij plen = len*2 + 1; 210048d938dc4889b74b258a786d5f53142b059fc32Linus Walleij 211a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij retcopy = malloc(plen); 212735f41692934a716158cf051d76e988febeca7eeLinus Walleij if (!retcopy) { 213735f41692934a716158cf051d76e988febeca7eeLinus Walleij *packed_size = 0; 214a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij return NULL; 215735f41692934a716158cf051d76e988febeca7eeLinus Walleij } 216a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij memcpy(retcopy, packed, plen); 217735f41692934a716158cf051d76e988febeca7eeLinus Walleij *packed_size = plen; 218a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij return (retcopy); 219a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij} 220a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij 221b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint32_t 222b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_uint32_t_array(PTPParams *params, unsigned char* data, uint16_t offset, uint32_t **array) 223eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 224eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint32_t n, i=0; 225eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 226eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij n=dtoh32a(&data[offset]); 227eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij *array = malloc (n*sizeof(uint32_t)); 228eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij while (n>i) { 229eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij (*array)[i]=dtoh32a(&data[offset+(sizeof(uint32_t)*(i+1))]); 230eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij i++; 231eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 232eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return n; 233eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 234eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 235b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint32_t 236f67bca9bde733f456ad341c0d852147124ab388aLinus Walleijptp_pack_uint32_t_array(PTPParams *params, uint32_t *array, uint32_t arraylen, unsigned char **data ) 237f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij{ 238f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij uint32_t i=0; 239f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij 240f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij *data = malloc ((arraylen+1)*sizeof(uint32_t)); 241f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij htod32a(&(*data)[0],arraylen); 242f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij for (i=0;i<arraylen;i++) 243f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij htod32a(&(*data)[sizeof(uint32_t)*(i+1)], array[i]); 244f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij return (arraylen+1)*sizeof(uint32_t); 245f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij} 246f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij 247f67bca9bde733f456ad341c0d852147124ab388aLinus Walleijstatic inline uint32_t 248b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_uint16_t_array(PTPParams *params, unsigned char* data, uint16_t offset, uint16_t **array) 249eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 250eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint32_t n, i=0; 251eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 252eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij n=dtoh32a(&data[offset]); 253eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij *array = malloc (n*sizeof(uint16_t)); 254eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij while (n>i) { 255eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij (*array)[i]=dtoh16a(&data[offset+(sizeof(uint16_t)*(i+2))]); 256eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij i++; 257eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 258eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return n; 259eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 260eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 261eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* DeviceInfo pack/unpack */ 262eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 263eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_di_StandardVersion 0 264eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_di_VendorExtensionID 2 265eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_di_VendorExtensionVersion 6 266eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_di_VendorExtensionDesc 8 267eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_di_FunctionalMode 8 268eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_di_OperationsSupported 10 269eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 270b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 271b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_DI (PTPParams *params, unsigned char* data, PTPDeviceInfo *di, unsigned int datalen) 272eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 273eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint8_t len; 274eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij unsigned int totallen; 275eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 2767347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij di->StandardVersion = dtoh16a(&data[PTP_di_StandardVersion]); 277eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->VendorExtensionID = 278eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij dtoh32a(&data[PTP_di_VendorExtensionID]); 279eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->VendorExtensionVersion = 280eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij dtoh16a(&data[PTP_di_VendorExtensionVersion]); 281eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->VendorExtensionDesc = 282eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij ptp_unpack_string(params, data, 283eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_VendorExtensionDesc, &len); 284eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen=len*2+1; 285eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->FunctionalMode = 286eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij dtoh16a(&data[PTP_di_FunctionalMode+totallen]); 287eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->OperationsSupported_len = ptp_unpack_uint16_t_array(params, data, 288eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 289eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &di->OperationsSupported); 290eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen=totallen+di->OperationsSupported_len*sizeof(uint16_t)+sizeof(uint32_t); 291eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->EventsSupported_len = ptp_unpack_uint16_t_array(params, data, 292eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 293eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &di->EventsSupported); 294eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen=totallen+di->EventsSupported_len*sizeof(uint16_t)+sizeof(uint32_t); 295eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->DevicePropertiesSupported_len = 296eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij ptp_unpack_uint16_t_array(params, data, 297eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 298eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &di->DevicePropertiesSupported); 299eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen=totallen+di->DevicePropertiesSupported_len*sizeof(uint16_t)+sizeof(uint32_t); 300eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->CaptureFormats_len = ptp_unpack_uint16_t_array(params, data, 301eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 302eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &di->CaptureFormats); 303eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen=totallen+di->CaptureFormats_len*sizeof(uint16_t)+sizeof(uint32_t); 304eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->ImageFormats_len = ptp_unpack_uint16_t_array(params, data, 305eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 306eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &di->ImageFormats); 307eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen=totallen+di->ImageFormats_len*sizeof(uint16_t)+sizeof(uint32_t); 308eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->Manufacturer = ptp_unpack_string(params, data, 309eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 310eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &len); 311eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen+=len*2+1; 312eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->Model = ptp_unpack_string(params, data, 313eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 314eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &len); 315eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen+=len*2+1; 316eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->DeviceVersion = ptp_unpack_string(params, data, 317eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 318eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &len); 319eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen+=len*2+1; 320eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->SerialNumber = ptp_unpack_string(params, data, 321eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 322eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &len); 323eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 324a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij 325a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleijstatic void 326a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleijptp_free_DI (PTPDeviceInfo *di) { 327a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij if (di->SerialNumber) free (di->SerialNumber); 328a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij if (di->DeviceVersion) free (di->DeviceVersion); 329a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij if (di->Model) free (di->Model); 330a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij if (di->Manufacturer) free (di->Manufacturer); 331a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij if (di->ImageFormats) free (di->ImageFormats); 332a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij if (di->CaptureFormats) free (di->CaptureFormats); 333a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij if (di->VendorExtensionDesc) free (di->VendorExtensionDesc); 334a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij if (di->OperationsSupported) free (di->OperationsSupported); 335a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij if (di->EventsSupported) free (di->EventsSupported); 336a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij if (di->DevicePropertiesSupported) free (di->DevicePropertiesSupported); 337a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij} 338eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 339eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* ObjectHandles array pack/unpack */ 340eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 341eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oh 0 342eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 343b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 344b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_OH (PTPParams *params, unsigned char* data, PTPObjectHandles *oh, unsigned int len) 345eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 346f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if (len) { 347f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij oh->n = ptp_unpack_uint32_t_array(params, data, PTP_oh, &oh->Handler); 348f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } else { 349f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij oh->n = 0; 350f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij oh->Handler = NULL; 351f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 352eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 353eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 354eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* StoreIDs array pack/unpack */ 355eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 356eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_sids 0 357eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 358b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 359b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_SIDs (PTPParams *params, unsigned char* data, PTPStorageIDs *sids, unsigned int len) 360eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 361eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij sids->n = ptp_unpack_uint32_t_array(params, data, PTP_sids, 362eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &sids->Storage); 363eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 364eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 365eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* StorageInfo pack/unpack */ 366eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 367eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_si_StorageType 0 368eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_si_FilesystemType 2 369eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_si_AccessCapability 4 370eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_si_MaxCapability 6 371eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_si_FreeSpaceInBytes 14 372eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_si_FreeSpaceInImages 22 373eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_si_StorageDescription 26 374eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 375b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 376b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_SI (PTPParams *params, unsigned char* data, PTPStorageInfo *si, unsigned int len) 377eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 378eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint8_t storagedescriptionlen; 379eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 380eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->StorageType=dtoh16a(&data[PTP_si_StorageType]); 381eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->FilesystemType=dtoh16a(&data[PTP_si_FilesystemType]); 382eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->AccessCapability=dtoh16a(&data[PTP_si_AccessCapability]); 383eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->MaxCapability=dtoh64a(&data[PTP_si_MaxCapability]); 384eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->FreeSpaceInBytes=dtoh64a(&data[PTP_si_FreeSpaceInBytes]); 385eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->FreeSpaceInImages=dtoh32a(&data[PTP_si_FreeSpaceInImages]); 386eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->StorageDescription=ptp_unpack_string(params, data, 387eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_si_StorageDescription, &storagedescriptionlen); 388eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->VolumeLabel=ptp_unpack_string(params, data, 389eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_si_StorageDescription+storagedescriptionlen*2+1, 390eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &storagedescriptionlen); 391eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 392eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 393eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* ObjectInfo pack/unpack */ 394eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 395eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_StorageID 0 396eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ObjectFormat 4 397eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ProtectionStatus 6 398eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ObjectCompressedSize 8 399eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ThumbFormat 12 400eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ThumbCompressedSize 14 401eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ThumbPixWidth 18 402eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ThumbPixHeight 22 403eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ImagePixWidth 26 404eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ImagePixHeight 30 405eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ImageBitDepth 34 406eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ParentObject 38 407eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_AssociationType 42 408eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_AssociationDesc 44 409eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_SequenceNumber 48 410eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_filenamelen 52 411eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_Filename 53 412eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 413a032327c7485548c42f8162f87469dc0e0dd2126Linus Walleij/* the max length assuming zero length dates. We have need 3 */ 414a032327c7485548c42f8162f87469dc0e0dd2126Linus Walleij/* bytes for these. */ 415a679b1c4d273f210abb6befc5d9954a25427c329Richard Low#define PTP_oi_MaxLen PTP_oi_Filename+(PTP_MAXSTRLEN+1)*2+3 416a679b1c4d273f210abb6befc5d9954a25427c329Richard Low 417b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint32_t 418b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_pack_OI (PTPParams *params, PTPObjectInfo *oi, unsigned char** oidataptr) 419eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 420b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij unsigned char* oidata; 421eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint8_t filenamelen; 422eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint8_t capturedatelen=0; 423a679b1c4d273f210abb6befc5d9954a25427c329Richard Low /* let's allocate some memory first; correct assuming zero length dates */ 424a679b1c4d273f210abb6befc5d9954a25427c329Richard Low oidata=malloc(PTP_oi_MaxLen); 425eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij /* the caller should free it after use! */ 426eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#if 0 427eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij char *capture_date="20020101T010101"; /* XXX Fake date */ 428eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#endif 429a679b1c4d273f210abb6befc5d9954a25427c329Richard Low memset (oidata, 0, PTP_oi_MaxLen); 430eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_StorageID],oi->StorageID); 431eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod16a(&oidata[PTP_oi_ObjectFormat],oi->ObjectFormat); 432eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod16a(&oidata[PTP_oi_ProtectionStatus],oi->ProtectionStatus); 433eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ObjectCompressedSize],oi->ObjectCompressedSize); 434eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod16a(&oidata[PTP_oi_ThumbFormat],oi->ThumbFormat); 435eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ThumbCompressedSize],oi->ThumbCompressedSize); 436eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ThumbPixWidth],oi->ThumbPixWidth); 437eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ThumbPixHeight],oi->ThumbPixHeight); 438eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ImagePixWidth],oi->ImagePixWidth); 439eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ImagePixHeight],oi->ImagePixHeight); 440eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ImageBitDepth],oi->ImageBitDepth); 441eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ParentObject],oi->ParentObject); 442eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod16a(&oidata[PTP_oi_AssociationType],oi->AssociationType); 443eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_AssociationDesc],oi->AssociationDesc); 444eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_SequenceNumber],oi->SequenceNumber); 445eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 446eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij ptp_pack_string(params, oi->Filename, oidata, PTP_oi_filenamelen, &filenamelen); 447eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* 448eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij filenamelen=(uint8_t)strlen(oi->Filename); 449eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod8a(&req->data[PTP_oi_filenamelen],filenamelen+1); 450eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij for (i=0;i<filenamelen && i< PTP_MAXSTRLEN; i++) { 451eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij req->data[PTP_oi_Filename+i*2]=oi->Filename[i]; 452eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 453eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij*/ 454eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij /* 455eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij *XXX Fake date. 456eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij * for example Kodak sets Capture date on the basis of EXIF data. 457eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij * Spec says that this field is from perspective of Initiator. 458eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij */ 459eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#if 0 /* seems now we don't need any data packed in OI dataset... for now ;)*/ 460eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij capturedatelen=strlen(capture_date); 461eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod8a(&data[PTP_oi_Filename+(filenamelen+1)*2], 462eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij capturedatelen+1); 463eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij for (i=0;i<capturedatelen && i< PTP_MAXSTRLEN; i++) { 464eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij data[PTP_oi_Filename+(i+filenamelen+1)*2+1]=capture_date[i]; 465eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 466eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod8a(&data[PTP_oi_Filename+(filenamelen+capturedatelen+2)*2+1], 467eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij capturedatelen+1); 468eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij for (i=0;i<capturedatelen && i< PTP_MAXSTRLEN; i++) { 469eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij data[PTP_oi_Filename+(i+filenamelen+capturedatelen+2)*2+2]= 470eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij capture_date[i]; 471eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 472eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#endif 473eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij /* XXX this function should return dataset length */ 474eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 475eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij *oidataptr=oidata; 476a679b1c4d273f210abb6befc5d9954a25427c329Richard Low return (PTP_oi_Filename+filenamelen*2+(capturedatelen+1)*3); 477eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 478eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 479b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 480b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_OI (PTPParams *params, unsigned char* data, PTPObjectInfo *oi, unsigned int len) 481eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 482eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint8_t filenamelen; 483eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint8_t capturedatelen; 484eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij char *capture_date; 485eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij char tmp[16]; 486eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij struct tm tm; 487eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 488eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij memset(&tm,0,sizeof(tm)); 489eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 490eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->StorageID=dtoh32a(&data[PTP_oi_StorageID]); 491eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ObjectFormat=dtoh16a(&data[PTP_oi_ObjectFormat]); 492eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ProtectionStatus=dtoh16a(&data[PTP_oi_ProtectionStatus]); 493eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ObjectCompressedSize=dtoh32a(&data[PTP_oi_ObjectCompressedSize]); 494eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ThumbFormat=dtoh16a(&data[PTP_oi_ThumbFormat]); 495eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ThumbCompressedSize=dtoh32a(&data[PTP_oi_ThumbCompressedSize]); 496eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ThumbPixWidth=dtoh32a(&data[PTP_oi_ThumbPixWidth]); 497eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ThumbPixHeight=dtoh32a(&data[PTP_oi_ThumbPixHeight]); 498eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ImagePixWidth=dtoh32a(&data[PTP_oi_ImagePixWidth]); 499eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ImagePixHeight=dtoh32a(&data[PTP_oi_ImagePixHeight]); 500eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ImageBitDepth=dtoh32a(&data[PTP_oi_ImageBitDepth]); 501eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ParentObject=dtoh32a(&data[PTP_oi_ParentObject]); 502eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->AssociationType=dtoh16a(&data[PTP_oi_AssociationType]); 503eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->AssociationDesc=dtoh32a(&data[PTP_oi_AssociationDesc]); 504eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->SequenceNumber=dtoh32a(&data[PTP_oi_SequenceNumber]); 505eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->Filename= ptp_unpack_string(params, data, PTP_oi_filenamelen, &filenamelen); 506eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 507eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij capture_date = ptp_unpack_string(params, data, 508eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_oi_filenamelen+filenamelen*2+1, &capturedatelen); 509eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij /* subset of ISO 8601, without '.s' tenths of second and 510eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij * time zone 511eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij */ 512eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij if (capturedatelen>15) 513eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij { 514eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij strncpy (tmp, capture_date, 4); 515eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tmp[4] = 0; 516eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tm.tm_year=atoi (tmp) - 1900; 517eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij strncpy (tmp, capture_date + 4, 2); 518eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tmp[2] = 0; 519eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tm.tm_mon = atoi (tmp) - 1; 520eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij strncpy (tmp, capture_date + 6, 2); 521eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tmp[2] = 0; 522eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tm.tm_mday = atoi (tmp); 523eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij strncpy (tmp, capture_date + 9, 2); 524eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tmp[2] = 0; 525eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tm.tm_hour = atoi (tmp); 526eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij strncpy (tmp, capture_date + 11, 2); 527eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tmp[2] = 0; 528eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tm.tm_min = atoi (tmp); 529eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij strncpy (tmp, capture_date + 13, 2); 530eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tmp[2] = 0; 531eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tm.tm_sec = atoi (tmp); 532eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->CaptureDate=mktime (&tm); 533eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 534eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij free(capture_date); 535eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 536eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij /* now it's modification date ;) */ 537eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij capture_date = ptp_unpack_string(params, data, 538eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_oi_filenamelen+filenamelen*2 539eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij +capturedatelen*2+2,&capturedatelen); 540eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij if (capturedatelen>15) 541eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij { 542eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij strncpy (tmp, capture_date, 4); 543eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tmp[4] = 0; 544eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tm.tm_year=atoi (tmp) - 1900; 545eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij strncpy (tmp, capture_date + 4, 2); 546eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tmp[2] = 0; 547eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tm.tm_mon = atoi (tmp) - 1; 548eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij strncpy (tmp, capture_date + 6, 2); 549eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tmp[2] = 0; 550eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tm.tm_mday = atoi (tmp); 551eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij strncpy (tmp, capture_date + 9, 2); 552eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tmp[2] = 0; 553eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tm.tm_hour = atoi (tmp); 554eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij strncpy (tmp, capture_date + 11, 2); 555eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tmp[2] = 0; 556eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tm.tm_min = atoi (tmp); 557eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij strncpy (tmp, capture_date + 13, 2); 558eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tmp[2] = 0; 559eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tm.tm_sec = atoi (tmp); 560eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ModificationDate=mktime (&tm); 561eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 562eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij free(capture_date); 563eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 564eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 565eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* Custom Type Value Assignement (without Length) macro frequently used below */ 566b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define CTVAL(target,func) { \ 567b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (total - *offset < sizeof(target)) \ 568b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 0; \ 569b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij target = func(&data[*offset]); \ 570b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij *offset += sizeof(target); \ 571eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 572eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 573b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define RARR(val,member,func) { \ 574b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij int n,j; \ 575b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (total - *offset < sizeof(uint32_t)) \ 576b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 0; \ 577b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij n = dtoh32a (&data[*offset]); \ 578b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij *offset += sizeof(uint32_t); \ 579b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij \ 580b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij val->a.count = n; \ 581b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij val->a.v = malloc(sizeof(val->a.v[0])*n); \ 582b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!val->a.v) return 0; \ 583b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (j=0;j<n;j++) \ 584b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij CTVAL(val->a.v[j].member, func); \ 585b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij} 586eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 587b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline int 588b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_DPV ( 589b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij PTPParams *params, unsigned char* data, int *offset, int total, 590b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij PTPPropertyValue* value, uint16_t datatype 591b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij) { 592eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij switch (datatype) { 593b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_INT8: 594b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij CTVAL(value->i8,dtoh8a); 595b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 596b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_UINT8: 597b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij CTVAL(value->u8,dtoh8a); 598b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 599b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_INT16: 600b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij CTVAL(value->i16,dtoh16a); 601b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 602b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_UINT16: 603b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij CTVAL(value->u16,dtoh16a); 604b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 605b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_INT32: 606b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij CTVAL(value->i32,dtoh32a); 607b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 608b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_UINT32: 609b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij CTVAL(value->u32,dtoh32a); 610b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 611abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij case PTP_DTC_INT64: 612abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij CTVAL(value->i64,dtoh64a); 613abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij break; 614abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij case PTP_DTC_UINT64: 615abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij CTVAL(value->u64,dtoh64a); 616abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij break; 617abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij 618037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij case PTP_DTC_UINT128: 619037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij *offset += 16; 620037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij /*fprintf(stderr,"unhandled unpack of uint128n");*/ 621037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij break; 622037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij case PTP_DTC_INT128: 623037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij *offset += 16; 624037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij /*fprintf(stderr,"unhandled unpack of int128n");*/ 625037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij break; 626037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij 627037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij 628037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij 629b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AINT8: 630b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij RARR(value,i8,dtoh8a); 631b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 632b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AUINT8: 633b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij RARR(value,u8,dtoh8a); 634b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 635b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AUINT16: 636b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij RARR(value,u16,dtoh16a); 637b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 638b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AINT16: 639b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij RARR(value,i16,dtoh16a); 640b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 641b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AUINT32: 642b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij RARR(value,u32,dtoh32a); 643b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 644b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AINT32: 645b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij RARR(value,i32,dtoh32a); 646b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 647abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij case PTP_DTC_AUINT64: 648abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij RARR(value,u64,dtoh64a); 649abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij break; 650abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij case PTP_DTC_AINT64: 651abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij RARR(value,i64,dtoh64a); 652abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij break; 653b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij /* XXX: other int types are unimplemented */ 654b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij /* XXX: other int arrays are unimplemented also */ 655b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_STR: { 656b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij uint8_t len; 657b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij /* XXX: max size */ 658b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij value->str = ptp_unpack_string(params,data,*offset,&len); 659b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij *offset += len*2+1; 660b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!value->str) 661eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return 0; 662b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 663eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 664037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij default: 665037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij return 0; 666b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 667b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 1; 668eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 669eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 670eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* Device Property pack/unpack */ 671eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 672eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_dpd_DevicePropertyCode 0 673eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_dpd_DataType 2 674eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_dpd_GetSet 4 675eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_dpd_FactoryDefaultValue 5 676eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 677b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline int 678b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_DPD (PTPParams *params, unsigned char* data, PTPDevicePropDesc *dpd, unsigned int dpdlen) 679eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 680b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij int offset=0, ret; 681eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 682b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij memset (dpd, 0, sizeof(*dpd)); 683eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij dpd->DevicePropertyCode=dtoh16a(&data[PTP_dpd_DevicePropertyCode]); 684eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij dpd->DataType=dtoh16a(&data[PTP_dpd_DataType]); 685eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij dpd->GetSet=dtoh8a(&data[PTP_dpd_GetSet]); 686b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 687b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij offset = PTP_dpd_FactoryDefaultValue; 688b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->FactoryDefaultValue, dpd->DataType); 689b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 690b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->CurrentValue, dpd->DataType); 691b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 692b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 693b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij /* if offset==0 then Data Type format is not supported by this 694b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij code or the Data Type is a string (with two empty strings as 695b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij values). In both cases Form Flag should be set to 0x00 and FORM is 696b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij not present. */ 697b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 698eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij dpd->FormFlag=PTP_DPFF_None; 699b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (offset==PTP_dpd_FactoryDefaultValue) 700b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 1; 701b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 702b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpd->FormFlag=dtoh8a(&data[offset]); 703b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij offset+=sizeof(uint8_t); 704eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 705eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij switch (dpd->FormFlag) { 706b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DPFF_Range: 707b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->FORM.Range.MinimumValue, dpd->DataType); 708b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 709b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->FORM.Range.MaximumValue, dpd->DataType); 710b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 711b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->FORM.Range.StepSize, dpd->DataType); 712b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 713eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij break; 714b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DPFF_Enumeration: { 715b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij int i; 716eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define N dpd->FORM.Enum.NumberOfValues 717b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij N = dtoh16a(&data[offset]); 718b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij offset+=sizeof(uint16_t); 719b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpd->FORM.Enum.SupportedValue = malloc(N*sizeof(dpd->FORM.Enum.SupportedValue[0])); 720b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!dpd->FORM.Enum.SupportedValue) 721b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij goto outofmemory; 722b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 723b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij memset (dpd->FORM.Enum.SupportedValue,0 , N*sizeof(dpd->FORM.Enum.SupportedValue[0])); 724b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<N;i++) { 725b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->FORM.Enum.SupportedValue[i], dpd->DataType); 726b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 727b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij /* Slightly different handling here. The HP PhotoSmart 120 728b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij * specifies an enumeration with N in wrong endian 729b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij * 00 01 instead of 01 00, so we count the enum just until the 730b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij * the end of the packet. 731b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij */ 732b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) { 733b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!i) 734b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij goto outofmemory; 735b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpd->FORM.Enum.NumberOfValues = i; 736b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 737eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 738b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 739eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 740eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 741b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#undef N 742b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 1; 743b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijoutofmemory: 744b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ptp_free_devicepropdesc(dpd); 745b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 0; 746eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 747eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 748b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij/* (MTP) Object Property pack/unpack */ 749b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_opd_ObjectPropertyCode 0 750b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_opd_DataType 2 751b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_opd_GetSet 4 752b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_opd_FactoryDefaultValue 5 753eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 754b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline int 755b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_OPD (PTPParams *params, unsigned char* data, PTPObjectPropDesc *opd, unsigned int opdlen) 756eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 757b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij int offset=0, ret; 758b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 759b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij memset (opd, 0, sizeof(*opd)); 760b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij opd->ObjectPropertyCode=dtoh16a(&data[PTP_opd_ObjectPropertyCode]); 761b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij opd->DataType=dtoh16a(&data[PTP_opd_DataType]); 762b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij opd->GetSet=dtoh8a(&data[PTP_opd_GetSet]); 763b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 764b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij offset = PTP_opd_FactoryDefaultValue; 765b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, opdlen, &opd->FactoryDefaultValue, opd->DataType); 766b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 767b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 768b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij opd->GroupCode=dtoh32a(&data[offset]); 769b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij offset+=sizeof(uint32_t); 770b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 771b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij opd->FormFlag=dtoh8a(&data[offset]); 772b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij offset+=sizeof(uint8_t); 773b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 774b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij switch (opd->FormFlag) { 775b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_OPFF_Range: 776b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, opdlen, &opd->FORM.Range.MinimumValue, opd->DataType); 777b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 778b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, opdlen, &opd->FORM.Range.MaximumValue, opd->DataType); 779b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 780b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, opdlen, &opd->FORM.Range.StepSize, opd->DataType); 781b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 782b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 783b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_OPFF_Enumeration: { 784b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij int i; 785b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define N opd->FORM.Enum.NumberOfValues 786b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij N = dtoh16a(&data[offset]); 787b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij offset+=sizeof(uint16_t); 788b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij opd->FORM.Enum.SupportedValue = malloc(N*sizeof(opd->FORM.Enum.SupportedValue[0])); 789b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!opd->FORM.Enum.SupportedValue) 790b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij goto outofmemory; 791b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 792b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij memset (opd->FORM.Enum.SupportedValue,0 , N*sizeof(opd->FORM.Enum.SupportedValue[0])); 793b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<N;i++) { 794b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, opdlen, &opd->FORM.Enum.SupportedValue[i], opd->DataType); 795b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 796b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij /* Slightly different handling here. The HP PhotoSmart 120 797b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij * specifies an enumeration with N in wrong endian 798b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij * 00 01 instead of 01 00, so we count the enum just until the 799b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij * the end of the packet. 800b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij */ 801b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) { 802b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!i) 803b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij goto outofmemory; 804b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij opd->FORM.Enum.NumberOfValues = i; 805b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 806b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 807b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 808b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#undef N 809b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 810eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 811b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 1; 812b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijoutofmemory: 813b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ptp_free_objectpropdesc(opd); 814b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 0; 815eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 816eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 817eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 818b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint32_t 819b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_pack_DPV (PTPParams *params, PTPPropertyValue* value, unsigned char** dpvptr, uint16_t datatype) 820eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 821b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij unsigned char* dpv=NULL; 822eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint32_t size=0; 823b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij int i; 824eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 825eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij switch (datatype) { 826b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_INT8: 827b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(int8_t); 828b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 829b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod8a(dpv,value->i8); 830b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 831b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_UINT8: 832b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint8_t); 833b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 834b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod8a(dpv,value->u8); 835b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 836b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_INT16: 837b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(int16_t); 838b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 839b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(dpv,value->i16); 840b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 841b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_UINT16: 842b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint16_t); 843b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 844b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(dpv,value->u16); 845b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 846b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_INT32: 847b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(int32_t); 848b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 849b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(dpv,value->i32); 850b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 851b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_UINT32: 852b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint32_t); 853b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 854b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(dpv,value->u32); 855b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 856abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij case PTP_DTC_INT64: 857abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij size=sizeof(int64_t); 858abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij dpv=malloc(size); 859abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij htod64a(dpv,value->i64); 860abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij break; 861abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij case PTP_DTC_UINT64: 862abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij size=sizeof(uint64_t); 863abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij dpv=malloc(size); 864abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij htod64a(dpv,value->u64); 865abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij break; 866b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AUINT8: 867b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint32_t)+value->a.count*sizeof(uint8_t); 868b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 869b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(dpv,value->a.count); 870b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<value->a.count;i++) 871cc2659036a503fce161cb77d9b0af17a52d7437bRichard Low htod8a(&dpv[sizeof(uint32_t)+i*sizeof(uint8_t)],value->a.v[i].u8); 872b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 873b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AINT8: 874b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint32_t)+value->a.count*sizeof(int8_t); 875b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 876b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(dpv,value->a.count); 877b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<value->a.count;i++) 878cc2659036a503fce161cb77d9b0af17a52d7437bRichard Low htod8a(&dpv[sizeof(uint32_t)+i*sizeof(int8_t)],value->a.v[i].i8); 879b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 880b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AUINT16: 881b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint32_t)+value->a.count*sizeof(uint16_t); 882b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 883b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(dpv,value->a.count); 884b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<value->a.count;i++) 885cc2659036a503fce161cb77d9b0af17a52d7437bRichard Low htod16a(&dpv[sizeof(uint32_t)+i*sizeof(uint16_t)],value->a.v[i].u16); 886b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 887b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AINT16: 888b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint32_t)+value->a.count*sizeof(int16_t); 889b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 890b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(dpv,value->a.count); 891b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<value->a.count;i++) 892cc2659036a503fce161cb77d9b0af17a52d7437bRichard Low htod16a(&dpv[sizeof(uint32_t)+i*sizeof(int16_t)],value->a.v[i].i16); 893b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 894b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AUINT32: 895b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint32_t)+value->a.count*sizeof(uint32_t); 896b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 897b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(dpv,value->a.count); 898b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<value->a.count;i++) 899cc2659036a503fce161cb77d9b0af17a52d7437bRichard Low htod32a(&dpv[sizeof(uint32_t)+i*sizeof(uint32_t)],value->a.v[i].u32); 900b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 901b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AINT32: 902b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint32_t)+value->a.count*sizeof(int32_t); 903b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 904b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(dpv,value->a.count); 905b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<value->a.count;i++) 906cc2659036a503fce161cb77d9b0af17a52d7437bRichard Low htod32a(&dpv[sizeof(uint32_t)+i*sizeof(int32_t)],value->a.v[i].i32); 907b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 908abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij case PTP_DTC_AUINT64: 909abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij size=sizeof(uint32_t)+value->a.count*sizeof(uint64_t); 910abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij dpv=malloc(size); 911abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij htod32a(dpv,value->a.count); 912abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij for (i=0;i<value->a.count;i++) 913cc2659036a503fce161cb77d9b0af17a52d7437bRichard Low htod64a(&dpv[sizeof(uint32_t)+i*sizeof(uint64_t)],value->a.v[i].u64); 914abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij break; 915abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij case PTP_DTC_AINT64: 916abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij size=sizeof(uint32_t)+value->a.count*sizeof(int64_t); 917abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij dpv=malloc(size); 918abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij htod32a(dpv,value->a.count); 919abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij for (i=0;i<value->a.count;i++) 920cc2659036a503fce161cb77d9b0af17a52d7437bRichard Low htod64a(&dpv[sizeof(uint32_t)+i*sizeof(int64_t)],value->a.v[i].i64); 921abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij break; 922b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij /* XXX: other int types are unimplemented */ 923b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_STR: { 924735f41692934a716158cf051d76e988febeca7eeLinus Walleij dpv=ptp_get_packed_stringcopy(params, value->str, &size); 925eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij break; 926b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 927eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 928eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij *dpvptr=dpv; 929eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return size; 93099310d4445697da39f22dff35457c75e35e97171Linus Walleij} 93199310d4445697da39f22dff35457c75e35e97171Linus Walleij 93299310d4445697da39f22dff35457c75e35e97171Linus Walleij#define MAX_MTP_PROPS 127 93399310d4445697da39f22dff35457c75e35e97171Linus Walleijstatic inline uint32_t 9346c0a6ce803cf79802b1c48339adf0964db30ec83Richard Lowptp_pack_OPL (PTPParams *params, MTPPropList *proplist, unsigned char** opldataptr) 93599310d4445697da39f22dff35457c75e35e97171Linus Walleij{ 93699310d4445697da39f22dff35457c75e35e97171Linus Walleij unsigned char* opldata; 93799310d4445697da39f22dff35457c75e35e97171Linus Walleij MTPPropList *propitr; 93899310d4445697da39f22dff35457c75e35e97171Linus Walleij unsigned char *packedprops[MAX_MTP_PROPS]; 93999310d4445697da39f22dff35457c75e35e97171Linus Walleij uint32_t packedpropslens[MAX_MTP_PROPS]; 94039b9374f23451201dece736db13f0f648584dc32Linus Walleij uint32_t packedobjecthandles[MAX_MTP_PROPS]; 94199310d4445697da39f22dff35457c75e35e97171Linus Walleij uint16_t packedpropsids[MAX_MTP_PROPS]; 94299310d4445697da39f22dff35457c75e35e97171Linus Walleij uint16_t packedpropstypes[MAX_MTP_PROPS]; 94399310d4445697da39f22dff35457c75e35e97171Linus Walleij uint32_t totalsize = 0; 94499310d4445697da39f22dff35457c75e35e97171Linus Walleij uint32_t bufp = 0; 94599310d4445697da39f22dff35457c75e35e97171Linus Walleij uint32_t noitems = 0; 94699310d4445697da39f22dff35457c75e35e97171Linus Walleij uint32_t i; 94799310d4445697da39f22dff35457c75e35e97171Linus Walleij 94899310d4445697da39f22dff35457c75e35e97171Linus Walleij totalsize = sizeof(uint32_t); /* 4 bytes to store the number of elements */ 94999310d4445697da39f22dff35457c75e35e97171Linus Walleij propitr = proplist; 95099310d4445697da39f22dff35457c75e35e97171Linus Walleij while (propitr != NULL && noitems < MAX_MTP_PROPS) { 9516c0a6ce803cf79802b1c48339adf0964db30ec83Richard Low /* Object Handle */ 95239b9374f23451201dece736db13f0f648584dc32Linus Walleij packedobjecthandles[noitems]=propitr->ObjectHandle; 95399310d4445697da39f22dff35457c75e35e97171Linus Walleij totalsize += sizeof(uint32_t); /* Object ID */ 95499310d4445697da39f22dff35457c75e35e97171Linus Walleij /* Metadata type */ 95599310d4445697da39f22dff35457c75e35e97171Linus Walleij packedpropsids[noitems]=propitr->property; 95699310d4445697da39f22dff35457c75e35e97171Linus Walleij totalsize += sizeof(uint16_t); 95799310d4445697da39f22dff35457c75e35e97171Linus Walleij /* Data type */ 95899310d4445697da39f22dff35457c75e35e97171Linus Walleij packedpropstypes[noitems]= propitr->datatype; 95999310d4445697da39f22dff35457c75e35e97171Linus Walleij totalsize += sizeof(uint16_t); 96099310d4445697da39f22dff35457c75e35e97171Linus Walleij /* Add each property to be sent. */ 96199310d4445697da39f22dff35457c75e35e97171Linus Walleij packedpropslens[noitems] = ptp_pack_DPV (params, &propitr->propval, &packedprops[noitems], propitr->datatype); 96299310d4445697da39f22dff35457c75e35e97171Linus Walleij totalsize += packedpropslens[noitems]; 96399310d4445697da39f22dff35457c75e35e97171Linus Walleij noitems ++; 96499310d4445697da39f22dff35457c75e35e97171Linus Walleij propitr = propitr->next; 96599310d4445697da39f22dff35457c75e35e97171Linus Walleij } 96699310d4445697da39f22dff35457c75e35e97171Linus Walleij 96799310d4445697da39f22dff35457c75e35e97171Linus Walleij /* Allocate memory for the packed property list */ 96899310d4445697da39f22dff35457c75e35e97171Linus Walleij opldata = malloc(totalsize); 96999310d4445697da39f22dff35457c75e35e97171Linus Walleij 97099310d4445697da39f22dff35457c75e35e97171Linus Walleij htod32a(&opldata[bufp],noitems); 97199310d4445697da39f22dff35457c75e35e97171Linus Walleij bufp += 4; 97299310d4445697da39f22dff35457c75e35e97171Linus Walleij 97399310d4445697da39f22dff35457c75e35e97171Linus Walleij /* Copy into a nice packed list */ 97499310d4445697da39f22dff35457c75e35e97171Linus Walleij for (i = 0; i < noitems; i++) { 97599310d4445697da39f22dff35457c75e35e97171Linus Walleij /* Object ID */ 9766c0a6ce803cf79802b1c48339adf0964db30ec83Richard Low htod32a(&opldata[bufp],packedobjecthandles[i]); 97799310d4445697da39f22dff35457c75e35e97171Linus Walleij bufp += sizeof(uint32_t); 97899310d4445697da39f22dff35457c75e35e97171Linus Walleij htod16a(&opldata[bufp],packedpropsids[i]); 97999310d4445697da39f22dff35457c75e35e97171Linus Walleij bufp += sizeof(uint16_t); 98099310d4445697da39f22dff35457c75e35e97171Linus Walleij htod16a(&opldata[bufp],packedpropstypes[i]); 98199310d4445697da39f22dff35457c75e35e97171Linus Walleij bufp += sizeof(uint16_t); 98299310d4445697da39f22dff35457c75e35e97171Linus Walleij /* The copy the actual property */ 98399310d4445697da39f22dff35457c75e35e97171Linus Walleij memcpy(&opldata[bufp], packedprops[i], packedpropslens[i]); 98499310d4445697da39f22dff35457c75e35e97171Linus Walleij bufp += packedpropslens[i]; 98599310d4445697da39f22dff35457c75e35e97171Linus Walleij free(packedprops[i]); 98699310d4445697da39f22dff35457c75e35e97171Linus Walleij } 98799310d4445697da39f22dff35457c75e35e97171Linus Walleij *opldataptr = opldata; 98899310d4445697da39f22dff35457c75e35e97171Linus Walleij return totalsize; 989eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 990eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 9918d82d2f4b0794e41ec26289045867eebb3496b8cRichard Lowstatic inline int 9928d82d2f4b0794e41ec26289045867eebb3496b8cRichard Lowptp_unpack_OPL (PTPParams *params, unsigned char* data, MTPPropList **proplist, unsigned int len) 9938d82d2f4b0794e41ec26289045867eebb3496b8cRichard Low{ 994277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij uint32_t prop_count = dtoh32a(data); 995277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij MTPPropList *prop = NULL; 996277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij int offset = 0, i; 997277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij 998277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij if (prop_count == 0) { 999277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij *proplist = NULL; 1000277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij return 0; 1001277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij } 1002277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij data += sizeof(uint32_t); 1003277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij *proplist = malloc(sizeof(MTPPropList)); 1004277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij prop = *proplist; 1005277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij for (i = 0; i < prop_count; i++) { 10066c0a6ce803cf79802b1c48339adf0964db30ec83Richard Low prop->ObjectHandle = dtoh32a(data); 1007277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij data += sizeof(uint32_t); 1008277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij len -= sizeof(uint32_t); 1009277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij 10106c0a6ce803cf79802b1c48339adf0964db30ec83Richard Low prop->property = dtoh16a(data); 1011277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij data += sizeof(uint16_t); 1012277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij len -= sizeof(uint16_t); 1013277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij 10146c0a6ce803cf79802b1c48339adf0964db30ec83Richard Low prop->datatype = dtoh16a(data); 1015277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij data += sizeof(uint16_t); 1016277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij len -= sizeof(uint16_t); 1017277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij 1018277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij offset = 0; 1019277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij ptp_unpack_DPV(params, data, &offset, len, &prop->propval, prop->datatype); 1020277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij data += offset; 1021277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij len -= offset; 1022277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij 1023277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij if (i != prop_count - 1) { 1024277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij prop->next = malloc(sizeof(MTPPropList)); 1025277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij prop = prop->next; 1026277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij } else 1027277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij prop->next = NULL; 1028277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij } 1029277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij return prop_count; 10308d82d2f4b0794e41ec26289045867eebb3496b8cRichard Low} 10318d82d2f4b0794e41ec26289045867eebb3496b8cRichard Low 1032eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* 1033eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP USB Event container unpack 1034eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij Copyright (c) 2003 Nikolai Kopanygin 1035eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij*/ 1036eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 1037eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_ec_Length 0 1038eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_ec_Type 4 1039eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_ec_Code 6 1040eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_ec_TransId 8 1041eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_ec_Param1 12 1042eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_ec_Param2 16 1043eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_ec_Param3 20 1044eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 1045b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 1046b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_EC (PTPParams *params, unsigned char* data, PTPUSBEventContainer *ec, unsigned int len) 1047eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 1048eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij if (data==NULL) 1049eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return; 1050eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij ec->length=dtoh32a(&data[PTP_ec_Length]); 1051eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij ec->type=dtoh16a(&data[PTP_ec_Type]); 1052eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij ec->code=dtoh16a(&data[PTP_ec_Code]); 1053eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij ec->trans_id=dtoh32a(&data[PTP_ec_TransId]); 1054b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 1055eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij if (ec->length>=(PTP_ec_Param1+4)) 1056eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij ec->param1=dtoh32a(&data[PTP_ec_Param1]); 1057eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij else 1058eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij ec->param1=0; 1059eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij if (ec->length>=(PTP_ec_Param2+4)) 1060eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij ec->param2=dtoh32a(&data[PTP_ec_Param2]); 1061eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij else 1062eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij ec->param2=0; 1063eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij if (ec->length>=(PTP_ec_Param3+4)) 1064eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij ec->param3=dtoh32a(&data[PTP_ec_Param3]); 1065eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij else 1066eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij ec->param3=0; 1067eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 1068eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 1069eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* 1070eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP Canon Folder Entry unpack 1071eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij Copyright (c) 2003 Nikolai Kopanygin 1072eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij*/ 1073eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_cfe_ObjectHandle 0 1074eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_cfe_ObjectFormatCode 4 1075eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_cfe_Flags 6 1076eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_cfe_ObjectSize 7 1077eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_cfe_Time 11 1078eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_cfe_Filename 15 1079eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 1080b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 1081b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_Canon_FE (PTPParams *params, unsigned char* data, PTPCANONFolderEntry *fe) 1082eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 1083eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij int i; 1084eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij if (data==NULL) 1085eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return; 1086eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij fe->ObjectHandle=dtoh32a(&data[PTP_cfe_ObjectHandle]); 1087eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij fe->ObjectFormatCode=dtoh16a(&data[PTP_cfe_ObjectFormatCode]); 1088eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij fe->Flags=dtoh8a(&data[PTP_cfe_Flags]); 1089b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij fe->ObjectSize=dtoh32a((unsigned char*)&data[PTP_cfe_ObjectSize]); 1090eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij fe->Time=(time_t)dtoh32a(&data[PTP_cfe_Time]); 1091eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij for (i=0; i<PTP_CANON_FilenameBufferLen; i++) 1092b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij fe->Filename[i]=(char)dtoh8a(&data[PTP_cfe_Filename+i]); 1093b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij} 1094b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 1095b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij/* 1096f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij PTP EOS Changes Entry unpack 1097f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij*/ 1098f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij#define PTP_ece_Size 0 1099f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij#define PTP_ece_Type 4 1100f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij 1101f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij#define PTP_ece_Prop_Subtype 8 /* only for properties */ 1102f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij#define PTP_ece_Prop_Val_Data 0xc /* only for properties */ 1103f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij#define PTP_ece_Prop_Desc_Type 0xc /* only for property descs */ 1104f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij#define PTP_ece_Prop_Desc_Count 0x10 /* only for property descs */ 1105f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij#define PTP_ece_Prop_Desc_Data 0x14 /* only for property descs */ 1106f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij 1107f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij#define PTP_ece_OI_ObjectID 8 /* only for objectinfos */ 1108f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij#define PTP_ece_OI_OFC 0x0c /* only for objectinfos */ 1109f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij#define PTP_ece_OI_Size 0x14 /* only for objectinfos */ 1110f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij#define PTP_ece_OI_Name 0x1c /* only for objectinfos */ 1111f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij 1112f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleijstatic inline int 1113f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleijptp_unpack_CANON_changes (PTPParams *params, unsigned char* data, int datasize, PTPCanon_changes_entry **ce) 1114f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij{ 1115f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij int i = 0, entries = 0; 1116f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij unsigned char *curdata = data; 1117f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij 1118f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if (data==NULL) 1119f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij return 0; 1120f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij while (curdata - data < datasize) { 1121f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij uint32_t size = dtoh32a(&curdata[PTP_ece_Size]); 1122f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij uint32_t type = dtoh32a(&curdata[PTP_ece_Type]); 1123f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij 1124f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij curdata += size; 1125f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if ((size == 8) && (type == 0)) 1126f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1127f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij entries++; 1128f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 1129f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij *ce = malloc (sizeof(PTPCanon_changes_entry)*entries); 1130f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if (!*ce) return 0; 1131f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij 1132f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij curdata = data; 1133f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij while (curdata - data < datasize) { 1134f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij uint32_t size = dtoh32a(&curdata[PTP_ece_Size]); 1135f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij uint32_t type = dtoh32a(&curdata[PTP_ece_Type]); 1136f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij 1137f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij switch (type) { 1138f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case 0xc186: { /* objectinfo from capture */ 1139f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij (*ce)[i].type = PTP_CANON_EOS_CHANGES_TYPE_OBJECTINFO; 1140f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij (*ce)[i].u.object.oid = dtoh32a(&curdata[PTP_ece_OI_ObjectID]); 1141f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij (*ce)[i].u.object.oi.ObjectFormat = dtoh16a(&curdata[PTP_ece_OI_OFC]); 1142f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij (*ce)[i].u.object.oi.ObjectCompressedSize = dtoh32a(&curdata[PTP_ece_OI_Size]); 1143f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij (*ce)[i].u.object.oi.Filename = strdup(((char*)&curdata[PTP_ece_OI_Name])); 1144f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1145f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 1146f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case 0xc18a: { /* property desc */ 1147f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij uint32_t proptype = dtoh32a(&curdata[PTP_ece_Prop_Subtype]); 1148f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij uint32_t propxtype = dtoh32a(&curdata[PTP_ece_Prop_Desc_Type]); 1149f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij uint32_t propxcnt = dtoh32a(&curdata[PTP_ece_Prop_Desc_Count]); 1150f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij unsigned char *data = &curdata[PTP_ece_Prop_Desc_Data]; 1151f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij int j; 1152f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij PTPDevicePropDesc *dpd; 1153f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij 11545d533bb85ccfc1bafa8df94570e87f3daf3d5e85Linus Walleij /*fprintf (stderr, "Adding EOS property %04x desc record, datasize is %d\n", proptype, size-PTP_ece_Prop_Desc_Data);*/ 1155f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij for (j=0;j<params->nrofcanon_props;j++) 1156f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if (params->canon_props[j].proptype == proptype) 1157f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1158f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if (j==params->nrofcanon_props) { 11595d533bb85ccfc1bafa8df94570e87f3daf3d5e85Linus Walleij /*fprintf (stderr, "should have received default value for %x first!\n", proptype);*/ 1160f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1161f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 1162f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij dpd = ¶ms->canon_props[j].dpd; 1163f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if (propxtype != 3) { 11645d533bb85ccfc1bafa8df94570e87f3daf3d5e85Linus Walleij /*fprintf (stderr, "propxtype is %x for %x, unhandled.\n", propxtype, proptype);*/ 1165f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1166f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 1167f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if (propxcnt) { 1168f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij dpd->FormFlag = PTP_DPFF_Enumeration; 1169f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij dpd->FORM.Enum.NumberOfValues = propxcnt; 1170f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij dpd->FORM.Enum.SupportedValue = malloc (sizeof (PTPPropertyValue)*propxcnt); 1171f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij for (j=0;j<propxcnt;j++) { 1172f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij switch (dpd->DataType) { 1173f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case PTP_DTC_UINT16: 1174f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij dpd->FORM.Enum.SupportedValue[j].u16 = dtoh16a(data); 11755d533bb85ccfc1bafa8df94570e87f3daf3d5e85Linus Walleij /*fprintf (stderr,"suppvalue[%d] of %x is %x\n", j, proptype, dtoh16a(data));*/ 1176f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1177f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case PTP_DTC_UINT8: 1178f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij dpd->FORM.Enum.SupportedValue[j].u8 = dtoh8a(data); 11795d533bb85ccfc1bafa8df94570e87f3daf3d5e85Linus Walleij /*fprintf (stderr,"suppvalue[%d] of %x is %x\n", j, proptype, dtoh8a(data));*/ 1180f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1181f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij default: 11825d533bb85ccfc1bafa8df94570e87f3daf3d5e85Linus Walleij /*fprintf(stderr,"data type 0x%04x of %x unhandled, fill in (val=%x).\n", dpd->DataType, proptype, dtoh32a(data));*/ 1183f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1184f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 1185f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij data += 4; /* might only be for propxtype 3 */ 1186f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 1187f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 1188f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1189f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 1190f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case 0xc189: /* property value */ 1191f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if (size >= 0xc) { /* property info */ 1192f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij int j; 1193f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij uint32_t proptype = dtoh32a(&curdata[PTP_ece_Prop_Subtype]); 1194f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij unsigned char *data = &curdata[PTP_ece_Prop_Val_Data]; 1195f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij PTPDevicePropDesc *dpd; 1196f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij 1197f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij for (j=0;j<params->nrofcanon_props;j++) 1198f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if (params->canon_props[j].proptype == proptype) 1199f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1200f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if (j<params->nrofcanon_props) { 1201f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if ( (params->canon_props[j].size != size) || 1202f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij (memcmp(params->canon_props[j].data,data,size-PTP_ece_Prop_Val_Data))) { 1203f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij params->canon_props[j].data = realloc(params->canon_props[j].data,size-PTP_ece_Prop_Val_Data); 1204f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij memcpy (params->canon_props[j].data,data,size-PTP_ece_Prop_Val_Data); 1205f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 1206f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } else { 1207f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if (j) 1208f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij params->canon_props = realloc(params->canon_props, sizeof(params->canon_props[0])*(j+1)); 1209f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij else 1210f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij params->canon_props = malloc(sizeof(params->canon_props[0])); 1211f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij params->canon_props[j].type = type; 1212f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij params->canon_props[j].proptype = proptype; 1213f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij params->canon_props[j].size = size; 1214f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij params->canon_props[j].data = malloc(size-PTP_ece_Prop_Val_Data); 1215f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij memcpy(params->canon_props[j].data, data, size-PTP_ece_Prop_Val_Data); 1216f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij memset (¶ms->canon_props[j].dpd,0,sizeof(params->canon_props[j].dpd)); 1217f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij params->canon_props[j].dpd.GetSet = 1; 1218f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij params->canon_props[j].dpd.FormFlag = PTP_DPFF_None; 1219f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij params->nrofcanon_props = j+1; 1220f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 1221f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij dpd = ¶ms->canon_props[j].dpd; 1222f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij switch (proptype) { 1223ac052c1ac330b94932d2b4f774e0053e78e91216Linus Walleij case PTP_DPC_CANON_EOS_CameraTime: 1224ac052c1ac330b94932d2b4f774e0053e78e91216Linus Walleij dpd->DataType = PTP_DTC_UINT32; 1225ac052c1ac330b94932d2b4f774e0053e78e91216Linus Walleij break; 1226f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case PTP_DPC_CANON_EOS_Aperture: 1227f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case PTP_DPC_CANON_EOS_ShutterSpeed: 1228f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case PTP_DPC_CANON_EOS_ISOSpeed: 1229f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij dpd->DataType = PTP_DTC_UINT16; 1230f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1231f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case PTP_DPC_CANON_EOS_PictureStyle: 1232f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case PTP_DPC_CANON_EOS_WhiteBalance: 1233f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case PTP_DPC_CANON_EOS_MeteringMode: 1234f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case PTP_DPC_CANON_EOS_ExpCompensation: 1235f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij dpd->DataType = PTP_DTC_UINT8; 1236f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1237f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case PTP_DPC_CANON_EOS_Owner: 1238f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij dpd->DataType = PTP_DTC_STR; 1239f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1240f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij default: 12415d533bb85ccfc1bafa8df94570e87f3daf3d5e85Linus Walleij /*fprintf (stderr, "Unknown EOS property %04x, datasize is %d\n", proptype, size-PTP_ece_Prop_Val_Data);*/ 1242f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1243f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 1244f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij switch (dpd->DataType) { 1245ac052c1ac330b94932d2b4f774e0053e78e91216Linus Walleij case PTP_DTC_UINT32: 1246ac052c1ac330b94932d2b4f774e0053e78e91216Linus Walleij dpd->FactoryDefaultValue.u32 = dtoh32a(data); 1247ac052c1ac330b94932d2b4f774e0053e78e91216Linus Walleij dpd->CurrentValue.u32 = dtoh32a(data); 1248ac052c1ac330b94932d2b4f774e0053e78e91216Linus Walleij /*fprintf (stderr,"currentvalue of %x is %x\n", proptype, dpd->CurrentValue.u16);*/ 1249ac052c1ac330b94932d2b4f774e0053e78e91216Linus Walleij break; 1250f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case PTP_DTC_UINT16: 1251f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij dpd->FactoryDefaultValue.u16 = dtoh16a(data); 1252f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij dpd->CurrentValue.u16 = dtoh16a(data); 1253f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij /*fprintf (stderr,"currentvalue of %x is %x\n", proptype, dpd->CurrentValue.u16);*/ 1254f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1255f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case PTP_DTC_UINT8: 1256f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij dpd->FactoryDefaultValue.u8 = dtoh8a(data); 1257f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij dpd->CurrentValue.u8 = dtoh8a(data); 1258f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij /*fprintf (stderr,"currentvalue of %x is %x\n", proptype, dpd->CurrentValue.u8);*/ 1259f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1260f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case PTP_DTC_STR: { 1261f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij uint8_t len = 0; 1262f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij dpd->FactoryDefaultValue.str = ptp_unpack_string(params, data, 0, &len); 1263f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij dpd->CurrentValue.str = ptp_unpack_string(params, data, 0, &len); 1264f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1265f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 1266f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij default: 1267f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij /* debug is printed in switch above this one */ 1268f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1269f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 1270f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1271f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 1272f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij default: 12735d533bb85ccfc1bafa8df94570e87f3daf3d5e85Linus Walleij /* fprintf (stderr, "unknown EOS property type %04x\n", type); */ 1274f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij (*ce)[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN; 1275f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1276f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 1277f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij curdata += size; 1278f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij i++; 1279f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 1280f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij 1281f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij return entries; 1282f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij} 1283f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij 1284f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij/* 1285b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij PTP USB Event container unpack for Nikon events. 1286b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij*/ 1287b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_nikon_ec_Length 0 1288b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_nikon_ec_Code 2 1289b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_nikon_ec_Param1 4 1290b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_nikon_ec_Size 6 1291b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 1292b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_Nikon_EC (PTPParams *params, unsigned char* data, unsigned int len, PTPUSBEventContainer **ec, int *cnt) 1293b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij{ 1294b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij int i; 1295b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 1296b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij *ec = NULL; 1297b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (data == NULL) 1298b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return; 1299b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (len < PTP_nikon_ec_Code) 1300b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return; 1301b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij *cnt = dtoh16a(&data[PTP_nikon_ec_Length]); 1302b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (*cnt > (len-PTP_nikon_ec_Code)/PTP_nikon_ec_Size) /* broken cnt? */ 1303b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return; 1304b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij *ec = malloc(sizeof(PTPUSBEventContainer)*(*cnt)); 1305b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 1306b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<*cnt;i++) { 1307b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij memset(&(*ec)[i],0,sizeof(PTPUSBEventContainer)); 1308b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij (*ec)[i].code = dtoh16a(&data[PTP_nikon_ec_Code+PTP_nikon_ec_Size*i]); 1309b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij (*ec)[i].param1 = dtoh32a(&data[PTP_nikon_ec_Param1+PTP_nikon_ec_Size*i]); 1310b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 1311eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 1312eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 1313eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 1314b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint32_t 1315b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_pack_EK_text(PTPParams *params, PTPEKTextParams *text, unsigned char **data) { 1316b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij int i, len = 0; 1317b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij uint8_t retlen; 1318b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij unsigned char *curdata; 1319b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 1320b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij len = 2*(strlen(text->title)+1)+1+ 1321b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 2*(strlen(text->line[0])+1)+1+ 1322b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 2*(strlen(text->line[1])+1)+1+ 1323b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 2*(strlen(text->line[2])+1)+1+ 1324b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 2*(strlen(text->line[3])+1)+1+ 1325b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 2*(strlen(text->line[4])+1)+1+ 1326b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 4*2+2*4+2+4+2+5*4*2; 1327b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij *data = malloc(len); 1328b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!*data) return 0; 1329b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 1330b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij curdata = *data; 1331b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,100);curdata+=2; 1332b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,1);curdata+=2; 1333b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,0);curdata+=2; 1334b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,1000);curdata+=2; 1335b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 1336b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(curdata,0);curdata+=4; 1337b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(curdata,0);curdata+=4; 1338b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 1339b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,6);curdata+=2; 1340b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(curdata,0);curdata+=4; 1341b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 1342b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ptp_pack_string(params, text->title, curdata, 0, &retlen); curdata+=2*retlen+1;htod16a(curdata,0);curdata+=2; 1343b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,0x10);curdata+=2; 1344b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 1345b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<5;i++) { 1346b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ptp_pack_string(params, text->line[i], curdata, 0, &retlen); curdata+=2*retlen+1;htod16a(curdata,0);curdata+=2; 1347b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,0x10);curdata+=2; 1348b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,0x01);curdata+=2; 1349b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,0x02);curdata+=2; 1350b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,0x06);curdata+=2; 1351b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 1352b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return len; 1353b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij} 13547347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij 13557347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_version 0x00 13567347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_ofc 0x02 13577347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_unk1 0x04 13587347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_objectid 0x08 13597347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_parentid 0x0c 13607347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_previd 0x10 /* in same dir */ 13617347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_nextid 0x14 /* in same dir */ 13627347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_nextchild 0x18 /* down one dir */ 13637347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_storageid 0x1c /* only in storage entry */ 13647347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_name 0x20 13657347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_flags 0x2c 13667347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_size 0x30 13677347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_unixtime 0x34 13687347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_year 0x38 13697347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_month 0x39 13707347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_mday 0x3a 13717347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_hour 0x3b 13727347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_minute 0x3c 13737347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_second 0x3d 13747347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_unk2 0x3e 13757347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_thumbsize 0x40 13767347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_width 0x44 13777347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_height 0x48 13787347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij 13797347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleijstatic inline uint16_t 13807347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleijptp_unpack_canon_directory ( 13817347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij PTPParams *params, 13827347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij unsigned char *dir, 13837347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij uint32_t cnt, 13847347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij PTPObjectHandles *handles, 13857347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij PTPObjectInfo **oinfos, /* size(handles->n) */ 13867347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij uint32_t **flags /* size(handles->n) */ 13877347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij) { 13887347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij unsigned int i, j, nrofobs = 0, curob = 0; 13897347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij 13907347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ISOBJECT(ptr) (dtoh32a((ptr)+ptp_canon_dir_storageid) == 0xffffffff) 13917347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij for (i=0;i<cnt;i++) 13927347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (ISOBJECT(dir+i*0x4c)) nrofobs++; 13937347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij handles->n = nrofobs; 13947347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij handles->Handler = calloc(sizeof(handles->Handler[0]),nrofobs); 13957347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (!handles->Handler) return PTP_RC_GeneralError; 13967347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij *oinfos = calloc(sizeof((*oinfos)[0]),nrofobs); 13977347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (!*oinfos) return PTP_RC_GeneralError; 13987347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij *flags = calloc(sizeof((*flags)[0]),nrofobs); 13997347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (!*flags) return PTP_RC_GeneralError; 14007347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij 14017347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij /* Migrate data into objects ids, handles into 14027347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij * the object handler array. 14037347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij */ 14047347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij curob = 0; 14057347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij for (i=0;i<cnt;i++) { 14067347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij unsigned char *cur = dir+i*0x4c; 14077347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij PTPObjectInfo *oi = (*oinfos)+curob; 14087347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij 14097347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (!ISOBJECT(cur)) 14107347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij continue; 14117347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij 14127347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij handles->Handler[curob] = dtoh32a(cur + ptp_canon_dir_objectid); 14137347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij oi->StorageID = 0xffffffff; 14147347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij oi->ObjectFormat = dtoh16a(cur + ptp_canon_dir_ofc); 14157347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij oi->ParentObject = dtoh32a(cur + ptp_canon_dir_parentid); 14167347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij oi->Filename = strdup((char*)(cur + ptp_canon_dir_name)); 14177347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij oi->ObjectCompressedSize= dtoh32a(cur + ptp_canon_dir_size); 14187347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij oi->ThumbCompressedSize = dtoh32a(cur + ptp_canon_dir_thumbsize); 14197347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij oi->ImagePixWidth = dtoh32a(cur + ptp_canon_dir_width); 14207347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij oi->ImagePixHeight = dtoh32a(cur + ptp_canon_dir_height); 14217347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij oi->CaptureDate = oi->ModificationDate = dtoh32a(cur + ptp_canon_dir_unixtime); 14227347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij (*flags)[curob] = dtoh32a(cur + ptp_canon_dir_flags); 14237347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij curob++; 14247347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 14257347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij /* Walk over Storage ID entries and distribute the IDs to 14267347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij * the parent objects. */ 14277347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij for (i=0;i<cnt;i++) { 14287347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij unsigned char *cur = dir+i*0x4c; 14297347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij uint32_t nextchild = dtoh32a(cur + ptp_canon_dir_nextchild); 14307347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij 14317347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (ISOBJECT(cur)) 14327347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij continue; 14337347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij for (j=0;j<handles->n;j++) if (nextchild == handles->Handler[j]) break; 14347347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (j == handles->n) continue; 14357347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij (*oinfos)[j].StorageID = dtoh32a(cur + ptp_canon_dir_storageid); 14367347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 14377347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij /* Walk over all objects and distribute the storage ids */ 14387347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij while (1) { 14397347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij int changed = 0; 14407347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij for (i=0;i<cnt;i++) { 14417347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij unsigned char *cur = dir+i*0x4c; 14427347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij uint32_t oid = dtoh32a(cur + ptp_canon_dir_objectid); 14437347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij uint32_t nextoid = dtoh32a(cur + ptp_canon_dir_nextid); 14447347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij uint32_t nextchild = dtoh32a(cur + ptp_canon_dir_nextchild); 14457347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij uint32_t storageid; 14467347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij 14477347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (!ISOBJECT(cur)) 14487347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij continue; 14497347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij for (j=0;j<handles->n;j++) if (oid == handles->Handler[j]) break; 14507347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (j == handles->n) { 14517347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij /*fprintf(stderr,"did not find oid in lookup pass for current oid\n");*/ 14527347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij continue; 14537347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 14547347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij storageid = (*oinfos)[j].StorageID; 14557347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (storageid == 0xffffffff) continue; 14567347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (nextoid != 0xffffffff) { 14577347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij for (j=0;j<handles->n;j++) if (nextoid == handles->Handler[j]) break; 14587347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (j == handles->n) { 14597347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij /*fprintf(stderr,"did not find oid in lookup pass for next oid\n");*/ 14607347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij continue; 14617347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 14627347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if ((*oinfos)[j].StorageID == 0xffffffff) { 14637347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij (*oinfos)[j].StorageID = storageid; 14647347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij changed++; 14657347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 14667347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 14677347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (nextchild != 0xffffffff) { 14687347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij for (j=0;j<handles->n;j++) if (nextchild == handles->Handler[j]) break; 14697347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (j == handles->n) { 14707347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij /*fprintf(stderr,"did not find oid in lookup pass for next child\n");*/ 14717347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij continue; 14727347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 14737347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if ((*oinfos)[j].StorageID == 0xffffffff) { 14747347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij (*oinfos)[j].StorageID = storageid; 14757347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij changed++; 14767347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 14777347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 14787347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 14797347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij /* Check if we: 14807347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij * - changed no entry (nothing more to do) 14817347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij * - changed all of them at once (usually happens) 14827347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij * break if we do. 14837347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij */ 14847347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (!changed || (changed==nrofobs-1)) 14857347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij break; 14867347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 14877347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#undef ISOBJECT 14887347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij return PTP_RC_OK; 14897347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij} 14907347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij 1491