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