ptp-pack.c revision a679b1c4d273f210abb6befc5d9954a25427c329
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 35b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint16_t 36eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleijdtoh16p (PTPParams *params, uint16_t var) 37eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 38eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return ((params->byteorder==PTP_DL_LE)?le16toh(var):be16toh(var)); 39eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 40eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 41b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint32_t 42eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleijdtoh32p (PTPParams *params, uint32_t var) 43eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 44eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return ((params->byteorder==PTP_DL_LE)?le32toh(var):be32toh(var)); 45eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 46eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 47b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint16_t 48eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleijdtoh16ap (PTPParams *params, unsigned char *a) 49eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 50eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return ((params->byteorder==PTP_DL_LE)?le16atoh(a):be16atoh(a)); 51eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 52eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 53b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint32_t 54eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleijdtoh32ap (PTPParams *params, unsigned char *a) 55eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 56eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return ((params->byteorder==PTP_DL_LE)?le32atoh(a):be32atoh(a)); 57eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 58eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 59b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint64_t 60eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleijdtoh64ap (PTPParams *params, unsigned char *a) 61eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 62b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij uint64_t tmp = 0; 63b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij int i; 64b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 65b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (params->byteorder==PTP_DL_LE) { 66b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<8;i++) 67b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij tmp |= (((uint64_t)a[i]) << (8*i)); 68b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } else { 69b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<8;i++) 70b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij tmp |= (((uint64_t)a[i]) << (8*(7-i))); 71b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 72b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return tmp; 73eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 74eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 75b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define htod8a(a,x) *(uint8_t*)(a) = x 76b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define htod16a(a,x) htod16ap(params,a,x) 77b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define htod32a(a,x) htod32ap(params,a,x) 78b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define htod16(x) htod16p(params,x) 79b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define htod32(x) htod32p(params,x) 80b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 81b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define dtoh8a(x) (*(uint8_t*)(x)) 82b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define dtoh16a(a) dtoh16ap(params,a) 83b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define dtoh32a(a) dtoh32ap(params,a) 84b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define dtoh64a(a) dtoh64ap(params,a) 85b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define dtoh16(x) dtoh16p(params,x) 86b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define dtoh32(x) dtoh32p(params,x) 87b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 88b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 89b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline char* 90b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_string(PTPParams *params, unsigned char* data, uint16_t offset, uint8_t *len) 91eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 92eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij int i; 93a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij uint8_t loclen; 94a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij 95a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij /* Cannot exceed 255 (PTP_MAXSTRLEN) since it is a single byte, duh ... */ 96a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij loclen = dtoh8a(&data[offset]); 97a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij /* This len is used to advance the buffer pointer */ 98a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij *len = loclen; 99a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij if (loclen) { 100a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij uint16_t string[PTP_MAXSTRLEN+1]; 101a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij char *stringp = (char *) string; 102a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij char loclstr[PTP_MAXSTRLEN*3+1]; /* UTF-8 encoding is max 3 bytes per UCS2 char. */ 103a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij char *locp = loclstr; 104a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij size_t nconv; 105a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij size_t convlen = loclen * 2; /* UCS-2 is 16 bit wide */ 106a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij size_t convmax = PTP_MAXSTRLEN*3; 107a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij 108a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij for (i=0;i<loclen;i++) { 109a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij string[i]=dtoh16a(&data[offset+i*2+1]); 110eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 111a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij /* be paranoid! Add a terminator. :( */ 112a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij string[loclen]=0x0000U; 113a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij loclstr[0]='\0'; 114a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij /* loclstr=ucs2_to_utf8(string); */ 115a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij /* Do the conversion. */ 116a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij nconv = iconv (params->cd_ucs2_to_locale, &stringp, &convlen, &locp, &convmax); 117a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij /* FIXME: handle size errors */ 118a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij loclstr[PTP_MAXSTRLEN*3] = '\0'; 119a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij if (nconv == (size_t) -1) 120a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij return NULL; 121a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij return strdup(loclstr); 122eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 123a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij return NULL; 124a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij} 125a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij 126a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij 127a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleijstatic inline int 128a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleijucs2strlen(uint16_t const * const unicstr) 129a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij{ 130a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij int length; 131a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij 132a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij /* Unicode strings are terminated with 2 * 0x00 */ 133a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij for(length = 0; unicstr[length] != 0x0000U; length ++); 134a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij return length; 135eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 136eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 137a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij 138b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 139b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_pack_string(PTPParams *params, char *string, unsigned char* data, uint16_t offset, uint8_t *len) 140eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 141eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij int i; 142a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij int packedlen; 143a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij uint16_t ucs2str[PTP_MAXSTRLEN+1]; 144a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij char *ucs2strp = (char *) ucs2str; 145a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij char *stringp = string; 146a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij size_t nconv; 147a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij size_t convlen = strlen(string); 148a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij size_t convmax = PTP_MAXSTRLEN * 2; /* Includes the terminator */ 149a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij 150a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij /* Cannot exceed 255 (PTP_MAXSTRLEN) since it is a single byte, duh ... */ 151a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij ucs2str[0] = 0x0000U; 152a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij memset(ucs2strp, 0, PTP_MAXSTRLEN*2+2); 153a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij nconv = iconv (params->cd_locale_to_ucs2, &stringp, &convlen, &ucs2strp, &convmax); 1544f40d11374a0ea3c4038f3b18a3601b3bbfe6dcfLinus Walleij if (nconv == (size_t) -1) 155a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij ucs2str[0] = 0x0000U; 156a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij packedlen = ucs2strlen(ucs2str); 157a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij if (packedlen > PTP_MAXSTRLEN-1) { 158a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij *len=0; 159a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij return; 160a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij } 161958441f8ed3e704cf07c9f600730f90a80a0d424Linus Walleij 1627f2343824550452974d78f5dbd94e64844355c33Linus Walleij /* number of characters including terminating 0 (PTP standard confirmed) */ 163a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij htod8a(&data[offset],packedlen+1); 164a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij for (i=0;i<packedlen && i< PTP_MAXSTRLEN; i++) { 165a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij htod16a(&data[offset+i*2+1],ucs2str[i]); 166eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 1676e4499552671f75f23171957823ce4e0b067cac7Linus Walleij htod16a(&data[offset+i*2+1],0x0000); 168958441f8ed3e704cf07c9f600730f90a80a0d424Linus Walleij 169958441f8ed3e704cf07c9f600730f90a80a0d424Linus Walleij /* The returned length is in number of characters */ 170048d938dc4889b74b258a786d5f53142b059fc32Linus Walleij *len = (uint8_t) packedlen+1; 171eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 172eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 173a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleijstatic inline unsigned char * 174735f41692934a716158cf051d76e988febeca7eeLinus Walleijptp_get_packed_stringcopy(PTPParams *params, char *string, uint32_t *packed_size) 175a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij{ 1768b42ca3d3baeb7c8f3e5eca88c613adb612e4ec0Richard Low uint8_t packed[PTP_MAXSTRLEN*2+3], len; 177a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij size_t plen; 178a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij unsigned char *retcopy = NULL; 179a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij 180a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij ptp_pack_string(params, string, (unsigned char*) packed, 0, &len); 181958441f8ed3e704cf07c9f600730f90a80a0d424Linus Walleij /* returned length is in characters, then one byte for string length */ 182958441f8ed3e704cf07c9f600730f90a80a0d424Linus Walleij plen = len*2 + 1; 183048d938dc4889b74b258a786d5f53142b059fc32Linus Walleij 184a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij retcopy = malloc(plen); 185735f41692934a716158cf051d76e988febeca7eeLinus Walleij if (!retcopy) { 186735f41692934a716158cf051d76e988febeca7eeLinus Walleij *packed_size = 0; 187a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij return NULL; 188735f41692934a716158cf051d76e988febeca7eeLinus Walleij } 189a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij memcpy(retcopy, packed, plen); 190735f41692934a716158cf051d76e988febeca7eeLinus Walleij *packed_size = plen; 191a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij return (retcopy); 192a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij} 193a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij 194b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint32_t 195b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_uint32_t_array(PTPParams *params, unsigned char* data, uint16_t offset, uint32_t **array) 196eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 197eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint32_t n, i=0; 198eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 199eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij n=dtoh32a(&data[offset]); 200eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij *array = malloc (n*sizeof(uint32_t)); 201eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij while (n>i) { 202eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij (*array)[i]=dtoh32a(&data[offset+(sizeof(uint32_t)*(i+1))]); 203eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij i++; 204eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 205eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return n; 206eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 207eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 208b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint32_t 209f67bca9bde733f456ad341c0d852147124ab388aLinus Walleijptp_pack_uint32_t_array(PTPParams *params, uint32_t *array, uint32_t arraylen, unsigned char **data ) 210f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij{ 211f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij uint32_t i=0; 212f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij 213f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij *data = malloc ((arraylen+1)*sizeof(uint32_t)); 214f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij htod32a(&(*data)[0],arraylen); 215f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij for (i=0;i<arraylen;i++) 216f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij htod32a(&(*data)[sizeof(uint32_t)*(i+1)], array[i]); 217f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij return (arraylen+1)*sizeof(uint32_t); 218f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij} 219f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij 220f67bca9bde733f456ad341c0d852147124ab388aLinus Walleijstatic inline uint32_t 221b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_uint16_t_array(PTPParams *params, unsigned char* data, uint16_t offset, uint16_t **array) 222eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 223eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint32_t n, i=0; 224eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 225eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij n=dtoh32a(&data[offset]); 226eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij *array = malloc (n*sizeof(uint16_t)); 227eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij while (n>i) { 228eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij (*array)[i]=dtoh16a(&data[offset+(sizeof(uint16_t)*(i+2))]); 229eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij i++; 230eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 231eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return n; 232eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 233eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 234eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* DeviceInfo pack/unpack */ 235eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 236eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_di_StandardVersion 0 237eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_di_VendorExtensionID 2 238eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_di_VendorExtensionVersion 6 239eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_di_VendorExtensionDesc 8 240eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_di_FunctionalMode 8 241eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_di_OperationsSupported 10 242eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 243b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 244b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_DI (PTPParams *params, unsigned char* data, PTPDeviceInfo *di, unsigned int datalen) 245eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 246eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint8_t len; 247eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij unsigned int totallen; 248eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 2497347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij di->StandardVersion = dtoh16a(&data[PTP_di_StandardVersion]); 250eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->VendorExtensionID = 251eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij dtoh32a(&data[PTP_di_VendorExtensionID]); 252eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->VendorExtensionVersion = 253eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij dtoh16a(&data[PTP_di_VendorExtensionVersion]); 254eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->VendorExtensionDesc = 255eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij ptp_unpack_string(params, data, 256eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_VendorExtensionDesc, &len); 257eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen=len*2+1; 258eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->FunctionalMode = 259eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij dtoh16a(&data[PTP_di_FunctionalMode+totallen]); 260eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->OperationsSupported_len = ptp_unpack_uint16_t_array(params, data, 261eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 262eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &di->OperationsSupported); 263eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen=totallen+di->OperationsSupported_len*sizeof(uint16_t)+sizeof(uint32_t); 264eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->EventsSupported_len = ptp_unpack_uint16_t_array(params, data, 265eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 266eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &di->EventsSupported); 267eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen=totallen+di->EventsSupported_len*sizeof(uint16_t)+sizeof(uint32_t); 268eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->DevicePropertiesSupported_len = 269eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij ptp_unpack_uint16_t_array(params, data, 270eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 271eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &di->DevicePropertiesSupported); 272eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen=totallen+di->DevicePropertiesSupported_len*sizeof(uint16_t)+sizeof(uint32_t); 273eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->CaptureFormats_len = ptp_unpack_uint16_t_array(params, data, 274eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 275eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &di->CaptureFormats); 276eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen=totallen+di->CaptureFormats_len*sizeof(uint16_t)+sizeof(uint32_t); 277eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->ImageFormats_len = ptp_unpack_uint16_t_array(params, data, 278eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 279eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &di->ImageFormats); 280eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen=totallen+di->ImageFormats_len*sizeof(uint16_t)+sizeof(uint32_t); 281eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->Manufacturer = ptp_unpack_string(params, data, 282eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 283eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &len); 284eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen+=len*2+1; 285eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->Model = ptp_unpack_string(params, data, 286eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 287eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &len); 288eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen+=len*2+1; 289eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->DeviceVersion = ptp_unpack_string(params, data, 290eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 291eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &len); 292eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen+=len*2+1; 293eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->SerialNumber = ptp_unpack_string(params, data, 294eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 295eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &len); 296eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 297eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 298eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* ObjectHandles array pack/unpack */ 299eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 300eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oh 0 301eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 302b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 303b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_OH (PTPParams *params, unsigned char* data, PTPObjectHandles *oh, unsigned int len) 304eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 305eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oh->n = ptp_unpack_uint32_t_array(params, data, PTP_oh, &oh->Handler); 306eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 307eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 308eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* StoreIDs array pack/unpack */ 309eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 310eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_sids 0 311eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 312b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 313b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_SIDs (PTPParams *params, unsigned char* data, PTPStorageIDs *sids, unsigned int len) 314eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 315eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij sids->n = ptp_unpack_uint32_t_array(params, data, PTP_sids, 316eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &sids->Storage); 317eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 318eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 319eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* StorageInfo pack/unpack */ 320eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 321eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_si_StorageType 0 322eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_si_FilesystemType 2 323eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_si_AccessCapability 4 324eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_si_MaxCapability 6 325eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_si_FreeSpaceInBytes 14 326eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_si_FreeSpaceInImages 22 327eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_si_StorageDescription 26 328eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 329b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 330b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_SI (PTPParams *params, unsigned char* data, PTPStorageInfo *si, unsigned int len) 331eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 332eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint8_t storagedescriptionlen; 333eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 334eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->StorageType=dtoh16a(&data[PTP_si_StorageType]); 335eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->FilesystemType=dtoh16a(&data[PTP_si_FilesystemType]); 336eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->AccessCapability=dtoh16a(&data[PTP_si_AccessCapability]); 337eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->MaxCapability=dtoh64a(&data[PTP_si_MaxCapability]); 338eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->FreeSpaceInBytes=dtoh64a(&data[PTP_si_FreeSpaceInBytes]); 339eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->FreeSpaceInImages=dtoh32a(&data[PTP_si_FreeSpaceInImages]); 340eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->StorageDescription=ptp_unpack_string(params, data, 341eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_si_StorageDescription, &storagedescriptionlen); 342eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->VolumeLabel=ptp_unpack_string(params, data, 343eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_si_StorageDescription+storagedescriptionlen*2+1, 344eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &storagedescriptionlen); 345eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 346eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 347eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* ObjectInfo pack/unpack */ 348eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 349eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_StorageID 0 350eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ObjectFormat 4 351eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ProtectionStatus 6 352eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ObjectCompressedSize 8 353eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ThumbFormat 12 354eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ThumbCompressedSize 14 355eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ThumbPixWidth 18 356eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ThumbPixHeight 22 357eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ImagePixWidth 26 358eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ImagePixHeight 30 359eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ImageBitDepth 34 360eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ParentObject 38 361eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_AssociationType 42 362eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_AssociationDesc 44 363eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_SequenceNumber 48 364eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_filenamelen 52 365eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_Filename 53 366eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 367a679b1c4d273f210abb6befc5d9954a25427c329Richard Low// the max length assuming zero length dates. We have need 3 368a679b1c4d273f210abb6befc5d9954a25427c329Richard Low// bytes for these. 369a679b1c4d273f210abb6befc5d9954a25427c329Richard Low#define PTP_oi_MaxLen PTP_oi_Filename+(PTP_MAXSTRLEN+1)*2+3 370a679b1c4d273f210abb6befc5d9954a25427c329Richard Low 371b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint32_t 372b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_pack_OI (PTPParams *params, PTPObjectInfo *oi, unsigned char** oidataptr) 373eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 374b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij unsigned char* oidata; 375eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint8_t filenamelen; 376eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint8_t capturedatelen=0; 377a679b1c4d273f210abb6befc5d9954a25427c329Richard Low /* let's allocate some memory first; correct assuming zero length dates */ 378a679b1c4d273f210abb6befc5d9954a25427c329Richard Low oidata=malloc(PTP_oi_MaxLen); 379eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij /* the caller should free it after use! */ 380eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#if 0 381eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij char *capture_date="20020101T010101"; /* XXX Fake date */ 382eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#endif 383a679b1c4d273f210abb6befc5d9954a25427c329Richard Low memset (oidata, 0, PTP_oi_MaxLen); 384eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_StorageID],oi->StorageID); 385eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod16a(&oidata[PTP_oi_ObjectFormat],oi->ObjectFormat); 386eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod16a(&oidata[PTP_oi_ProtectionStatus],oi->ProtectionStatus); 387eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ObjectCompressedSize],oi->ObjectCompressedSize); 388eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod16a(&oidata[PTP_oi_ThumbFormat],oi->ThumbFormat); 389eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ThumbCompressedSize],oi->ThumbCompressedSize); 390eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ThumbPixWidth],oi->ThumbPixWidth); 391eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ThumbPixHeight],oi->ThumbPixHeight); 392eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ImagePixWidth],oi->ImagePixWidth); 393eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ImagePixHeight],oi->ImagePixHeight); 394eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ImageBitDepth],oi->ImageBitDepth); 395eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ParentObject],oi->ParentObject); 396eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod16a(&oidata[PTP_oi_AssociationType],oi->AssociationType); 397eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_AssociationDesc],oi->AssociationDesc); 398eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_SequenceNumber],oi->SequenceNumber); 399eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 400eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij ptp_pack_string(params, oi->Filename, oidata, PTP_oi_filenamelen, &filenamelen); 401eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* 402eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij filenamelen=(uint8_t)strlen(oi->Filename); 403eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod8a(&req->data[PTP_oi_filenamelen],filenamelen+1); 404eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij for (i=0;i<filenamelen && i< PTP_MAXSTRLEN; i++) { 405eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij req->data[PTP_oi_Filename+i*2]=oi->Filename[i]; 406eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 407eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij*/ 408eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij /* 409eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij *XXX Fake date. 410eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij * for example Kodak sets Capture date on the basis of EXIF data. 411eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij * Spec says that this field is from perspective of Initiator. 412eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij */ 413eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#if 0 /* seems now we don't need any data packed in OI dataset... for now ;)*/ 414eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij capturedatelen=strlen(capture_date); 415eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod8a(&data[PTP_oi_Filename+(filenamelen+1)*2], 416eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij capturedatelen+1); 417eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij for (i=0;i<capturedatelen && i< PTP_MAXSTRLEN; i++) { 418eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij data[PTP_oi_Filename+(i+filenamelen+1)*2+1]=capture_date[i]; 419eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 420eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod8a(&data[PTP_oi_Filename+(filenamelen+capturedatelen+2)*2+1], 421eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij capturedatelen+1); 422eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij for (i=0;i<capturedatelen && i< PTP_MAXSTRLEN; i++) { 423eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij data[PTP_oi_Filename+(i+filenamelen+capturedatelen+2)*2+2]= 424eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij capture_date[i]; 425eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 426eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#endif 427eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij /* XXX this function should return dataset length */ 428eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 429eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij *oidataptr=oidata; 430a679b1c4d273f210abb6befc5d9954a25427c329Richard Low return (PTP_oi_Filename+filenamelen*2+(capturedatelen+1)*3); 431eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 432eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 433b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 434b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_OI (PTPParams *params, unsigned char* data, PTPObjectInfo *oi, unsigned int len) 435eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 436eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint8_t filenamelen; 437eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint8_t capturedatelen; 438eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij char *capture_date; 439eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij char tmp[16]; 440eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij struct tm tm; 441eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 442eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij memset(&tm,0,sizeof(tm)); 443eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 444eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->StorageID=dtoh32a(&data[PTP_oi_StorageID]); 445eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ObjectFormat=dtoh16a(&data[PTP_oi_ObjectFormat]); 446eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ProtectionStatus=dtoh16a(&data[PTP_oi_ProtectionStatus]); 447eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ObjectCompressedSize=dtoh32a(&data[PTP_oi_ObjectCompressedSize]); 448eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ThumbFormat=dtoh16a(&data[PTP_oi_ThumbFormat]); 449eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ThumbCompressedSize=dtoh32a(&data[PTP_oi_ThumbCompressedSize]); 450eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ThumbPixWidth=dtoh32a(&data[PTP_oi_ThumbPixWidth]); 451eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ThumbPixHeight=dtoh32a(&data[PTP_oi_ThumbPixHeight]); 452eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ImagePixWidth=dtoh32a(&data[PTP_oi_ImagePixWidth]); 453eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ImagePixHeight=dtoh32a(&data[PTP_oi_ImagePixHeight]); 454eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ImageBitDepth=dtoh32a(&data[PTP_oi_ImageBitDepth]); 455eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ParentObject=dtoh32a(&data[PTP_oi_ParentObject]); 456eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->AssociationType=dtoh16a(&data[PTP_oi_AssociationType]); 457eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->AssociationDesc=dtoh32a(&data[PTP_oi_AssociationDesc]); 458eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->SequenceNumber=dtoh32a(&data[PTP_oi_SequenceNumber]); 459eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->Filename= ptp_unpack_string(params, data, PTP_oi_filenamelen, &filenamelen); 460eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 461eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij capture_date = ptp_unpack_string(params, data, 462eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_oi_filenamelen+filenamelen*2+1, &capturedatelen); 463eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij /* subset of ISO 8601, without '.s' tenths of second and 464eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij * time zone 465eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij */ 466eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij if (capturedatelen>15) 467eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij { 468eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij strncpy (tmp, capture_date, 4); 469eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tmp[4] = 0; 470eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tm.tm_year=atoi (tmp) - 1900; 471eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij strncpy (tmp, capture_date + 4, 2); 472eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tmp[2] = 0; 473eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tm.tm_mon = atoi (tmp) - 1; 474eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij strncpy (tmp, capture_date + 6, 2); 475eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tmp[2] = 0; 476eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tm.tm_mday = atoi (tmp); 477eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij strncpy (tmp, capture_date + 9, 2); 478eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tmp[2] = 0; 479eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tm.tm_hour = atoi (tmp); 480eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij strncpy (tmp, capture_date + 11, 2); 481eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tmp[2] = 0; 482eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tm.tm_min = atoi (tmp); 483eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij strncpy (tmp, capture_date + 13, 2); 484eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tmp[2] = 0; 485eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tm.tm_sec = atoi (tmp); 486eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->CaptureDate=mktime (&tm); 487eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 488eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij free(capture_date); 489eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 490eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij /* now it's modification date ;) */ 491eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij capture_date = ptp_unpack_string(params, data, 492eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_oi_filenamelen+filenamelen*2 493eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij +capturedatelen*2+2,&capturedatelen); 494eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij if (capturedatelen>15) 495eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij { 496eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij strncpy (tmp, capture_date, 4); 497eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tmp[4] = 0; 498eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tm.tm_year=atoi (tmp) - 1900; 499eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij strncpy (tmp, capture_date + 4, 2); 500eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tmp[2] = 0; 501eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tm.tm_mon = atoi (tmp) - 1; 502eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij strncpy (tmp, capture_date + 6, 2); 503eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tmp[2] = 0; 504eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tm.tm_mday = atoi (tmp); 505eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij strncpy (tmp, capture_date + 9, 2); 506eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tmp[2] = 0; 507eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tm.tm_hour = atoi (tmp); 508eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij strncpy (tmp, capture_date + 11, 2); 509eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tmp[2] = 0; 510eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tm.tm_min = atoi (tmp); 511eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij strncpy (tmp, capture_date + 13, 2); 512eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tmp[2] = 0; 513eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tm.tm_sec = atoi (tmp); 514eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ModificationDate=mktime (&tm); 515eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 516eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij free(capture_date); 517eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 518eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 519eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* Custom Type Value Assignement (without Length) macro frequently used below */ 520b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define CTVAL(target,func) { \ 521b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (total - *offset < sizeof(target)) \ 522b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 0; \ 523b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij target = func(&data[*offset]); \ 524b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij *offset += sizeof(target); \ 525eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 526eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 527b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define RARR(val,member,func) { \ 528b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij int n,j; \ 529b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (total - *offset < sizeof(uint32_t)) \ 530b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 0; \ 531b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij n = dtoh32a (&data[*offset]); \ 532b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij *offset += sizeof(uint32_t); \ 533b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij \ 534b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij val->a.count = n; \ 535b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij val->a.v = malloc(sizeof(val->a.v[0])*n); \ 536b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!val->a.v) return 0; \ 537b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (j=0;j<n;j++) \ 538b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij CTVAL(val->a.v[j].member, func); \ 539b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij} 540eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 541b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline int 542b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_DPV ( 543b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij PTPParams *params, unsigned char* data, int *offset, int total, 544b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij PTPPropertyValue* value, uint16_t datatype 545b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij) { 546eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij switch (datatype) { 547b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_INT8: 548b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij CTVAL(value->i8,dtoh8a); 549b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 550b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_UINT8: 551b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij CTVAL(value->u8,dtoh8a); 552b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 553b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_INT16: 554b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij CTVAL(value->i16,dtoh16a); 555b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 556b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_UINT16: 557b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij CTVAL(value->u16,dtoh16a); 558b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 559b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_INT32: 560b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij CTVAL(value->i32,dtoh32a); 561b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 562b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_UINT32: 563b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij CTVAL(value->u32,dtoh32a); 564b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 565037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij 566037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij 567037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij 568037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij case PTP_DTC_UINT64: 569037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij *offset += 8; 570037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij /*fprintf(stderr,"unhandled unpack of uint64\n");*/ 571037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij break; 572037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij case PTP_DTC_INT64: 573037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij *offset += 8; 574037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij /*fprintf(stderr,"unhandled unpack of int64\n");*/ 575037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij break; 576037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij case PTP_DTC_UINT128: 577037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij *offset += 16; 578037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij /*fprintf(stderr,"unhandled unpack of uint128n");*/ 579037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij break; 580037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij case PTP_DTC_INT128: 581037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij *offset += 16; 582037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij /*fprintf(stderr,"unhandled unpack of int128n");*/ 583037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij break; 584037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij 585037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij 586037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij 587b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AINT8: 588b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij RARR(value,i8,dtoh8a); 589b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 590b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AUINT8: 591b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij RARR(value,u8,dtoh8a); 592b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 593b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AUINT16: 594b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij RARR(value,u16,dtoh16a); 595b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 596b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AINT16: 597b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij RARR(value,i16,dtoh16a); 598b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 599b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AUINT32: 600b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij RARR(value,u32,dtoh32a); 601b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 602b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AINT32: 603b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij RARR(value,i32,dtoh32a); 604b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 605b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij /* XXX: other int types are unimplemented */ 606b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij /* XXX: other int arrays are unimplemented also */ 607b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_STR: { 608b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij uint8_t len; 609b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij /* XXX: max size */ 610b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij value->str = ptp_unpack_string(params,data,*offset,&len); 611b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij *offset += len*2+1; 612b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!value->str) 613eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return 0; 614b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 615eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 616037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij default: 617037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij return 0; 618b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 619b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 1; 620eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 621eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 622eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* Device Property pack/unpack */ 623eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 624eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_dpd_DevicePropertyCode 0 625eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_dpd_DataType 2 626eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_dpd_GetSet 4 627eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_dpd_FactoryDefaultValue 5 628eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 629b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline int 630b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_DPD (PTPParams *params, unsigned char* data, PTPDevicePropDesc *dpd, unsigned int dpdlen) 631eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 632b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij int offset=0, ret; 633eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 634b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij memset (dpd, 0, sizeof(*dpd)); 635eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij dpd->DevicePropertyCode=dtoh16a(&data[PTP_dpd_DevicePropertyCode]); 636eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij dpd->DataType=dtoh16a(&data[PTP_dpd_DataType]); 637eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij dpd->GetSet=dtoh8a(&data[PTP_dpd_GetSet]); 638b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 639b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij offset = PTP_dpd_FactoryDefaultValue; 640b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->FactoryDefaultValue, dpd->DataType); 641b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 642b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->CurrentValue, dpd->DataType); 643b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 644b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 645b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij /* if offset==0 then Data Type format is not supported by this 646b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij code or the Data Type is a string (with two empty strings as 647b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij values). In both cases Form Flag should be set to 0x00 and FORM is 648b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij not present. */ 649b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 650eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij dpd->FormFlag=PTP_DPFF_None; 651b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (offset==PTP_dpd_FactoryDefaultValue) 652b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 1; 653b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 654b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpd->FormFlag=dtoh8a(&data[offset]); 655b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij offset+=sizeof(uint8_t); 656eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 657eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij switch (dpd->FormFlag) { 658b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DPFF_Range: 659b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->FORM.Range.MinimumValue, dpd->DataType); 660b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 661b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->FORM.Range.MaximumValue, dpd->DataType); 662b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 663b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->FORM.Range.StepSize, dpd->DataType); 664b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 665eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij break; 666b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DPFF_Enumeration: { 667b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij int i; 668eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define N dpd->FORM.Enum.NumberOfValues 669b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij N = dtoh16a(&data[offset]); 670b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij offset+=sizeof(uint16_t); 671b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpd->FORM.Enum.SupportedValue = malloc(N*sizeof(dpd->FORM.Enum.SupportedValue[0])); 672b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!dpd->FORM.Enum.SupportedValue) 673b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij goto outofmemory; 674b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 675b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij memset (dpd->FORM.Enum.SupportedValue,0 , N*sizeof(dpd->FORM.Enum.SupportedValue[0])); 676b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<N;i++) { 677b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->FORM.Enum.SupportedValue[i], dpd->DataType); 678b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 679b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij /* Slightly different handling here. The HP PhotoSmart 120 680b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij * specifies an enumeration with N in wrong endian 681b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij * 00 01 instead of 01 00, so we count the enum just until the 682b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij * the end of the packet. 683b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij */ 684b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) { 685b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!i) 686b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij goto outofmemory; 687b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpd->FORM.Enum.NumberOfValues = i; 688b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 689eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 690b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 691eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 692eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 693b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#undef N 694b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 1; 695b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijoutofmemory: 696b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ptp_free_devicepropdesc(dpd); 697b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 0; 698eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 699eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 700b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij/* (MTP) Object Property pack/unpack */ 701b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_opd_ObjectPropertyCode 0 702b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_opd_DataType 2 703b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_opd_GetSet 4 704b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_opd_FactoryDefaultValue 5 705eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 706b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline int 707b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_OPD (PTPParams *params, unsigned char* data, PTPObjectPropDesc *opd, unsigned int opdlen) 708eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 709b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij int offset=0, ret; 710b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 711b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij memset (opd, 0, sizeof(*opd)); 712b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij opd->ObjectPropertyCode=dtoh16a(&data[PTP_opd_ObjectPropertyCode]); 713b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij opd->DataType=dtoh16a(&data[PTP_opd_DataType]); 714b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij opd->GetSet=dtoh8a(&data[PTP_opd_GetSet]); 715b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 716b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij offset = PTP_opd_FactoryDefaultValue; 717b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, opdlen, &opd->FactoryDefaultValue, opd->DataType); 718b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 719b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 720b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij opd->GroupCode=dtoh32a(&data[offset]); 721b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij offset+=sizeof(uint32_t); 722b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 723b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij opd->FormFlag=dtoh8a(&data[offset]); 724b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij offset+=sizeof(uint8_t); 725b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 726b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij switch (opd->FormFlag) { 727b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_OPFF_Range: 728b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, opdlen, &opd->FORM.Range.MinimumValue, opd->DataType); 729b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 730b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, opdlen, &opd->FORM.Range.MaximumValue, opd->DataType); 731b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 732b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, opdlen, &opd->FORM.Range.StepSize, opd->DataType); 733b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 734b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 735b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_OPFF_Enumeration: { 736b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij int i; 737b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define N opd->FORM.Enum.NumberOfValues 738b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij N = dtoh16a(&data[offset]); 739b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij offset+=sizeof(uint16_t); 740b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij opd->FORM.Enum.SupportedValue = malloc(N*sizeof(opd->FORM.Enum.SupportedValue[0])); 741b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!opd->FORM.Enum.SupportedValue) 742b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij goto outofmemory; 743b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 744b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij memset (opd->FORM.Enum.SupportedValue,0 , N*sizeof(opd->FORM.Enum.SupportedValue[0])); 745b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<N;i++) { 746b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, opdlen, &opd->FORM.Enum.SupportedValue[i], opd->DataType); 747b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 748b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij /* Slightly different handling here. The HP PhotoSmart 120 749b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij * specifies an enumeration with N in wrong endian 750b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij * 00 01 instead of 01 00, so we count the enum just until the 751b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij * the end of the packet. 752b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij */ 753b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) { 754b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!i) 755b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij goto outofmemory; 756b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij opd->FORM.Enum.NumberOfValues = i; 757b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 758b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 759b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 760b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#undef N 761b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 762eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 763b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 1; 764b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijoutofmemory: 765b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ptp_free_objectpropdesc(opd); 766b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 0; 767eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 768eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 769eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 770b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint32_t 771b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_pack_DPV (PTPParams *params, PTPPropertyValue* value, unsigned char** dpvptr, uint16_t datatype) 772eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 773b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij unsigned char* dpv=NULL; 774eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint32_t size=0; 775b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij int i; 776eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 777eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij switch (datatype) { 778b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_INT8: 779b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(int8_t); 780b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 781b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod8a(dpv,value->i8); 782b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 783b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_UINT8: 784b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint8_t); 785b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 786b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod8a(dpv,value->u8); 787b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 788b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_INT16: 789b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(int16_t); 790b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 791b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(dpv,value->i16); 792b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 793b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_UINT16: 794b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint16_t); 795b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 796b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(dpv,value->u16); 797b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 798b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_INT32: 799b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(int32_t); 800b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 801b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(dpv,value->i32); 802b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 803b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_UINT32: 804b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint32_t); 805b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 806b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(dpv,value->u32); 807b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 808b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AUINT8: 809b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint32_t)+value->a.count*sizeof(uint8_t); 810b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 811b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(dpv,value->a.count); 812b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<value->a.count;i++) 813b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod8a(&dpv[4+i],value->a.v[i].u8); 814b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 815b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AINT8: 816b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint32_t)+value->a.count*sizeof(int8_t); 817b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 818b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(dpv,value->a.count); 819b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<value->a.count;i++) 820b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod8a(&dpv[4+i],value->a.v[i].i8); 821b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 822b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AUINT16: 823b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint32_t)+value->a.count*sizeof(uint16_t); 824b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 825b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(dpv,value->a.count); 826b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<value->a.count;i++) 827b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(&dpv[4+i],value->a.v[i].u16); 828b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 829b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AINT16: 830b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint32_t)+value->a.count*sizeof(int16_t); 831b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 832b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(dpv,value->a.count); 833b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<value->a.count;i++) 834b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(&dpv[4+i],value->a.v[i].i16); 835b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 836b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AUINT32: 837b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint32_t)+value->a.count*sizeof(uint32_t); 838b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 839b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(dpv,value->a.count); 840b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<value->a.count;i++) 841b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(&dpv[4+i],value->a.v[i].u32); 842b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 843b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AINT32: 844b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint32_t)+value->a.count*sizeof(int32_t); 845b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 846b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(dpv,value->a.count); 847b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<value->a.count;i++) 848b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(&dpv[4+i],value->a.v[i].i32); 849b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 850b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij /* XXX: other int types are unimplemented */ 851b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_STR: { 852735f41692934a716158cf051d76e988febeca7eeLinus Walleij dpv=ptp_get_packed_stringcopy(params, value->str, &size); 853eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij break; 854b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 855eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 856eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij *dpvptr=dpv; 857eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return size; 85899310d4445697da39f22dff35457c75e35e97171Linus Walleij} 85999310d4445697da39f22dff35457c75e35e97171Linus Walleij 86099310d4445697da39f22dff35457c75e35e97171Linus Walleij#define MAX_MTP_PROPS 127 86199310d4445697da39f22dff35457c75e35e97171Linus Walleijstatic inline uint32_t 8626c0a6ce803cf79802b1c48339adf0964db30ec83Richard Lowptp_pack_OPL (PTPParams *params, MTPPropList *proplist, unsigned char** opldataptr) 86399310d4445697da39f22dff35457c75e35e97171Linus Walleij{ 86499310d4445697da39f22dff35457c75e35e97171Linus Walleij unsigned char* opldata; 86599310d4445697da39f22dff35457c75e35e97171Linus Walleij MTPPropList *propitr; 86699310d4445697da39f22dff35457c75e35e97171Linus Walleij unsigned char *packedprops[MAX_MTP_PROPS]; 86799310d4445697da39f22dff35457c75e35e97171Linus Walleij uint32_t packedpropslens[MAX_MTP_PROPS]; 86839b9374f23451201dece736db13f0f648584dc32Linus Walleij uint32_t packedobjecthandles[MAX_MTP_PROPS]; 86999310d4445697da39f22dff35457c75e35e97171Linus Walleij uint16_t packedpropsids[MAX_MTP_PROPS]; 87099310d4445697da39f22dff35457c75e35e97171Linus Walleij uint16_t packedpropstypes[MAX_MTP_PROPS]; 87199310d4445697da39f22dff35457c75e35e97171Linus Walleij uint32_t totalsize = 0; 87299310d4445697da39f22dff35457c75e35e97171Linus Walleij uint32_t bufp = 0; 87399310d4445697da39f22dff35457c75e35e97171Linus Walleij uint32_t noitems = 0; 87499310d4445697da39f22dff35457c75e35e97171Linus Walleij uint32_t i; 87599310d4445697da39f22dff35457c75e35e97171Linus Walleij 87699310d4445697da39f22dff35457c75e35e97171Linus Walleij totalsize = sizeof(uint32_t); /* 4 bytes to store the number of elements */ 87799310d4445697da39f22dff35457c75e35e97171Linus Walleij propitr = proplist; 87899310d4445697da39f22dff35457c75e35e97171Linus Walleij while (propitr != NULL && noitems < MAX_MTP_PROPS) { 8796c0a6ce803cf79802b1c48339adf0964db30ec83Richard Low /* Object Handle */ 88039b9374f23451201dece736db13f0f648584dc32Linus Walleij packedobjecthandles[noitems]=propitr->ObjectHandle; 88199310d4445697da39f22dff35457c75e35e97171Linus Walleij totalsize += sizeof(uint32_t); /* Object ID */ 88299310d4445697da39f22dff35457c75e35e97171Linus Walleij /* Metadata type */ 88399310d4445697da39f22dff35457c75e35e97171Linus Walleij packedpropsids[noitems]=propitr->property; 88499310d4445697da39f22dff35457c75e35e97171Linus Walleij totalsize += sizeof(uint16_t); 88599310d4445697da39f22dff35457c75e35e97171Linus Walleij /* Data type */ 88699310d4445697da39f22dff35457c75e35e97171Linus Walleij packedpropstypes[noitems]= propitr->datatype; 88799310d4445697da39f22dff35457c75e35e97171Linus Walleij totalsize += sizeof(uint16_t); 88899310d4445697da39f22dff35457c75e35e97171Linus Walleij /* Add each property to be sent. */ 88999310d4445697da39f22dff35457c75e35e97171Linus Walleij packedpropslens[noitems] = ptp_pack_DPV (params, &propitr->propval, &packedprops[noitems], propitr->datatype); 89099310d4445697da39f22dff35457c75e35e97171Linus Walleij totalsize += packedpropslens[noitems]; 89199310d4445697da39f22dff35457c75e35e97171Linus Walleij noitems ++; 89299310d4445697da39f22dff35457c75e35e97171Linus Walleij propitr = propitr->next; 89399310d4445697da39f22dff35457c75e35e97171Linus Walleij } 89499310d4445697da39f22dff35457c75e35e97171Linus Walleij 89599310d4445697da39f22dff35457c75e35e97171Linus Walleij /* Allocate memory for the packed property list */ 89699310d4445697da39f22dff35457c75e35e97171Linus Walleij opldata = malloc(totalsize); 89799310d4445697da39f22dff35457c75e35e97171Linus Walleij 89899310d4445697da39f22dff35457c75e35e97171Linus Walleij htod32a(&opldata[bufp],noitems); 89999310d4445697da39f22dff35457c75e35e97171Linus Walleij bufp += 4; 90099310d4445697da39f22dff35457c75e35e97171Linus Walleij 90199310d4445697da39f22dff35457c75e35e97171Linus Walleij /* Copy into a nice packed list */ 90299310d4445697da39f22dff35457c75e35e97171Linus Walleij for (i = 0; i < noitems; i++) { 90399310d4445697da39f22dff35457c75e35e97171Linus Walleij /* Object ID */ 9046c0a6ce803cf79802b1c48339adf0964db30ec83Richard Low htod32a(&opldata[bufp],packedobjecthandles[i]); 90599310d4445697da39f22dff35457c75e35e97171Linus Walleij bufp += sizeof(uint32_t); 90699310d4445697da39f22dff35457c75e35e97171Linus Walleij htod16a(&opldata[bufp],packedpropsids[i]); 90799310d4445697da39f22dff35457c75e35e97171Linus Walleij bufp += sizeof(uint16_t); 90899310d4445697da39f22dff35457c75e35e97171Linus Walleij htod16a(&opldata[bufp],packedpropstypes[i]); 90999310d4445697da39f22dff35457c75e35e97171Linus Walleij bufp += sizeof(uint16_t); 91099310d4445697da39f22dff35457c75e35e97171Linus Walleij /* The copy the actual property */ 91199310d4445697da39f22dff35457c75e35e97171Linus Walleij memcpy(&opldata[bufp], packedprops[i], packedpropslens[i]); 91299310d4445697da39f22dff35457c75e35e97171Linus Walleij bufp += packedpropslens[i]; 91399310d4445697da39f22dff35457c75e35e97171Linus Walleij free(packedprops[i]); 91499310d4445697da39f22dff35457c75e35e97171Linus Walleij } 91599310d4445697da39f22dff35457c75e35e97171Linus Walleij *opldataptr = opldata; 91699310d4445697da39f22dff35457c75e35e97171Linus Walleij return totalsize; 917eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 918eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 9198d82d2f4b0794e41ec26289045867eebb3496b8cRichard Lowstatic inline int 9208d82d2f4b0794e41ec26289045867eebb3496b8cRichard Lowptp_unpack_OPL (PTPParams *params, unsigned char* data, MTPPropList **proplist, unsigned int len) 9218d82d2f4b0794e41ec26289045867eebb3496b8cRichard Low{ 922277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij uint32_t prop_count = dtoh32a(data); 923277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij MTPPropList *prop = NULL; 924277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij int offset = 0, i; 925277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij 926277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij if (prop_count == 0) { 927277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij *proplist = NULL; 928277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij return 0; 929277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij } 930277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij data += sizeof(uint32_t); 931277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij *proplist = malloc(sizeof(MTPPropList)); 932277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij prop = *proplist; 933277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij for (i = 0; i < prop_count; i++) { 9346c0a6ce803cf79802b1c48339adf0964db30ec83Richard Low prop->ObjectHandle = dtoh32a(data); 935277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij data += sizeof(uint32_t); 936277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij len -= sizeof(uint32_t); 937277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij 9386c0a6ce803cf79802b1c48339adf0964db30ec83Richard Low prop->property = dtoh16a(data); 939277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij data += sizeof(uint16_t); 940277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij len -= sizeof(uint16_t); 941277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij 9426c0a6ce803cf79802b1c48339adf0964db30ec83Richard Low prop->datatype = dtoh16a(data); 943277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij data += sizeof(uint16_t); 944277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij len -= sizeof(uint16_t); 945277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij 946277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij offset = 0; 947277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij ptp_unpack_DPV(params, data, &offset, len, &prop->propval, prop->datatype); 948277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij data += offset; 949277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij len -= offset; 950277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij 951277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij if (i != prop_count - 1) { 952277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij prop->next = malloc(sizeof(MTPPropList)); 953277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij prop = prop->next; 954277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij } else 955277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij prop->next = NULL; 956277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij } 957277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij return prop_count; 9588d82d2f4b0794e41ec26289045867eebb3496b8cRichard Low} 9598d82d2f4b0794e41ec26289045867eebb3496b8cRichard Low 960eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* 961eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP USB Event container unpack 962eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij Copyright (c) 2003 Nikolai Kopanygin 963eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij*/ 964eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 965eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_ec_Length 0 966eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_ec_Type 4 967eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_ec_Code 6 968eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_ec_TransId 8 969eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_ec_Param1 12 970eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_ec_Param2 16 971eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_ec_Param3 20 972eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 973b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 974b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_EC (PTPParams *params, unsigned char* data, PTPUSBEventContainer *ec, unsigned int len) 975eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 976eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij if (data==NULL) 977eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return; 978eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij ec->length=dtoh32a(&data[PTP_ec_Length]); 979eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij ec->type=dtoh16a(&data[PTP_ec_Type]); 980eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij ec->code=dtoh16a(&data[PTP_ec_Code]); 981eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij ec->trans_id=dtoh32a(&data[PTP_ec_TransId]); 982b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 983eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij if (ec->length>=(PTP_ec_Param1+4)) 984eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij ec->param1=dtoh32a(&data[PTP_ec_Param1]); 985eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij else 986eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij ec->param1=0; 987eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij if (ec->length>=(PTP_ec_Param2+4)) 988eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij ec->param2=dtoh32a(&data[PTP_ec_Param2]); 989eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij else 990eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij ec->param2=0; 991eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij if (ec->length>=(PTP_ec_Param3+4)) 992eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij ec->param3=dtoh32a(&data[PTP_ec_Param3]); 993eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij else 994eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij ec->param3=0; 995eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 996eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 997eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* 998eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP Canon Folder Entry unpack 999eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij Copyright (c) 2003 Nikolai Kopanygin 1000eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij*/ 1001eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_cfe_ObjectHandle 0 1002eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_cfe_ObjectFormatCode 4 1003eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_cfe_Flags 6 1004eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_cfe_ObjectSize 7 1005eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_cfe_Time 11 1006eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_cfe_Filename 15 1007eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 1008b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 1009b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_Canon_FE (PTPParams *params, unsigned char* data, PTPCANONFolderEntry *fe) 1010eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 1011eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij int i; 1012eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij if (data==NULL) 1013eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return; 1014eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij fe->ObjectHandle=dtoh32a(&data[PTP_cfe_ObjectHandle]); 1015eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij fe->ObjectFormatCode=dtoh16a(&data[PTP_cfe_ObjectFormatCode]); 1016eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij fe->Flags=dtoh8a(&data[PTP_cfe_Flags]); 1017b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij fe->ObjectSize=dtoh32a((unsigned char*)&data[PTP_cfe_ObjectSize]); 1018eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij fe->Time=(time_t)dtoh32a(&data[PTP_cfe_Time]); 1019eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij for (i=0; i<PTP_CANON_FilenameBufferLen; i++) 1020b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij fe->Filename[i]=(char)dtoh8a(&data[PTP_cfe_Filename+i]); 1021b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij} 1022b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 1023b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij/* 1024b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij PTP USB Event container unpack for Nikon events. 1025b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij*/ 1026b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_nikon_ec_Length 0 1027b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_nikon_ec_Code 2 1028b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_nikon_ec_Param1 4 1029b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_nikon_ec_Size 6 1030b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 1031b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_Nikon_EC (PTPParams *params, unsigned char* data, unsigned int len, PTPUSBEventContainer **ec, int *cnt) 1032b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij{ 1033b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij int i; 1034b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 1035b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij *ec = NULL; 1036b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (data == NULL) 1037b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return; 1038b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (len < PTP_nikon_ec_Code) 1039b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return; 1040b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij *cnt = dtoh16a(&data[PTP_nikon_ec_Length]); 1041b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (*cnt > (len-PTP_nikon_ec_Code)/PTP_nikon_ec_Size) /* broken cnt? */ 1042b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return; 1043b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij *ec = malloc(sizeof(PTPUSBEventContainer)*(*cnt)); 1044b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 1045b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<*cnt;i++) { 1046b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij memset(&(*ec)[i],0,sizeof(PTPUSBEventContainer)); 1047b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij (*ec)[i].code = dtoh16a(&data[PTP_nikon_ec_Code+PTP_nikon_ec_Size*i]); 1048b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij (*ec)[i].param1 = dtoh32a(&data[PTP_nikon_ec_Param1+PTP_nikon_ec_Size*i]); 1049b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 1050eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 1051eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 1052eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 1053b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint32_t 1054b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_pack_EK_text(PTPParams *params, PTPEKTextParams *text, unsigned char **data) { 1055b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij int i, len = 0; 1056b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij uint8_t retlen; 1057b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij unsigned char *curdata; 1058b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 1059b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij len = 2*(strlen(text->title)+1)+1+ 1060b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 2*(strlen(text->line[0])+1)+1+ 1061b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 2*(strlen(text->line[1])+1)+1+ 1062b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 2*(strlen(text->line[2])+1)+1+ 1063b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 2*(strlen(text->line[3])+1)+1+ 1064b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 2*(strlen(text->line[4])+1)+1+ 1065b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 4*2+2*4+2+4+2+5*4*2; 1066b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij *data = malloc(len); 1067b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!*data) return 0; 1068b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 1069b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij curdata = *data; 1070b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,100);curdata+=2; 1071b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,1);curdata+=2; 1072b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,0);curdata+=2; 1073b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,1000);curdata+=2; 1074b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 1075b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(curdata,0);curdata+=4; 1076b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(curdata,0);curdata+=4; 1077b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 1078b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,6);curdata+=2; 1079b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(curdata,0);curdata+=4; 1080b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 1081b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ptp_pack_string(params, text->title, curdata, 0, &retlen); curdata+=2*retlen+1;htod16a(curdata,0);curdata+=2; 1082b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,0x10);curdata+=2; 1083b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 1084b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<5;i++) { 1085b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ptp_pack_string(params, text->line[i], curdata, 0, &retlen); curdata+=2*retlen+1;htod16a(curdata,0);curdata+=2; 1086b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,0x10);curdata+=2; 1087b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,0x01);curdata+=2; 1088b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,0x02);curdata+=2; 1089b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,0x06);curdata+=2; 1090b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 1091b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return len; 1092b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij} 10937347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij 10947347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_version 0x00 10957347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_ofc 0x02 10967347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_unk1 0x04 10977347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_objectid 0x08 10987347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_parentid 0x0c 10997347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_previd 0x10 /* in same dir */ 11007347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_nextid 0x14 /* in same dir */ 11017347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_nextchild 0x18 /* down one dir */ 11027347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_storageid 0x1c /* only in storage entry */ 11037347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_name 0x20 11047347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_flags 0x2c 11057347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_size 0x30 11067347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_unixtime 0x34 11077347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_year 0x38 11087347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_month 0x39 11097347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_mday 0x3a 11107347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_hour 0x3b 11117347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_minute 0x3c 11127347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_second 0x3d 11137347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_unk2 0x3e 11147347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_thumbsize 0x40 11157347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_width 0x44 11167347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_height 0x48 11177347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij 11187347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleijstatic inline uint16_t 11197347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleijptp_unpack_canon_directory ( 11207347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij PTPParams *params, 11217347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij unsigned char *dir, 11227347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij uint32_t cnt, 11237347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij PTPObjectHandles *handles, 11247347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij PTPObjectInfo **oinfos, /* size(handles->n) */ 11257347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij uint32_t **flags /* size(handles->n) */ 11267347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij) { 11277347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij unsigned int i, j, nrofobs = 0, curob = 0; 11287347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij 11297347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ISOBJECT(ptr) (dtoh32a((ptr)+ptp_canon_dir_storageid) == 0xffffffff) 11307347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij for (i=0;i<cnt;i++) 11317347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (ISOBJECT(dir+i*0x4c)) nrofobs++; 11327347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij handles->n = nrofobs; 11337347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij handles->Handler = calloc(sizeof(handles->Handler[0]),nrofobs); 11347347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (!handles->Handler) return PTP_RC_GeneralError; 11357347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij *oinfos = calloc(sizeof((*oinfos)[0]),nrofobs); 11367347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (!*oinfos) return PTP_RC_GeneralError; 11377347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij *flags = calloc(sizeof((*flags)[0]),nrofobs); 11387347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (!*flags) return PTP_RC_GeneralError; 11397347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij 11407347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij /* Migrate data into objects ids, handles into 11417347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij * the object handler array. 11427347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij */ 11437347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij curob = 0; 11447347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij for (i=0;i<cnt;i++) { 11457347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij unsigned char *cur = dir+i*0x4c; 11467347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij PTPObjectInfo *oi = (*oinfos)+curob; 11477347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij 11487347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (!ISOBJECT(cur)) 11497347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij continue; 11507347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij 11517347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij handles->Handler[curob] = dtoh32a(cur + ptp_canon_dir_objectid); 11527347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij oi->StorageID = 0xffffffff; 11537347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij oi->ObjectFormat = dtoh16a(cur + ptp_canon_dir_ofc); 11547347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij oi->ParentObject = dtoh32a(cur + ptp_canon_dir_parentid); 11557347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij oi->Filename = strdup((char*)(cur + ptp_canon_dir_name)); 11567347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij oi->ObjectCompressedSize= dtoh32a(cur + ptp_canon_dir_size); 11577347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij oi->ThumbCompressedSize = dtoh32a(cur + ptp_canon_dir_thumbsize); 11587347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij oi->ImagePixWidth = dtoh32a(cur + ptp_canon_dir_width); 11597347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij oi->ImagePixHeight = dtoh32a(cur + ptp_canon_dir_height); 11607347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij oi->CaptureDate = oi->ModificationDate = dtoh32a(cur + ptp_canon_dir_unixtime); 11617347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij (*flags)[curob] = dtoh32a(cur + ptp_canon_dir_flags); 11627347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij curob++; 11637347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 11647347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij /* Walk over Storage ID entries and distribute the IDs to 11657347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij * the parent objects. */ 11667347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij for (i=0;i<cnt;i++) { 11677347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij unsigned char *cur = dir+i*0x4c; 11687347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij uint32_t nextchild = dtoh32a(cur + ptp_canon_dir_nextchild); 11697347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij 11707347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (ISOBJECT(cur)) 11717347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij continue; 11727347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij for (j=0;j<handles->n;j++) if (nextchild == handles->Handler[j]) break; 11737347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (j == handles->n) continue; 11747347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij (*oinfos)[j].StorageID = dtoh32a(cur + ptp_canon_dir_storageid); 11757347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 11767347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij /* Walk over all objects and distribute the storage ids */ 11777347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij while (1) { 11787347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij int changed = 0; 11797347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij for (i=0;i<cnt;i++) { 11807347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij unsigned char *cur = dir+i*0x4c; 11817347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij uint32_t oid = dtoh32a(cur + ptp_canon_dir_objectid); 11827347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij uint32_t nextoid = dtoh32a(cur + ptp_canon_dir_nextid); 11837347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij uint32_t nextchild = dtoh32a(cur + ptp_canon_dir_nextchild); 11847347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij uint32_t storageid; 11857347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij 11867347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (!ISOBJECT(cur)) 11877347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij continue; 11887347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij for (j=0;j<handles->n;j++) if (oid == handles->Handler[j]) break; 11897347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (j == handles->n) { 11907347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij /*fprintf(stderr,"did not find oid in lookup pass for current oid\n");*/ 11917347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij continue; 11927347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 11937347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij storageid = (*oinfos)[j].StorageID; 11947347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (storageid == 0xffffffff) continue; 11957347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (nextoid != 0xffffffff) { 11967347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij for (j=0;j<handles->n;j++) if (nextoid == handles->Handler[j]) break; 11977347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (j == handles->n) { 11987347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij /*fprintf(stderr,"did not find oid in lookup pass for next oid\n");*/ 11997347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij continue; 12007347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 12017347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if ((*oinfos)[j].StorageID == 0xffffffff) { 12027347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij (*oinfos)[j].StorageID = storageid; 12037347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij changed++; 12047347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 12057347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 12067347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (nextchild != 0xffffffff) { 12077347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij for (j=0;j<handles->n;j++) if (nextchild == handles->Handler[j]) break; 12087347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (j == handles->n) { 12097347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij /*fprintf(stderr,"did not find oid in lookup pass for next child\n");*/ 12107347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij continue; 12117347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 12127347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if ((*oinfos)[j].StorageID == 0xffffffff) { 12137347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij (*oinfos)[j].StorageID = storageid; 12147347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij changed++; 12157347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 12167347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 12177347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 12187347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij /* Check if we: 12197347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij * - changed no entry (nothing more to do) 12207347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij * - changed all of them at once (usually happens) 12217347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij * break if we do. 12227347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij */ 12237347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (!changed || (changed==nrofobs-1)) 12247347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij break; 12257347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 12267347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#undef ISOBJECT 12277347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij return PTP_RC_OK; 12287347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij} 12297347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij 1230