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