ptp-pack.c revision a823a70e892d5eb1f4528679429cb3d9539abbe4
1b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij/* currently this file is included into ptp.c */ 2eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 3a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij#include <iconv.h> 4a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij 5b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint16_t 6eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleijhtod16p (PTPParams *params, uint16_t var) 7eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 8eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return ((params->byteorder==PTP_DL_LE)?htole16(var):htobe16(var)); 9eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 10eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 11b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint32_t 12eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleijhtod32p (PTPParams *params, uint32_t var) 13eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 14eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return ((params->byteorder==PTP_DL_LE)?htole32(var):htobe32(var)); 15eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 16eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 17b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 18eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleijhtod16ap (PTPParams *params, unsigned char *a, uint16_t val) 19eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 20eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij if (params->byteorder==PTP_DL_LE) 21b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htole16a(a,val); 22b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij else 23eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htobe16a(a,val); 24eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 25eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 26b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 27eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleijhtod32ap (PTPParams *params, unsigned char *a, uint32_t val) 28eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 29eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij if (params->byteorder==PTP_DL_LE) 30b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htole32a(a,val); 31b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij else 32eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htobe32a(a,val); 33eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 34eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 35b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint16_t 36eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleijdtoh16p (PTPParams *params, uint16_t var) 37eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 38eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return ((params->byteorder==PTP_DL_LE)?le16toh(var):be16toh(var)); 39eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 40eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 41b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint32_t 42eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleijdtoh32p (PTPParams *params, uint32_t var) 43eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 44eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return ((params->byteorder==PTP_DL_LE)?le32toh(var):be32toh(var)); 45eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 46eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 47b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint16_t 48eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleijdtoh16ap (PTPParams *params, unsigned char *a) 49eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 50eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return ((params->byteorder==PTP_DL_LE)?le16atoh(a):be16atoh(a)); 51eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 52eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 53b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint32_t 54eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleijdtoh32ap (PTPParams *params, unsigned char *a) 55eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 56eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return ((params->byteorder==PTP_DL_LE)?le32atoh(a):be32atoh(a)); 57eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 58eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 59b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint64_t 60eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleijdtoh64ap (PTPParams *params, unsigned char *a) 61eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 62b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij uint64_t tmp = 0; 63b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij int i; 64b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 65b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (params->byteorder==PTP_DL_LE) { 66b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<8;i++) 67b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij tmp |= (((uint64_t)a[i]) << (8*i)); 68b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } else { 69b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<8;i++) 70b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij tmp |= (((uint64_t)a[i]) << (8*(7-i))); 71b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 72b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return tmp; 73eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 74eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 75b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define htod8a(a,x) *(uint8_t*)(a) = x 76b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define htod16a(a,x) htod16ap(params,a,x) 77b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define htod32a(a,x) htod32ap(params,a,x) 78b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define htod16(x) htod16p(params,x) 79b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define htod32(x) htod32p(params,x) 80b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 81b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define dtoh8a(x) (*(uint8_t*)(x)) 82b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define dtoh16a(a) dtoh16ap(params,a) 83b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define dtoh32a(a) dtoh32ap(params,a) 84b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define dtoh64a(a) dtoh64ap(params,a) 85b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define dtoh16(x) dtoh16p(params,x) 86b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define dtoh32(x) dtoh32p(params,x) 87b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 88b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 89b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline char* 90b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_string(PTPParams *params, unsigned char* data, uint16_t offset, uint8_t *len) 91eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 92eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij int i; 93a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij uint8_t loclen; 94a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij 95a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij /* Cannot exceed 255 (PTP_MAXSTRLEN) since it is a single byte, duh ... */ 96a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij loclen = dtoh8a(&data[offset]); 97a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij /* This len is used to advance the buffer pointer */ 98a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij *len = loclen; 99a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij if (loclen) { 100a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij uint16_t string[PTP_MAXSTRLEN+1]; 101a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij char *stringp = (char *) string; 102a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij char loclstr[PTP_MAXSTRLEN*3+1]; /* UTF-8 encoding is max 3 bytes per UCS2 char. */ 103a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij char *locp = loclstr; 104a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij size_t nconv; 105a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij size_t convlen = loclen * 2; /* UCS-2 is 16 bit wide */ 106a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij size_t convmax = PTP_MAXSTRLEN*3; 107a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij 108a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij for (i=0;i<loclen;i++) { 109a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij string[i]=dtoh16a(&data[offset+i*2+1]); 110eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 111a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij /* be paranoid! Add a terminator. :( */ 112a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij string[loclen]=0x0000U; 113a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij loclstr[0]='\0'; 114a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij /* loclstr=ucs2_to_utf8(string); */ 115a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij /* Do the conversion. */ 116a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij nconv = iconv (params->cd_ucs2_to_locale, &stringp, &convlen, &locp, &convmax); 117a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij /* FIXME: handle size errors */ 118a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij loclstr[PTP_MAXSTRLEN*3] = '\0'; 119a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij if (nconv == (size_t) -1) 120a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij return NULL; 121a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij return strdup(loclstr); 122eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 123a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij return NULL; 124a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij} 125a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij 126a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij 127a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleijstatic inline int 128a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleijucs2strlen(uint16_t const * const unicstr) 129a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij{ 130a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij int length; 131a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij 132a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij /* Unicode strings are terminated with 2 * 0x00 */ 133a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij for(length = 0; unicstr[length] != 0x0000U; length ++); 134a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij return length; 135eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 136eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 137a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij 138b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 139b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_pack_string(PTPParams *params, char *string, unsigned char* data, uint16_t offset, uint8_t *len) 140eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 141eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij int i; 142a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij int packedlen; 143a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij uint16_t ucs2str[PTP_MAXSTRLEN+1]; 144a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij char *ucs2strp = (char *) ucs2str; 145a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij char *stringp = string; 146a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij size_t nconv; 147a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij size_t convlen = strlen(string); 148a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij size_t convmax = PTP_MAXSTRLEN * 2; /* Includes the terminator */ 149a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij 150a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij /* Cannot exceed 255 (PTP_MAXSTRLEN) since it is a single byte, duh ... */ 151a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij ucs2str[0] = 0x0000U; 152a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij memset(ucs2strp, 0, PTP_MAXSTRLEN*2+2); 153a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij nconv = iconv (params->cd_locale_to_ucs2, &stringp, &convlen, &ucs2strp, &convmax); 154a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij if (nconv == (size_t) -1) { 155a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij ucs2str[0] = 0x0000U; 156a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij } 157a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij packedlen = ucs2strlen(ucs2str); 158a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij if (packedlen > PTP_MAXSTRLEN-1) { 159a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij *len=0; 160a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij return; 161a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij } 162a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij *len = (uint8_t) packedlen; 163a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij 164a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij /* +1 for the length byte, no zero 0x0000 terminator */ 165a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij htod8a(&data[offset],packedlen+1); 166a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij for (i=0;i<packedlen && i< PTP_MAXSTRLEN; i++) { 167a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij htod16a(&data[offset+i*2+1],ucs2str[i]); 168eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 169eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 170eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 171a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleijstatic inline unsigned char * 172a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleijptp_get_packed_stringcopy(PTPParams *params, char *string) 173a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij{ 174a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij uint8_t packed[PTP_MAXSTRLEN+3], len; 175a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij size_t plen; 176a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij unsigned char *retcopy = NULL; 177a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij 178a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij ptp_pack_string(params, string, (unsigned char*) packed, 0, &len); 179a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij plen = len + 1; 180a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij /* Assure proper termination */ 181a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij packed[plen] = 0x00; 182a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij packed[plen+1] = 0x00; 183a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij /* Include terminator */ 184a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij plen += 2; 185a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij retcopy = malloc(plen); 186a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij if (!retcopy) 187a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij return NULL; 188a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij memcpy(retcopy, packed, plen); 189a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij return (retcopy); 190a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij} 191a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij 192b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint32_t 193b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_uint32_t_array(PTPParams *params, unsigned char* data, uint16_t offset, uint32_t **array) 194eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 195eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint32_t n, i=0; 196eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 197eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij n=dtoh32a(&data[offset]); 198eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij *array = malloc (n*sizeof(uint32_t)); 199eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij while (n>i) { 200eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij (*array)[i]=dtoh32a(&data[offset+(sizeof(uint32_t)*(i+1))]); 201eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij i++; 202eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 203eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return n; 204eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 205eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 206b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint32_t 207f67bca9bde733f456ad341c0d852147124ab388aLinus Walleijptp_pack_uint32_t_array(PTPParams *params, uint32_t *array, uint32_t arraylen, unsigned char **data ) 208f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij{ 209f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij uint32_t i=0; 210f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij 211f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij *data = malloc ((arraylen+1)*sizeof(uint32_t)); 212f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij htod32a(&(*data)[0],arraylen); 213f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij for (i=0;i<arraylen;i++) 214f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij htod32a(&(*data)[sizeof(uint32_t)*(i+1)], array[i]); 215f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij return (arraylen+1)*sizeof(uint32_t); 216f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij} 217f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij 218f67bca9bde733f456ad341c0d852147124ab388aLinus Walleijstatic inline uint32_t 219b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_uint16_t_array(PTPParams *params, unsigned char* data, uint16_t offset, uint16_t **array) 220eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 221eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint32_t n, i=0; 222eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 223eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij n=dtoh32a(&data[offset]); 224eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij *array = malloc (n*sizeof(uint16_t)); 225eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij while (n>i) { 226eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij (*array)[i]=dtoh16a(&data[offset+(sizeof(uint16_t)*(i+2))]); 227eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij i++; 228eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 229eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return n; 230eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 231eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 232eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* DeviceInfo pack/unpack */ 233eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 234eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_di_StandardVersion 0 235eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_di_VendorExtensionID 2 236eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_di_VendorExtensionVersion 6 237eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_di_VendorExtensionDesc 8 238eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_di_FunctionalMode 8 239eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_di_OperationsSupported 10 240eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 241b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 242b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_DI (PTPParams *params, unsigned char* data, PTPDeviceInfo *di, unsigned int datalen) 243eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 244eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint8_t len; 245eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij unsigned int totallen; 246eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 247eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->StaqndardVersion = dtoh16a(&data[PTP_di_StandardVersion]); 248eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->VendorExtensionID = 249eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij dtoh32a(&data[PTP_di_VendorExtensionID]); 250eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->VendorExtensionVersion = 251eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij dtoh16a(&data[PTP_di_VendorExtensionVersion]); 252eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->VendorExtensionDesc = 253eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij ptp_unpack_string(params, data, 254eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_VendorExtensionDesc, &len); 255eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen=len*2+1; 256eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->FunctionalMode = 257eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij dtoh16a(&data[PTP_di_FunctionalMode+totallen]); 258eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->OperationsSupported_len = ptp_unpack_uint16_t_array(params, data, 259eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 260eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &di->OperationsSupported); 261eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen=totallen+di->OperationsSupported_len*sizeof(uint16_t)+sizeof(uint32_t); 262eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->EventsSupported_len = ptp_unpack_uint16_t_array(params, data, 263eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 264eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &di->EventsSupported); 265eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen=totallen+di->EventsSupported_len*sizeof(uint16_t)+sizeof(uint32_t); 266eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->DevicePropertiesSupported_len = 267eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij ptp_unpack_uint16_t_array(params, data, 268eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 269eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &di->DevicePropertiesSupported); 270eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen=totallen+di->DevicePropertiesSupported_len*sizeof(uint16_t)+sizeof(uint32_t); 271eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->CaptureFormats_len = ptp_unpack_uint16_t_array(params, data, 272eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 273eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &di->CaptureFormats); 274eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen=totallen+di->CaptureFormats_len*sizeof(uint16_t)+sizeof(uint32_t); 275eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->ImageFormats_len = ptp_unpack_uint16_t_array(params, data, 276eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 277eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &di->ImageFormats); 278eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen=totallen+di->ImageFormats_len*sizeof(uint16_t)+sizeof(uint32_t); 279eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->Manufacturer = ptp_unpack_string(params, data, 280eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 281eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &len); 282eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen+=len*2+1; 283eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->Model = ptp_unpack_string(params, data, 284eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 285eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &len); 286eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen+=len*2+1; 287eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->DeviceVersion = ptp_unpack_string(params, data, 288eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 289eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &len); 290eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen+=len*2+1; 291eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->SerialNumber = ptp_unpack_string(params, data, 292eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 293eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &len); 294eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 295eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 296eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* ObjectHandles array pack/unpack */ 297eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 298eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oh 0 299eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 300b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 301b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_OH (PTPParams *params, unsigned char* data, PTPObjectHandles *oh, unsigned int len) 302eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 303eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oh->n = ptp_unpack_uint32_t_array(params, data, PTP_oh, &oh->Handler); 304eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 305eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 306eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* StoreIDs array pack/unpack */ 307eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 308eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_sids 0 309eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 310b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 311b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_SIDs (PTPParams *params, unsigned char* data, PTPStorageIDs *sids, unsigned int len) 312eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 313eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij sids->n = ptp_unpack_uint32_t_array(params, data, PTP_sids, 314eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &sids->Storage); 315eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 316eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 317eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* StorageInfo pack/unpack */ 318eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 319eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_si_StorageType 0 320eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_si_FilesystemType 2 321eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_si_AccessCapability 4 322eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_si_MaxCapability 6 323eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_si_FreeSpaceInBytes 14 324eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_si_FreeSpaceInImages 22 325eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_si_StorageDescription 26 326eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 327b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 328b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_SI (PTPParams *params, unsigned char* data, PTPStorageInfo *si, unsigned int len) 329eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 330eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint8_t storagedescriptionlen; 331eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 332eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->StorageType=dtoh16a(&data[PTP_si_StorageType]); 333eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->FilesystemType=dtoh16a(&data[PTP_si_FilesystemType]); 334eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->AccessCapability=dtoh16a(&data[PTP_si_AccessCapability]); 335eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->MaxCapability=dtoh64a(&data[PTP_si_MaxCapability]); 336eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->FreeSpaceInBytes=dtoh64a(&data[PTP_si_FreeSpaceInBytes]); 337eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->FreeSpaceInImages=dtoh32a(&data[PTP_si_FreeSpaceInImages]); 338eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->StorageDescription=ptp_unpack_string(params, data, 339eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_si_StorageDescription, &storagedescriptionlen); 340eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->VolumeLabel=ptp_unpack_string(params, data, 341eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_si_StorageDescription+storagedescriptionlen*2+1, 342eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &storagedescriptionlen); 343eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 344eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 345eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* ObjectInfo pack/unpack */ 346eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 347eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_StorageID 0 348eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ObjectFormat 4 349eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ProtectionStatus 6 350eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ObjectCompressedSize 8 351eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ThumbFormat 12 352eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ThumbCompressedSize 14 353eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ThumbPixWidth 18 354eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ThumbPixHeight 22 355eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ImagePixWidth 26 356eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ImagePixHeight 30 357eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ImageBitDepth 34 358eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ParentObject 38 359eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_AssociationType 42 360eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_AssociationDesc 44 361eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_SequenceNumber 48 362eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_filenamelen 52 363eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_Filename 53 364eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 365b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint32_t 366b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_pack_OI (PTPParams *params, PTPObjectInfo *oi, unsigned char** oidataptr) 367eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 368b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij unsigned char* oidata; 369eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint8_t filenamelen; 370eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint8_t capturedatelen=0; 371eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij /* let's allocate some memory first; XXX i'm sure it's wrong */ 372eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oidata=malloc(PTP_oi_Filename+(strlen(oi->Filename)+1)*2+4); 373eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij /* the caller should free it after use! */ 374eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#if 0 375eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij char *capture_date="20020101T010101"; /* XXX Fake date */ 376eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#endif 377eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij memset (oidata, 0, (PTP_oi_Filename+(strlen(oi->Filename)+1)*2+4)); 378eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_StorageID],oi->StorageID); 379eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod16a(&oidata[PTP_oi_ObjectFormat],oi->ObjectFormat); 380eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod16a(&oidata[PTP_oi_ProtectionStatus],oi->ProtectionStatus); 381eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ObjectCompressedSize],oi->ObjectCompressedSize); 382eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod16a(&oidata[PTP_oi_ThumbFormat],oi->ThumbFormat); 383eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ThumbCompressedSize],oi->ThumbCompressedSize); 384eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ThumbPixWidth],oi->ThumbPixWidth); 385eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ThumbPixHeight],oi->ThumbPixHeight); 386eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ImagePixWidth],oi->ImagePixWidth); 387eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ImagePixHeight],oi->ImagePixHeight); 388eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ImageBitDepth],oi->ImageBitDepth); 389eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ParentObject],oi->ParentObject); 390eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod16a(&oidata[PTP_oi_AssociationType],oi->AssociationType); 391eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_AssociationDesc],oi->AssociationDesc); 392eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_SequenceNumber],oi->SequenceNumber); 393eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 394eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij ptp_pack_string(params, oi->Filename, oidata, PTP_oi_filenamelen, &filenamelen); 395eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* 396eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij filenamelen=(uint8_t)strlen(oi->Filename); 397eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod8a(&req->data[PTP_oi_filenamelen],filenamelen+1); 398eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij for (i=0;i<filenamelen && i< PTP_MAXSTRLEN; i++) { 399eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij req->data[PTP_oi_Filename+i*2]=oi->Filename[i]; 400eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 401eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij*/ 402eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij /* 403eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij *XXX Fake date. 404eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij * for example Kodak sets Capture date on the basis of EXIF data. 405eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij * Spec says that this field is from perspective of Initiator. 406eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij */ 407eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#if 0 /* seems now we don't need any data packed in OI dataset... for now ;)*/ 408eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij capturedatelen=strlen(capture_date); 409eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod8a(&data[PTP_oi_Filename+(filenamelen+1)*2], 410eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij capturedatelen+1); 411eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij for (i=0;i<capturedatelen && i< PTP_MAXSTRLEN; i++) { 412eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij data[PTP_oi_Filename+(i+filenamelen+1)*2+1]=capture_date[i]; 413eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 414eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod8a(&data[PTP_oi_Filename+(filenamelen+capturedatelen+2)*2+1], 415eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij capturedatelen+1); 416eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij for (i=0;i<capturedatelen && i< PTP_MAXSTRLEN; i++) { 417eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij data[PTP_oi_Filename+(i+filenamelen+capturedatelen+2)*2+2]= 418eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij capture_date[i]; 419eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 420eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#endif 421eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij /* XXX this function should return dataset length */ 422eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 423eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij *oidataptr=oidata; 424eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return (PTP_oi_Filename+(filenamelen+1)*2+(capturedatelen+1)*4); 425eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 426eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 427b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 428b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_OI (PTPParams *params, unsigned char* data, PTPObjectInfo *oi, unsigned int len) 429eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 430eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint8_t filenamelen; 431eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint8_t capturedatelen; 432eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij char *capture_date; 433eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij char tmp[16]; 434eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij struct tm tm; 435eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 436eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij memset(&tm,0,sizeof(tm)); 437eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 438eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->StorageID=dtoh32a(&data[PTP_oi_StorageID]); 439eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ObjectFormat=dtoh16a(&data[PTP_oi_ObjectFormat]); 440eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ProtectionStatus=dtoh16a(&data[PTP_oi_ProtectionStatus]); 441eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ObjectCompressedSize=dtoh32a(&data[PTP_oi_ObjectCompressedSize]); 442eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ThumbFormat=dtoh16a(&data[PTP_oi_ThumbFormat]); 443eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ThumbCompressedSize=dtoh32a(&data[PTP_oi_ThumbCompressedSize]); 444eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ThumbPixWidth=dtoh32a(&data[PTP_oi_ThumbPixWidth]); 445eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ThumbPixHeight=dtoh32a(&data[PTP_oi_ThumbPixHeight]); 446eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ImagePixWidth=dtoh32a(&data[PTP_oi_ImagePixWidth]); 447eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ImagePixHeight=dtoh32a(&data[PTP_oi_ImagePixHeight]); 448eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ImageBitDepth=dtoh32a(&data[PTP_oi_ImageBitDepth]); 449eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ParentObject=dtoh32a(&data[PTP_oi_ParentObject]); 450eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->AssociationType=dtoh16a(&data[PTP_oi_AssociationType]); 451eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->AssociationDesc=dtoh32a(&data[PTP_oi_AssociationDesc]); 452eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->SequenceNumber=dtoh32a(&data[PTP_oi_SequenceNumber]); 453eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->Filename= ptp_unpack_string(params, data, PTP_oi_filenamelen, &filenamelen); 454eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 455eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij capture_date = ptp_unpack_string(params, data, 456eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_oi_filenamelen+filenamelen*2+1, &capturedatelen); 457eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij /* subset of ISO 8601, without '.s' tenths of second and 458eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij * time zone 459eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij */ 460eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij if (capturedatelen>15) 461eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij { 462eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij strncpy (tmp, capture_date, 4); 463eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tmp[4] = 0; 464eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tm.tm_year=atoi (tmp) - 1900; 465eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij strncpy (tmp, capture_date + 4, 2); 466eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tmp[2] = 0; 467eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tm.tm_mon = atoi (tmp) - 1; 468eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij strncpy (tmp, capture_date + 6, 2); 469eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tmp[2] = 0; 470eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tm.tm_mday = atoi (tmp); 471eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij strncpy (tmp, capture_date + 9, 2); 472eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tmp[2] = 0; 473eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tm.tm_hour = atoi (tmp); 474eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij strncpy (tmp, capture_date + 11, 2); 475eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tmp[2] = 0; 476eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tm.tm_min = atoi (tmp); 477eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij strncpy (tmp, capture_date + 13, 2); 478eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tmp[2] = 0; 479eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tm.tm_sec = atoi (tmp); 480eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->CaptureDate=mktime (&tm); 481eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 482eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij free(capture_date); 483eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 484eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij /* now it's modification date ;) */ 485eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij capture_date = ptp_unpack_string(params, data, 486eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_oi_filenamelen+filenamelen*2 487eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij +capturedatelen*2+2,&capturedatelen); 488eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij if (capturedatelen>15) 489eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij { 490eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij strncpy (tmp, capture_date, 4); 491eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tmp[4] = 0; 492eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tm.tm_year=atoi (tmp) - 1900; 493eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij strncpy (tmp, capture_date + 4, 2); 494eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tmp[2] = 0; 495eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tm.tm_mon = atoi (tmp) - 1; 496eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij strncpy (tmp, capture_date + 6, 2); 497eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tmp[2] = 0; 498eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tm.tm_mday = atoi (tmp); 499eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij strncpy (tmp, capture_date + 9, 2); 500eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tmp[2] = 0; 501eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tm.tm_hour = atoi (tmp); 502eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij strncpy (tmp, capture_date + 11, 2); 503eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tmp[2] = 0; 504eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tm.tm_min = atoi (tmp); 505eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij strncpy (tmp, capture_date + 13, 2); 506eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tmp[2] = 0; 507eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij tm.tm_sec = atoi (tmp); 508eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ModificationDate=mktime (&tm); 509eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 510eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij free(capture_date); 511eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 512eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 513eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* Custom Type Value Assignement (without Length) macro frequently used below */ 514b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define CTVAL(target,func) { \ 515b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (total - *offset < sizeof(target)) \ 516b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 0; \ 517b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij target = func(&data[*offset]); \ 518b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij *offset += sizeof(target); \ 519eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 520eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 521b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define RARR(val,member,func) { \ 522b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij int n,j; \ 523b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (total - *offset < sizeof(uint32_t)) \ 524b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 0; \ 525b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij n = dtoh32a (&data[*offset]); \ 526b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij *offset += sizeof(uint32_t); \ 527b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij \ 528b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij val->a.count = n; \ 529b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij val->a.v = malloc(sizeof(val->a.v[0])*n); \ 530b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!val->a.v) return 0; \ 531b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (j=0;j<n;j++) \ 532b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij CTVAL(val->a.v[j].member, func); \ 533b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij} 534eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 535b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline int 536b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_DPV ( 537b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij PTPParams *params, unsigned char* data, int *offset, int total, 538b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij PTPPropertyValue* value, uint16_t datatype 539b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij) { 540eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij switch (datatype) { 541b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_INT8: 542b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij CTVAL(value->i8,dtoh8a); 543b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 544b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_UINT8: 545b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij CTVAL(value->u8,dtoh8a); 546b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 547b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_INT16: 548b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij CTVAL(value->i16,dtoh16a); 549b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 550b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_UINT16: 551b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij CTVAL(value->u16,dtoh16a); 552b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 553b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_INT32: 554b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij CTVAL(value->i32,dtoh32a); 555b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 556b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_UINT32: 557b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij CTVAL(value->u32,dtoh32a); 558b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 559b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AINT8: 560b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij RARR(value,i8,dtoh8a); 561b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 562b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AUINT8: 563b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij RARR(value,u8,dtoh8a); 564b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 565b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AUINT16: 566b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij RARR(value,u16,dtoh16a); 567b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 568b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AINT16: 569b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij RARR(value,i16,dtoh16a); 570b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 571b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AUINT32: 572b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij RARR(value,u32,dtoh32a); 573b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 574b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AINT32: 575b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij RARR(value,i32,dtoh32a); 576b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 577b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij /* XXX: other int types are unimplemented */ 578b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij /* XXX: other int arrays are unimplemented also */ 579b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_STR: { 580b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij uint8_t len; 581b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij /* XXX: max size */ 582b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij value->str = ptp_unpack_string(params,data,*offset,&len); 583b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij *offset += len*2+1; 584b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!value->str) 585eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return 0; 586b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 587eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 588b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 589b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 1; 590eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 591eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 592eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* Device Property pack/unpack */ 593eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 594eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_dpd_DevicePropertyCode 0 595eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_dpd_DataType 2 596eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_dpd_GetSet 4 597eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_dpd_FactoryDefaultValue 5 598eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 599b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline int 600b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_DPD (PTPParams *params, unsigned char* data, PTPDevicePropDesc *dpd, unsigned int dpdlen) 601eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 602b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij int offset=0, ret; 603eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 604b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij memset (dpd, 0, sizeof(*dpd)); 605eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij dpd->DevicePropertyCode=dtoh16a(&data[PTP_dpd_DevicePropertyCode]); 606eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij dpd->DataType=dtoh16a(&data[PTP_dpd_DataType]); 607eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij dpd->GetSet=dtoh8a(&data[PTP_dpd_GetSet]); 608b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 609b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij offset = PTP_dpd_FactoryDefaultValue; 610b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->FactoryDefaultValue, dpd->DataType); 611b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 612b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->CurrentValue, dpd->DataType); 613b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 614b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 615b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij /* if offset==0 then Data Type format is not supported by this 616b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij code or the Data Type is a string (with two empty strings as 617b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij values). In both cases Form Flag should be set to 0x00 and FORM is 618b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij not present. */ 619b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 620eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij dpd->FormFlag=PTP_DPFF_None; 621b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (offset==PTP_dpd_FactoryDefaultValue) 622b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 1; 623b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 624b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpd->FormFlag=dtoh8a(&data[offset]); 625b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij offset+=sizeof(uint8_t); 626eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 627eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij switch (dpd->FormFlag) { 628b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DPFF_Range: 629b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->FORM.Range.MinimumValue, dpd->DataType); 630b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 631b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->FORM.Range.MaximumValue, dpd->DataType); 632b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 633b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->FORM.Range.StepSize, dpd->DataType); 634b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 635eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij break; 636b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DPFF_Enumeration: { 637b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij int i; 638eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define N dpd->FORM.Enum.NumberOfValues 639b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij N = dtoh16a(&data[offset]); 640b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij offset+=sizeof(uint16_t); 641b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpd->FORM.Enum.SupportedValue = malloc(N*sizeof(dpd->FORM.Enum.SupportedValue[0])); 642b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!dpd->FORM.Enum.SupportedValue) 643b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij goto outofmemory; 644b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 645b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij memset (dpd->FORM.Enum.SupportedValue,0 , N*sizeof(dpd->FORM.Enum.SupportedValue[0])); 646b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<N;i++) { 647b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->FORM.Enum.SupportedValue[i], dpd->DataType); 648b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 649b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij /* Slightly different handling here. The HP PhotoSmart 120 650b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij * specifies an enumeration with N in wrong endian 651b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij * 00 01 instead of 01 00, so we count the enum just until the 652b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij * the end of the packet. 653b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij */ 654b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) { 655b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!i) 656b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij goto outofmemory; 657b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpd->FORM.Enum.NumberOfValues = i; 658b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 659eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 660b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 661eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 662eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 663b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#undef N 664b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 1; 665b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijoutofmemory: 666b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ptp_free_devicepropdesc(dpd); 667b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 0; 668eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 669eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 670b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij/* (MTP) Object Property pack/unpack */ 671b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_opd_ObjectPropertyCode 0 672b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_opd_DataType 2 673b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_opd_GetSet 4 674b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_opd_FactoryDefaultValue 5 675eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 676b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline int 677b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_OPD (PTPParams *params, unsigned char* data, PTPObjectPropDesc *opd, unsigned int opdlen) 678eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 679b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij int offset=0, ret; 680b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 681b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij memset (opd, 0, sizeof(*opd)); 682b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij opd->ObjectPropertyCode=dtoh16a(&data[PTP_opd_ObjectPropertyCode]); 683b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij opd->DataType=dtoh16a(&data[PTP_opd_DataType]); 684b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij opd->GetSet=dtoh8a(&data[PTP_opd_GetSet]); 685b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 686b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij offset = PTP_opd_FactoryDefaultValue; 687b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, opdlen, &opd->FactoryDefaultValue, opd->DataType); 688b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 689b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 690b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij opd->GroupCode=dtoh32a(&data[offset]); 691b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij offset+=sizeof(uint32_t); 692b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 693b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij opd->FormFlag=dtoh8a(&data[offset]); 694b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij offset+=sizeof(uint8_t); 695b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 696b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij switch (opd->FormFlag) { 697b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_OPFF_Range: 698b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, opdlen, &opd->FORM.Range.MinimumValue, opd->DataType); 699b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 700b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, opdlen, &opd->FORM.Range.MaximumValue, opd->DataType); 701b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 702b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, opdlen, &opd->FORM.Range.StepSize, opd->DataType); 703b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 704b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 705b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_OPFF_Enumeration: { 706b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij int i; 707b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define N opd->FORM.Enum.NumberOfValues 708b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij N = dtoh16a(&data[offset]); 709b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij offset+=sizeof(uint16_t); 710b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij opd->FORM.Enum.SupportedValue = malloc(N*sizeof(opd->FORM.Enum.SupportedValue[0])); 711b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!opd->FORM.Enum.SupportedValue) 712b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij goto outofmemory; 713b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 714b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij memset (opd->FORM.Enum.SupportedValue,0 , N*sizeof(opd->FORM.Enum.SupportedValue[0])); 715b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<N;i++) { 716b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, opdlen, &opd->FORM.Enum.SupportedValue[i], opd->DataType); 717b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 718b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij /* Slightly different handling here. The HP PhotoSmart 120 719b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij * specifies an enumeration with N in wrong endian 720b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij * 00 01 instead of 01 00, so we count the enum just until the 721b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij * the end of the packet. 722b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij */ 723b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) { 724b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!i) 725b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij goto outofmemory; 726b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij opd->FORM.Enum.NumberOfValues = i; 727b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 728b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 729b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 730b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#undef N 731b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 732eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 733b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 1; 734b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijoutofmemory: 735b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ptp_free_objectpropdesc(opd); 736b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 0; 737eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 738eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 739eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 740b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint32_t 741b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_pack_DPV (PTPParams *params, PTPPropertyValue* value, unsigned char** dpvptr, uint16_t datatype) 742eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 743b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij unsigned char* dpv=NULL; 744eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint32_t size=0; 745b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij int i; 746eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 747eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij switch (datatype) { 748b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_INT8: 749b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(int8_t); 750b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 751b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod8a(dpv,value->i8); 752b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 753b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_UINT8: 754b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint8_t); 755b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 756b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod8a(dpv,value->u8); 757b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 758b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_INT16: 759b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(int16_t); 760b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 761b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(dpv,value->i16); 762b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 763b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_UINT16: 764b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint16_t); 765b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 766b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(dpv,value->u16); 767b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 768b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_INT32: 769b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(int32_t); 770b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 771b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(dpv,value->i32); 772b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 773b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_UINT32: 774b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint32_t); 775b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 776b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(dpv,value->u32); 777b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 778b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AUINT8: 779b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint32_t)+value->a.count*sizeof(uint8_t); 780b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 781b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(dpv,value->a.count); 782b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<value->a.count;i++) 783b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod8a(&dpv[4+i],value->a.v[i].u8); 784b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 785b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AINT8: 786b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint32_t)+value->a.count*sizeof(int8_t); 787b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 788b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(dpv,value->a.count); 789b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<value->a.count;i++) 790b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod8a(&dpv[4+i],value->a.v[i].i8); 791b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 792b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AUINT16: 793b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint32_t)+value->a.count*sizeof(uint16_t); 794b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 795b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(dpv,value->a.count); 796b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<value->a.count;i++) 797b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(&dpv[4+i],value->a.v[i].u16); 798b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 799b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AINT16: 800b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint32_t)+value->a.count*sizeof(int16_t); 801b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 802b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(dpv,value->a.count); 803b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<value->a.count;i++) 804b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(&dpv[4+i],value->a.v[i].i16); 805b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 806b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AUINT32: 807b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint32_t)+value->a.count*sizeof(uint32_t); 808b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 809b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(dpv,value->a.count); 810b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<value->a.count;i++) 811b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(&dpv[4+i],value->a.v[i].u32); 812b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 813b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AINT32: 814b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint32_t)+value->a.count*sizeof(int32_t); 815b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 816b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(dpv,value->a.count); 817b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<value->a.count;i++) 818b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(&dpv[4+i],value->a.v[i].i32); 819b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 820b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij /* XXX: other int types are unimplemented */ 821b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_STR: { 822a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij dpv=ptp_get_packed_stringcopy(params, value->str); 823eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij break; 824b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 825eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 826eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij *dpvptr=dpv; 827eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return size; 828eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 829eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 830eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* 831eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP USB Event container unpack 832eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij Copyright (c) 2003 Nikolai Kopanygin 833eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij*/ 834eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 835eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_ec_Length 0 836eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_ec_Type 4 837eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_ec_Code 6 838eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_ec_TransId 8 839eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_ec_Param1 12 840eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_ec_Param2 16 841eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_ec_Param3 20 842eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 843b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 844b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_EC (PTPParams *params, unsigned char* data, PTPUSBEventContainer *ec, unsigned int len) 845eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 846eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij if (data==NULL) 847eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return; 848eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij ec->length=dtoh32a(&data[PTP_ec_Length]); 849eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij ec->type=dtoh16a(&data[PTP_ec_Type]); 850eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij ec->code=dtoh16a(&data[PTP_ec_Code]); 851eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij ec->trans_id=dtoh32a(&data[PTP_ec_TransId]); 852b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 853eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij if (ec->length>=(PTP_ec_Param1+4)) 854eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij ec->param1=dtoh32a(&data[PTP_ec_Param1]); 855eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij else 856eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij ec->param1=0; 857eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij if (ec->length>=(PTP_ec_Param2+4)) 858eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij ec->param2=dtoh32a(&data[PTP_ec_Param2]); 859eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij else 860eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij ec->param2=0; 861eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij if (ec->length>=(PTP_ec_Param3+4)) 862eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij ec->param3=dtoh32a(&data[PTP_ec_Param3]); 863eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij else 864eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij ec->param3=0; 865eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 866eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 867eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* 868eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP Canon Folder Entry unpack 869eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij Copyright (c) 2003 Nikolai Kopanygin 870eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij*/ 871eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_cfe_ObjectHandle 0 872eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_cfe_ObjectFormatCode 4 873eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_cfe_Flags 6 874eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_cfe_ObjectSize 7 875eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_cfe_Time 11 876eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_cfe_Filename 15 877eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 878b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 879b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_Canon_FE (PTPParams *params, unsigned char* data, PTPCANONFolderEntry *fe) 880eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 881eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij int i; 882eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij if (data==NULL) 883eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return; 884eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij fe->ObjectHandle=dtoh32a(&data[PTP_cfe_ObjectHandle]); 885eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij fe->ObjectFormatCode=dtoh16a(&data[PTP_cfe_ObjectFormatCode]); 886eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij fe->Flags=dtoh8a(&data[PTP_cfe_Flags]); 887b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij fe->ObjectSize=dtoh32a((unsigned char*)&data[PTP_cfe_ObjectSize]); 888eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij fe->Time=(time_t)dtoh32a(&data[PTP_cfe_Time]); 889eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij for (i=0; i<PTP_CANON_FilenameBufferLen; i++) 890b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij fe->Filename[i]=(char)dtoh8a(&data[PTP_cfe_Filename+i]); 891b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij} 892b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 893b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij/* 894b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij PTP USB Event container unpack for Nikon events. 895b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij*/ 896b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_nikon_ec_Length 0 897b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_nikon_ec_Code 2 898b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_nikon_ec_Param1 4 899b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_nikon_ec_Size 6 900b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 901b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_Nikon_EC (PTPParams *params, unsigned char* data, unsigned int len, PTPUSBEventContainer **ec, int *cnt) 902b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij{ 903b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij int i; 904b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 905b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij *ec = NULL; 906b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (data == NULL) 907b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return; 908b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (len < PTP_nikon_ec_Code) 909b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return; 910b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij *cnt = dtoh16a(&data[PTP_nikon_ec_Length]); 911b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (*cnt > (len-PTP_nikon_ec_Code)/PTP_nikon_ec_Size) /* broken cnt? */ 912b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return; 913b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij *ec = malloc(sizeof(PTPUSBEventContainer)*(*cnt)); 914b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 915b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<*cnt;i++) { 916b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij memset(&(*ec)[i],0,sizeof(PTPUSBEventContainer)); 917b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij (*ec)[i].code = dtoh16a(&data[PTP_nikon_ec_Code+PTP_nikon_ec_Size*i]); 918b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij (*ec)[i].param1 = dtoh32a(&data[PTP_nikon_ec_Param1+PTP_nikon_ec_Size*i]); 919b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 920eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 921eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 922eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 923b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint32_t 924b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_pack_EK_text(PTPParams *params, PTPEKTextParams *text, unsigned char **data) { 925b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij int i, len = 0; 926b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij uint8_t retlen; 927b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij unsigned char *curdata; 928b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 929b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij len = 2*(strlen(text->title)+1)+1+ 930b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 2*(strlen(text->line[0])+1)+1+ 931b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 2*(strlen(text->line[1])+1)+1+ 932b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 2*(strlen(text->line[2])+1)+1+ 933b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 2*(strlen(text->line[3])+1)+1+ 934b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 2*(strlen(text->line[4])+1)+1+ 935b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 4*2+2*4+2+4+2+5*4*2; 936b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij *data = malloc(len); 937b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!*data) return 0; 938b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 939b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij curdata = *data; 940b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,100);curdata+=2; 941b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,1);curdata+=2; 942b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,0);curdata+=2; 943b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,1000);curdata+=2; 944b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 945b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(curdata,0);curdata+=4; 946b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(curdata,0);curdata+=4; 947b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 948b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,6);curdata+=2; 949b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(curdata,0);curdata+=4; 950b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 951b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ptp_pack_string(params, text->title, curdata, 0, &retlen); curdata+=2*retlen+1;htod16a(curdata,0);curdata+=2; 952b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,0x10);curdata+=2; 953b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 954b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<5;i++) { 955b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ptp_pack_string(params, text->line[i], curdata, 0, &retlen); curdata+=2*retlen+1;htod16a(curdata,0);curdata+=2; 956b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,0x10);curdata+=2; 957b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,0x01);curdata+=2; 958b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,0x02);curdata+=2; 959b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,0x06);curdata+=2; 960b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 961b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return len; 962b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij} 963