blob: 231eb54cab10be85ca212dd19ab937af1175b83d [file] [log] [blame]
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001/* ptp.c
2 *
Linus Walleijb02a0662006-04-25 08:05:09 +00003 * Copyright (C) 2001-2004 Mariusz Woloszyn <emsi@ipartners.pl>
4 * Copyright (C) 2003-2006 Marcus Meissner <marcus@jet.franken.de>
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00005 *
Linus Walleijb02a0662006-04-25 08:05:09 +00006 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
Linus Walleijeb8c6fe2006-02-03 09:46:22 +000010 *
Linus Walleijb02a0662006-04-25 08:05:09 +000011 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
Linus Walleijeb8c6fe2006-02-03 09:46:22 +000015 *
Linus Walleijb02a0662006-04-25 08:05:09 +000016 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
Linus Walleijeb8c6fe2006-02-03 09:46:22 +000020 */
21
22#include <config.h>
23#include "ptp.h"
Linus Walleijeb8c6fe2006-02-03 09:46:22 +000024
25#include <stdlib.h>
26#include <stdarg.h>
27#include <stdio.h>
28#include <string.h>
29
30#ifdef ENABLE_NLS
31# include <libintl.h>
32# undef _
33# define _(String) dgettext (PACKAGE, String)
34# ifdef gettext_noop
35# define N_(String) gettext_noop (String)
36# else
37# define N_(String) (String)
38# endif
39#else
40# define textdomain(String) (String)
41# define gettext(String) (String)
42# define dgettext(Domain,Message) (Message)
43# define dcgettext(Domain,Message,Type) (Message)
44# define bindtextdomain(Domain,Directory) (Domain)
45# define _(String) (String)
46# define N_(String) (String)
47#endif
48
Linus Walleijb02a0662006-04-25 08:05:09 +000049#define CHECK_PTP_RC(result) {uint16_t r=(result); if (r!=PTP_RC_OK) return r;}
50
51#define PTP_CNT_INIT(cnt) {memset(&cnt,0,sizeof(cnt));}
Linus Walleijeb8c6fe2006-02-03 09:46:22 +000052
53static void
54ptp_debug (PTPParams *params, const char *format, ...)
55{
56 va_list args;
57
58 va_start (args, format);
59 if (params->debug_func!=NULL)
60 params->debug_func (params->data, format, args);
61 else
62 {
63 vfprintf (stderr, format, args);
64 fprintf (stderr,"\n");
65 fflush (stderr);
66 }
67 va_end (args);
68}
69
70static void
71ptp_error (PTPParams *params, const char *format, ...)
72{
73 va_list args;
74
75 va_start (args, format);
76 if (params->error_func!=NULL)
77 params->error_func (params->data, format, args);
78 else
79 {
80 vfprintf (stderr, format, args);
81 fprintf (stderr,"\n");
82 fflush (stderr);
83 }
84 va_end (args);
85}
86
Linus Walleijb02a0662006-04-25 08:05:09 +000087/* Pack / unpack functions */
88
89#include "ptp-pack.c"
90
Linus Walleijeb8c6fe2006-02-03 09:46:22 +000091/* send / receive functions */
92
93uint16_t
94ptp_usb_sendreq (PTPParams* params, PTPContainer* req)
95{
96 uint16_t ret;
97 PTPUSBBulkContainer usbreq;
98
99 /* build appropriate USB container */
100 usbreq.length=htod32(PTP_USB_BULK_REQ_LEN-
101 (sizeof(uint32_t)*(5-req->Nparam)));
102 usbreq.type=htod16(PTP_USB_CONTAINER_COMMAND);
103 usbreq.code=htod16(req->Code);
104 usbreq.trans_id=htod32(req->Transaction_ID);
105 usbreq.payload.params.param1=htod32(req->Param1);
106 usbreq.payload.params.param2=htod32(req->Param2);
107 usbreq.payload.params.param3=htod32(req->Param3);
108 usbreq.payload.params.param4=htod32(req->Param4);
109 usbreq.payload.params.param5=htod32(req->Param5);
110 /* send it to responder */
111 ret=params->write_func((unsigned char *)&usbreq,
112 PTP_USB_BULK_REQ_LEN-(sizeof(uint32_t)*(5-req->Nparam)),
113 params->data);
114 if (ret!=PTP_RC_OK) {
115 ret = PTP_ERROR_IO;
116/* ptp_error (params,
117 "PTP: request code 0x%04x sending req error 0x%04x",
118 req->Code,ret); */
119 }
120 return ret;
121}
122
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000123uint16_t
124ptp_usb_senddata (PTPParams* params, PTPContainer* ptp,
125 unsigned char *data, unsigned int size)
126{
127 uint16_t ret;
Linus Walleijb02a0662006-04-25 08:05:09 +0000128 int wlen, datawlen;
129 PTPUSBBulkContainer usbdata;
130
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000131 /* build appropriate USB container */
Linus Walleijb02a0662006-04-25 08:05:09 +0000132 usbdata.length = htod32(PTP_USB_BULK_HDR_LEN+size);
133 usbdata.type = htod16(PTP_USB_CONTAINER_DATA);
134 usbdata.code = htod16(ptp->Code);
135 usbdata.trans_id= htod32(ptp->Transaction_ID);
136
137 if (params->split_header_data) {
138 datawlen = 0;
139 wlen = PTP_USB_BULK_HDR_LEN;
140 } else {
141 /* For all camera devices. */
142 datawlen = (size<PTP_USB_BULK_PAYLOAD_LEN)?size:PTP_USB_BULK_PAYLOAD_LEN;
143 wlen = PTP_USB_BULK_HDR_LEN + datawlen;
144 memcpy(usbdata.payload.data, data, datawlen);
145
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000146 }
Linus Walleijb02a0662006-04-25 08:05:09 +0000147 /* send first part of data */
148 ret = params->write_func((unsigned char *)&usbdata, wlen, params->data);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000149 if (ret!=PTP_RC_OK) {
150 ret = PTP_ERROR_IO;
Linus Walleijb02a0662006-04-25 08:05:09 +0000151/* ptp_error (params,
152 "PTP: request code 0x%04x sending data error 0x%04x",
153 ptp->Code,ret);*/
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000154 return ret;
155 }
Linus Walleijb02a0662006-04-25 08:05:09 +0000156 if (size <= datawlen) return ret;
157 /* if everything OK send the rest */
158 ret=params->write_func (data + datawlen, size - datawlen, params->data);
159 if (ret!=PTP_RC_OK) {
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000160 ret = PTP_ERROR_IO;
Linus Walleijb02a0662006-04-25 08:05:09 +0000161/* ptp_error (params,
162 "PTP: request code 0x%04x sending data error 0x%04x",
163 ptp->Code,ret); */
164 }
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000165 return ret;
166}
167
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000168uint16_t
169ptp_usb_getdata (PTPParams* params, PTPContainer* ptp,
Linus Walleijb02a0662006-04-25 08:05:09 +0000170 unsigned char **data, unsigned int *readlen)
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000171{
172 uint16_t ret;
173 PTPUSBBulkContainer usbdata;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000174
175 PTP_CNT_INIT(usbdata);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000176 if (*data!=NULL) return PTP_ERROR_BADPARAM;
Linus Walleijb02a0662006-04-25 08:05:09 +0000177 do {
178 unsigned int len, rlen;
179 /* read the header and potentially the first data */
180 ret=params->read_func((unsigned char *)&usbdata,
181 sizeof(usbdata), params->data, &rlen);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000182 if (ret!=PTP_RC_OK) {
183 ret = PTP_ERROR_IO;
Linus Walleijb02a0662006-04-25 08:05:09 +0000184 break;
185 } else
186 if (dtoh16(usbdata.type)!=PTP_USB_CONTAINER_DATA) {
187 ret = PTP_ERROR_DATA_EXPECTED;
188 break;
189 } else
190 if (dtoh16(usbdata.code)!=ptp->Code) {
191 ret = dtoh16(usbdata.code);
192 break;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000193 }
Linus Walleijc60275a2006-04-30 10:58:11 +0000194 if (rlen > dtoh32(usbdata.length)) {
195 /* I observed this on iRiver MTP devices. -Marcus */
196 ptp_debug (params, "ptp2/ptp_usb_getdata: read %d bytes too much, expect problems!", rlen - dtoh32(usbdata.length)
197 );
198 rlen = dtoh32(usbdata.length);
199 }
Linus Walleijb02a0662006-04-25 08:05:09 +0000200
201 /* For most PTP devices rlen is 512 == sizeof(usbdata)
202 * here. For MTP devices splitting header and data it might
203 * be 12.
204 */
205 /* Evaluate full data length. */
206 len=dtoh32(usbdata.length)-PTP_USB_BULK_HDR_LEN;
207
208 /* autodetect split header/data MTP devices */
209 if (dtoh32(usbdata.length) > 12 && (rlen==12))
210 params->split_header_data = 1;
211
212 /* Allocate memory for data. */
213 *data=calloc(len,1);
214 if (readlen)
215 *readlen = len;
216
217 /* Copy first part of data to 'data' */
218 memcpy(*data,usbdata.payload.data,rlen - PTP_USB_BULK_HDR_LEN);
219
220 /* Is that all of data? */
221 if (len+PTP_USB_BULK_HDR_LEN<=rlen) break;
222
223 /* If not read the rest of it. */
224 ret=params->read_func(((unsigned char *)(*data))+
225 rlen - PTP_USB_BULK_HDR_LEN,
226 len-(rlen - PTP_USB_BULK_HDR_LEN),
227 params->data, &rlen);
228 if (ret!=PTP_RC_OK) {
229 ret = PTP_ERROR_IO;
230 break;
231 }
232 } while (0);
233/*
234 if (ret!=PTP_RC_OK) {
235 ptp_error (params,
236 "PTP: request code 0x%04x getting data error 0x%04x",
237 ptp->Code, ret);
238 }*/
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000239 return ret;
240}
241
242uint16_t
243ptp_usb_getresp (PTPParams* params, PTPContainer* resp)
244{
245 uint16_t ret;
Linus Walleijb02a0662006-04-25 08:05:09 +0000246 unsigned int rlen;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000247 PTPUSBBulkContainer usbresp;
248
249 PTP_CNT_INIT(usbresp);
250 /* read response, it should never be longer than sizeof(usbresp) */
251 ret=params->read_func((unsigned char *)&usbresp,
Linus Walleijb02a0662006-04-25 08:05:09 +0000252 sizeof(usbresp), params->data, &rlen);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000253
254 if (ret!=PTP_RC_OK) {
255 ret = PTP_ERROR_IO;
256 } else
257 if (dtoh16(usbresp.type)!=PTP_USB_CONTAINER_RESPONSE) {
258 ret = PTP_ERROR_RESP_EXPECTED;
259 } else
260 if (dtoh16(usbresp.code)!=resp->Code) {
261 ret = dtoh16(usbresp.code);
262 }
263 if (ret!=PTP_RC_OK) {
264/* ptp_error (params,
265 "PTP: request code 0x%04x getting resp error 0x%04x",
266 resp->Code, ret);*/
267 return ret;
268 }
269 /* build an appropriate PTPContainer */
270 resp->Code=dtoh16(usbresp.code);
271 resp->SessionID=params->session_id;
272 resp->Transaction_ID=dtoh32(usbresp.trans_id);
273 resp->Param1=dtoh32(usbresp.payload.params.param1);
274 resp->Param2=dtoh32(usbresp.payload.params.param2);
275 resp->Param3=dtoh32(usbresp.payload.params.param3);
276 resp->Param4=dtoh32(usbresp.payload.params.param4);
277 resp->Param5=dtoh32(usbresp.payload.params.param5);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000278 return ret;
279}
280
281/* major PTP functions */
282
Linus Walleijb02a0662006-04-25 08:05:09 +0000283/* Transaction data phase description */
284#define PTP_DP_NODATA 0x0000 /* no data phase */
285#define PTP_DP_SENDDATA 0x0001 /* sending data */
286#define PTP_DP_GETDATA 0x0002 /* receiving data */
287#define PTP_DP_DATA_MASK 0x00ff /* data phase mask */
288
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000289/**
290 * ptp_transaction:
291 * params: PTPParams*
292 * PTPContainer* ptp - general ptp container
293 * uint16_t flags - lower 8 bits - data phase description
294 * unsigned int sendlen - senddata phase data length
295 * char** data - send or receive data buffer pointer
Linus Walleijb02a0662006-04-25 08:05:09 +0000296 * int* recvlen - receive data length
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000297 *
298 * Performs PTP transaction. ptp is a PTPContainer with appropriate fields
299 * filled in (i.e. operation code and parameters). It's up to caller to do
300 * so.
301 * The flags decide thether the transaction has a data phase and what is its
302 * direction (send or receive).
303 * If transaction is sending data the sendlen should contain its length in
304 * bytes, otherwise it's ignored.
305 * The data should contain an address of a pointer to data going to be sent
306 * or is filled with such a pointer address if data are received depending
307 * od dataphase direction (send or received) or is beeing ignored (no
308 * dataphase).
309 * The memory for a pointer should be preserved by the caller, if data are
310 * beeing retreived the appropriate amount of memory is beeing allocated
311 * (the caller should handle that!).
312 *
313 * Return values: Some PTP_RC_* code.
314 * Upon success PTPContainer* ptp contains PTP Response Phase container with
315 * all fields filled in.
316 **/
Linus Walleijb02a0662006-04-25 08:05:09 +0000317static uint16_t
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000318ptp_transaction (PTPParams* params, PTPContainer* ptp,
Linus Walleijb02a0662006-04-25 08:05:09 +0000319 uint16_t flags, unsigned int sendlen, unsigned char** data,
320 unsigned int *recvlen)
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000321{
322 if ((params==NULL) || (ptp==NULL))
323 return PTP_ERROR_BADPARAM;
324
325 ptp->Transaction_ID=params->transaction_id++;
326 ptp->SessionID=params->session_id;
327 /* send request */
328 CHECK_PTP_RC(params->sendreq_func (params, ptp));
329 /* is there a dataphase? */
330 switch (flags&PTP_DP_DATA_MASK) {
Linus Walleijb02a0662006-04-25 08:05:09 +0000331 case PTP_DP_SENDDATA:
332 CHECK_PTP_RC(params->senddata_func(params, ptp,
333 *data, sendlen));
334 break;
335 case PTP_DP_GETDATA:
336 CHECK_PTP_RC(params->getdata_func(params, ptp,
337 (unsigned char**)data, recvlen));
338 break;
339 case PTP_DP_NODATA:
340 break;
341 default:
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000342 return PTP_ERROR_BADPARAM;
343 }
344 /* get response */
345 CHECK_PTP_RC(params->getresp_func(params, ptp));
Linus Walleijb02a0662006-04-25 08:05:09 +0000346
347 return ptp->Code;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000348}
349
350/* Enets handling functions */
351
352/* PTP Events wait for or check mode */
353#define PTP_EVENT_CHECK 0x0000 /* waits for */
354#define PTP_EVENT_CHECK_FAST 0x0001 /* checks */
355
356static inline uint16_t
357ptp_usb_event (PTPParams* params, PTPContainer* event, int wait)
358{
359 uint16_t ret;
Linus Walleijb02a0662006-04-25 08:05:09 +0000360 unsigned int rlen;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000361 PTPUSBEventContainer usbevent;
362 PTP_CNT_INIT(usbevent);
363
364 if ((params==NULL) || (event==NULL))
365 return PTP_ERROR_BADPARAM;
366
367 switch(wait) {
368 case PTP_EVENT_CHECK:
369 ret=params->check_int_func((unsigned char*)&usbevent,
Linus Walleijb02a0662006-04-25 08:05:09 +0000370 sizeof(usbevent), params->data, &rlen);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000371 break;
372 case PTP_EVENT_CHECK_FAST:
373 ret=params->check_int_fast_func((unsigned char*)
Linus Walleijb02a0662006-04-25 08:05:09 +0000374 &usbevent, sizeof(usbevent), params->data, &rlen);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000375 break;
376 default:
377 ret=PTP_ERROR_BADPARAM;
378 }
379 if (ret!=PTP_RC_OK) {
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000380 ptp_error (params,
381 "PTP: reading event an error 0x%04x occured", ret);
Linus Walleijb02a0662006-04-25 08:05:09 +0000382 ret = PTP_ERROR_IO;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000383 /* reading event error is nonfatal (for example timeout) */
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000384 }
385 /* if we read anything over interrupt endpoint it must be an event */
386 /* build an appropriate PTPContainer */
387 event->Code=dtoh16(usbevent.code);
388 event->SessionID=params->session_id;
389 event->Transaction_ID=dtoh32(usbevent.trans_id);
390 event->Param1=dtoh32(usbevent.param1);
391 event->Param2=dtoh32(usbevent.param2);
392 event->Param3=dtoh32(usbevent.param3);
393
Linus Walleijb02a0662006-04-25 08:05:09 +0000394 return ret;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000395}
396
397uint16_t
398ptp_usb_event_check (PTPParams* params, PTPContainer* event) {
399
400 return ptp_usb_event (params, event, PTP_EVENT_CHECK_FAST);
401}
402
403uint16_t
404ptp_usb_event_wait (PTPParams* params, PTPContainer* event) {
405
406 return ptp_usb_event (params, event, PTP_EVENT_CHECK);
407}
408
409/**
410 * PTP operation functions
411 *
412 * all ptp_ functions should take integer parameters
413 * in host byte order!
414 **/
415
416
417/**
418 * ptp_getdeviceinfo:
419 * params: PTPParams*
420 *
421 * Gets device info dataset and fills deviceinfo structure.
422 *
423 * Return values: Some PTP_RC_* code.
424 **/
425uint16_t
426ptp_getdeviceinfo (PTPParams* params, PTPDeviceInfo* deviceinfo)
427{
428 uint16_t ret;
Linus Walleijb02a0662006-04-25 08:05:09 +0000429 unsigned int len;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000430 PTPContainer ptp;
Linus Walleijb02a0662006-04-25 08:05:09 +0000431 unsigned char* di=NULL;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000432
433 PTP_CNT_INIT(ptp);
434 ptp.Code=PTP_OC_GetDeviceInfo;
435 ptp.Nparam=0;
Linus Walleijb02a0662006-04-25 08:05:09 +0000436 len=0;
437 ret=ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &di, &len);
438 if (ret == PTP_RC_OK) ptp_unpack_DI(params, di, deviceinfo, len);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000439 free(di);
440 return ret;
441}
442
443
444/**
445 * ptp_opensession:
446 * params: PTPParams*
447 * session - session number
448 *
449 * Establishes a new session.
450 *
451 * Return values: Some PTP_RC_* code.
452 **/
453uint16_t
454ptp_opensession (PTPParams* params, uint32_t session)
455{
456 uint16_t ret;
457 PTPContainer ptp;
458
459 ptp_debug(params,"PTP: Opening session");
460
461 /* SessonID field of the operation dataset should always
462 be set to 0 for OpenSession request! */
463 params->session_id=0x00000000;
464 /* TransactionID should be set to 0 also! */
465 params->transaction_id=0x0000000;
466
467 PTP_CNT_INIT(ptp);
468 ptp.Code=PTP_OC_OpenSession;
469 ptp.Param1=session;
470 ptp.Nparam=1;
Linus Walleijb02a0662006-04-25 08:05:09 +0000471 ret=ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000472 /* now set the global session id to current session number */
473 params->session_id=session;
474 return ret;
475}
476
477/**
478 * ptp_closesession:
479 * params: PTPParams*
480 *
481 * Closes session.
482 *
483 * Return values: Some PTP_RC_* code.
484 **/
485uint16_t
486ptp_closesession (PTPParams* params)
487{
488 PTPContainer ptp;
489
490 ptp_debug(params,"PTP: Closing session");
491
492 PTP_CNT_INIT(ptp);
493 ptp.Code=PTP_OC_CloseSession;
494 ptp.Nparam=0;
Linus Walleijb02a0662006-04-25 08:05:09 +0000495 return ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000496}
497
498/**
499 * ptp_getststorageids:
500 * params: PTPParams*
501 *
Linus Walleijb02a0662006-04-25 08:05:09 +0000502 * Gets array of StorageIDs and fills the storageids structure.
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000503 *
504 * Return values: Some PTP_RC_* code.
505 **/
506uint16_t
507ptp_getstorageids (PTPParams* params, PTPStorageIDs* storageids)
508{
509 uint16_t ret;
510 PTPContainer ptp;
Linus Walleijb02a0662006-04-25 08:05:09 +0000511 unsigned int len;
512 unsigned char* sids=NULL;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000513
514 PTP_CNT_INIT(ptp);
515 ptp.Code=PTP_OC_GetStorageIDs;
516 ptp.Nparam=0;
Linus Walleijb02a0662006-04-25 08:05:09 +0000517 len=0;
518 ret=ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &sids, &len);
519 if (ret == PTP_RC_OK) ptp_unpack_SIDs(params, sids, storageids, len);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000520 free(sids);
521 return ret;
522}
523
524/**
525 * ptp_getststorageinfo:
526 * params: PTPParams*
527 * storageid - StorageID
528 *
529 * Gets StorageInfo dataset of desired storage and fills storageinfo
530 * structure.
531 *
532 * Return values: Some PTP_RC_* code.
533 **/
534uint16_t
535ptp_getstorageinfo (PTPParams* params, uint32_t storageid,
536 PTPStorageInfo* storageinfo)
537{
538 uint16_t ret;
539 PTPContainer ptp;
Linus Walleijb02a0662006-04-25 08:05:09 +0000540 unsigned char* si=NULL;
541 unsigned int len;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000542
543 PTP_CNT_INIT(ptp);
544 ptp.Code=PTP_OC_GetStorageInfo;
545 ptp.Param1=storageid;
546 ptp.Nparam=1;
Linus Walleijb02a0662006-04-25 08:05:09 +0000547 len=0;
548 ret=ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &si, &len);
549 if (ret == PTP_RC_OK) ptp_unpack_SI(params, si, storageinfo, len);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000550 free(si);
551 return ret;
552}
553
554/**
555 * ptp_getobjecthandles:
556 * params: PTPParams*
557 * storage - StorageID
558 * objectformatcode - ObjectFormatCode (optional)
559 * associationOH - ObjectHandle of Association for
560 * wich a list of children is desired
561 * (optional)
562 * objecthandles - pointer to structute
563 *
564 * Fills objecthandles with structure returned by device.
565 *
566 * Return values: Some PTP_RC_* code.
567 **/
568uint16_t
569ptp_getobjecthandles (PTPParams* params, uint32_t storage,
570 uint32_t objectformatcode, uint32_t associationOH,
571 PTPObjectHandles* objecthandles)
572{
573 uint16_t ret;
574 PTPContainer ptp;
Linus Walleijb02a0662006-04-25 08:05:09 +0000575 unsigned char* oh=NULL;
576 unsigned int len;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000577
578 PTP_CNT_INIT(ptp);
579 ptp.Code=PTP_OC_GetObjectHandles;
580 ptp.Param1=storage;
581 ptp.Param2=objectformatcode;
582 ptp.Param3=associationOH;
583 ptp.Nparam=3;
Linus Walleijb02a0662006-04-25 08:05:09 +0000584 len=0;
585 ret=ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &oh, &len);
586 if (ret == PTP_RC_OK) ptp_unpack_OH(params, oh, objecthandles, len);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000587 free(oh);
588 return ret;
589}
590
Linus Walleijb02a0662006-04-25 08:05:09 +0000591/**
592 * ptp_getnumobjects:
593 * params: PTPParams*
594 * storage - StorageID
595 * objectformatcode - ObjectFormatCode (optional)
596 * associationOH - ObjectHandle of Association for
597 * wich a list of children is desired
598 * (optional)
599 * numobs - pointer to uint32_t that takes number of objects
600 *
601 * Fills numobs with number of objects on device.
602 *
603 * Return values: Some PTP_RC_* code.
604 **/
605uint16_t
606ptp_getnumobjects (PTPParams* params, uint32_t storage,
607 uint32_t objectformatcode, uint32_t associationOH,
608 uint32_t* numobs)
609{
610 uint16_t ret;
611 PTPContainer ptp;
612 int len;
613
614 PTP_CNT_INIT(ptp);
615 ptp.Code=PTP_OC_GetObjectHandles;
616 ptp.Param1=storage;
617 ptp.Param2=objectformatcode;
618 ptp.Param3=associationOH;
619 ptp.Nparam=3;
620 len=0;
621 ret=ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL);
622 if (ret == PTP_RC_OK) {
623 if (ptp.Nparam >= 1)
624 *numobs = ptp.Param1;
625 else
626 ret = PTP_RC_GeneralError;
627 }
628 return ret;
629}
630
631/**
632 * ptp_getobjectinfo:
633 * params: PTPParams*
634 * handle - Object handle
635 * objectinfo - pointer to objectinfo that is returned
636 *
637 * Get objectinfo structure for handle from device.
638 *
639 * Return values: Some PTP_RC_* code.
640 **/
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000641uint16_t
642ptp_getobjectinfo (PTPParams* params, uint32_t handle,
643 PTPObjectInfo* objectinfo)
644{
645 uint16_t ret;
646 PTPContainer ptp;
Linus Walleijb02a0662006-04-25 08:05:09 +0000647 unsigned char* oi=NULL;
648 unsigned int len;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000649
650 PTP_CNT_INIT(ptp);
651 ptp.Code=PTP_OC_GetObjectInfo;
652 ptp.Param1=handle;
653 ptp.Nparam=1;
Linus Walleijb02a0662006-04-25 08:05:09 +0000654 len=0;
655 ret=ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &oi, &len);
656 if (ret == PTP_RC_OK) ptp_unpack_OI(params, oi, objectinfo, len);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000657 free(oi);
658 return ret;
659}
660
Linus Walleijb02a0662006-04-25 08:05:09 +0000661/**
662 * ptp_getobject:
663 * params: PTPParams*
664 * handle - Object handle
665 * object - pointer to data area
666 *
667 * Get object 'handle' from device and store the data in newly
668 * allocated 'object'.
669 *
670 * Return values: Some PTP_RC_* code.
671 **/
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000672uint16_t
Linus Walleijb02a0662006-04-25 08:05:09 +0000673ptp_getobject (PTPParams* params, uint32_t handle, unsigned char** object)
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000674{
675 PTPContainer ptp;
Linus Walleijb02a0662006-04-25 08:05:09 +0000676 unsigned int len;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000677
678 PTP_CNT_INIT(ptp);
679 ptp.Code=PTP_OC_GetObject;
680 ptp.Param1=handle;
681 ptp.Nparam=1;
Linus Walleijb02a0662006-04-25 08:05:09 +0000682 len=0;
683 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, object, &len);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000684}
685
Linus Walleijb02a0662006-04-25 08:05:09 +0000686/**
687 * ptp_getpartialobject:
688 * params: PTPParams*
689 * handle - Object handle
690 * offset - Offset into object
691 * maxbytes - Maximum of bytes to read
692 * object - pointer to data area
693 *
694 * Get object 'handle' from device and store the data in newly
695 * allocated 'object'. Start from offset and read at most maxbytes.
696 *
697 * Return values: Some PTP_RC_* code.
698 **/
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000699uint16_t
Linus Walleijb02a0662006-04-25 08:05:09 +0000700ptp_getpartialobject (PTPParams* params, uint32_t handle, uint32_t offset,
701 uint32_t maxbytes, unsigned char** object)
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000702{
703 PTPContainer ptp;
Linus Walleijb02a0662006-04-25 08:05:09 +0000704 unsigned int len;
705
706 PTP_CNT_INIT(ptp);
707 ptp.Code=PTP_OC_GetPartialObject;
708 ptp.Param1=handle;
709 ptp.Param2=offset;
710 ptp.Param3=maxbytes;
711 ptp.Nparam=3;
712 len=0;
713 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, object, &len);
714}
715
716/**
717 * ptp_getthumb:
718 * params: PTPParams*
719 * handle - Object handle
720 * object - pointer to data area
721 *
722 * Get thumb for object 'handle' from device and store the data in newly
723 * allocated 'object'.
724 *
725 * Return values: Some PTP_RC_* code.
726 **/
727uint16_t
728ptp_getthumb (PTPParams* params, uint32_t handle, unsigned char** object)
729{
730 PTPContainer ptp;
731 unsigned int len;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000732
733 PTP_CNT_INIT(ptp);
734 ptp.Code=PTP_OC_GetThumb;
735 ptp.Param1=handle;
736 ptp.Nparam=1;
Linus Walleijb02a0662006-04-25 08:05:09 +0000737 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, object, &len);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000738}
739
740/**
741 * ptp_deleteobject:
742 * params: PTPParams*
743 * handle - object handle
744 * ofc - object format code (optional)
745 *
746 * Deletes desired objects.
747 *
748 * Return values: Some PTP_RC_* code.
749 **/
750uint16_t
Linus Walleijb02a0662006-04-25 08:05:09 +0000751ptp_deleteobject (PTPParams* params, uint32_t handle, uint32_t ofc)
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000752{
753 PTPContainer ptp;
754
755 PTP_CNT_INIT(ptp);
756 ptp.Code=PTP_OC_DeleteObject;
757 ptp.Param1=handle;
758 ptp.Param2=ofc;
759 ptp.Nparam=2;
Linus Walleijb02a0662006-04-25 08:05:09 +0000760 return ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000761}
762
763/**
764 * ptp_sendobjectinfo:
765 * params: PTPParams*
766 * uint32_t* store - destination StorageID on Responder
767 * uint32_t* parenthandle - Parent ObjectHandle on responder
768 * uint32_t* handle - see Return values
769 * PTPObjectInfo* objectinfo- ObjectInfo that is to be sent
770 *
771 * Sends ObjectInfo of file that is to be sent via SendFileObject.
772 *
773 * Return values: Some PTP_RC_* code.
774 * Upon success : uint32_t* store - Responder StorageID in which
775 * object will be stored
776 * uint32_t* parenthandle- Responder Parent ObjectHandle
777 * in which the object will be stored
778 * uint32_t* handle - Responder's reserved ObjectHandle
779 * for the incoming object
780 **/
781uint16_t
782ptp_sendobjectinfo (PTPParams* params, uint32_t* store,
783 uint32_t* parenthandle, uint32_t* handle,
784 PTPObjectInfo* objectinfo)
785{
786 uint16_t ret;
787 PTPContainer ptp;
Linus Walleijb02a0662006-04-25 08:05:09 +0000788 unsigned char* oidata=NULL;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000789 uint32_t size;
790
791 PTP_CNT_INIT(ptp);
792 ptp.Code=PTP_OC_SendObjectInfo;
793 ptp.Param1=*store;
794 ptp.Param2=*parenthandle;
795 ptp.Nparam=2;
796
797 size=ptp_pack_OI(params, objectinfo, &oidata);
Linus Walleijb02a0662006-04-25 08:05:09 +0000798 ret = ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, &oidata, NULL);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000799 free(oidata);
800 *store=ptp.Param1;
801 *parenthandle=ptp.Param2;
802 *handle=ptp.Param3;
803 return ret;
804}
805
806/**
807 * ptp_sendobject:
808 * params: PTPParams*
809 * char* object - contains the object that is to be sent
810 * uint32_t size - object size
811 *
812 * Sends object to Responder.
813 *
814 * Return values: Some PTP_RC_* code.
815 *
816 */
817uint16_t
Linus Walleijb02a0662006-04-25 08:05:09 +0000818ptp_sendobject (PTPParams* params, unsigned char* object, uint32_t size)
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000819{
820 PTPContainer ptp;
821
822 PTP_CNT_INIT(ptp);
823 ptp.Code=PTP_OC_SendObject;
824 ptp.Nparam=0;
825
Linus Walleijb02a0662006-04-25 08:05:09 +0000826 return ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, &object, NULL);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000827}
828
829
830/**
831 * ptp_initiatecapture:
832 * params: PTPParams*
833 * storageid - destination StorageID on Responder
834 * ofc - object format code
835 *
836 * Causes device to initiate the capture of one or more new data objects
837 * according to its current device properties, storing the data into store
838 * indicated by storageid. If storageid is 0x00000000, the object(s) will
839 * be stored in a store that is determined by the capturing device.
840 * The capturing of new data objects is an asynchronous operation.
841 *
842 * Return values: Some PTP_RC_* code.
843 **/
844
845uint16_t
846ptp_initiatecapture (PTPParams* params, uint32_t storageid,
847 uint32_t ofc)
848{
849 PTPContainer ptp;
850
851 PTP_CNT_INIT(ptp);
852 ptp.Code=PTP_OC_InitiateCapture;
853 ptp.Param1=storageid;
854 ptp.Param2=ofc;
855 ptp.Nparam=2;
Linus Walleijb02a0662006-04-25 08:05:09 +0000856 return ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000857}
858
859uint16_t
860ptp_getdevicepropdesc (PTPParams* params, uint16_t propcode,
861 PTPDevicePropDesc* devicepropertydesc)
862{
863 PTPContainer ptp;
864 uint16_t ret;
Linus Walleijb02a0662006-04-25 08:05:09 +0000865 unsigned int len;
866 unsigned char* dpd=NULL;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000867
868 PTP_CNT_INIT(ptp);
869 ptp.Code=PTP_OC_GetDevicePropDesc;
870 ptp.Param1=propcode;
871 ptp.Nparam=1;
Linus Walleijb02a0662006-04-25 08:05:09 +0000872 len=0;
873 ret=ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &dpd, &len);
874 if (ret == PTP_RC_OK) ptp_unpack_DPD(params, dpd, devicepropertydesc, len);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000875 free(dpd);
876 return ret;
877}
878
Linus Walleijb02a0662006-04-25 08:05:09 +0000879
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000880uint16_t
881ptp_getdevicepropvalue (PTPParams* params, uint16_t propcode,
Linus Walleijb02a0662006-04-25 08:05:09 +0000882 PTPPropertyValue* value, uint16_t datatype)
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000883{
884 PTPContainer ptp;
885 uint16_t ret;
Linus Walleijb02a0662006-04-25 08:05:09 +0000886 unsigned int len;
887 int offset;
888 unsigned char* dpv=NULL;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000889
890
891 PTP_CNT_INIT(ptp);
892 ptp.Code=PTP_OC_GetDevicePropValue;
893 ptp.Param1=propcode;
894 ptp.Nparam=1;
Linus Walleijb02a0662006-04-25 08:05:09 +0000895 len=offset=0;
896 ret=ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &dpv, &len);
897 if (ret == PTP_RC_OK) ptp_unpack_DPV(params, dpv, &offset, len, value, datatype);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000898 free(dpv);
899 return ret;
900}
901
902uint16_t
903ptp_setdevicepropvalue (PTPParams* params, uint16_t propcode,
Linus Walleijb02a0662006-04-25 08:05:09 +0000904 PTPPropertyValue *value, uint16_t datatype)
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000905{
906 PTPContainer ptp;
907 uint16_t ret;
908 uint32_t size;
Linus Walleijb02a0662006-04-25 08:05:09 +0000909 unsigned char* dpv=NULL;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000910
911 PTP_CNT_INIT(ptp);
912 ptp.Code=PTP_OC_SetDevicePropValue;
913 ptp.Param1=propcode;
914 ptp.Nparam=1;
915 size=ptp_pack_DPV(params, value, &dpv, datatype);
Linus Walleijb02a0662006-04-25 08:05:09 +0000916 ret=ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, &dpv, NULL);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000917 free(dpv);
918 return ret;
919}
920
921/**
922 * ptp_ek_sendfileobjectinfo:
923 * params: PTPParams*
924 * uint32_t* store - destination StorageID on Responder
925 * uint32_t* parenthandle - Parent ObjectHandle on responder
926 * uint32_t* handle - see Return values
927 * PTPObjectInfo* objectinfo- ObjectInfo that is to be sent
928 *
929 * Sends ObjectInfo of file that is to be sent via SendFileObject.
930 *
931 * Return values: Some PTP_RC_* code.
932 * Upon success : uint32_t* store - Responder StorageID in which
933 * object will be stored
934 * uint32_t* parenthandle- Responder Parent ObjectHandle
935 * in which the object will be stored
936 * uint32_t* handle - Responder's reserved ObjectHandle
937 * for the incoming object
938 **/
939uint16_t
940ptp_ek_sendfileobjectinfo (PTPParams* params, uint32_t* store,
941 uint32_t* parenthandle, uint32_t* handle,
942 PTPObjectInfo* objectinfo)
943{
944 uint16_t ret;
945 PTPContainer ptp;
Linus Walleijb02a0662006-04-25 08:05:09 +0000946 unsigned char* oidata=NULL;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000947 uint32_t size;
948
949 PTP_CNT_INIT(ptp);
950 ptp.Code=PTP_OC_EK_SendFileObjectInfo;
951 ptp.Param1=*store;
952 ptp.Param2=*parenthandle;
953 ptp.Nparam=2;
954
955 size=ptp_pack_OI(params, objectinfo, &oidata);
Linus Walleijb02a0662006-04-25 08:05:09 +0000956 ret=ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, &oidata, NULL);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000957 free(oidata);
958 *store=ptp.Param1;
959 *parenthandle=ptp.Param2;
960 *handle=ptp.Param3;
961 return ret;
962}
963
964/**
Linus Walleijb02a0662006-04-25 08:05:09 +0000965 * ptp_ek_getserial:
966 * params: PTPParams*
967 * char** serial - contains the serial number of the camera
968 * uint32_t* size - contains the string length
969 *
970 * Gets the serial number from the device. (ptp serial)
971 *
972 * Return values: Some PTP_RC_* code.
973 *
974 */
975uint16_t
976ptp_ek_getserial (PTPParams* params, unsigned char **data, unsigned int *size)
977{
978 PTPContainer ptp;
979
980 PTP_CNT_INIT(ptp);
981 ptp.Code = PTP_OC_EK_GetSerial;
982 ptp.Nparam = 0;
983 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, data, size);
984}
985
986/**
987 * ptp_ek_setserial:
988 * params: PTPParams*
989 * char* serial - contains the new serial number
990 * uint32_t size - string length
991 *
992 * Sets the serial number of the device. (ptp serial)
993 *
994 * Return values: Some PTP_RC_* code.
995 *
996 */
997uint16_t
998ptp_ek_setserial (PTPParams* params, unsigned char *data, unsigned int size)
999{
1000 PTPContainer ptp;
1001
1002 PTP_CNT_INIT(ptp);
1003 ptp.Code = PTP_OC_EK_SetSerial;
1004 ptp.Nparam = 0;
1005 return ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, &data, NULL);
1006}
1007
1008/* unclear what it does yet */
1009uint16_t
1010ptp_ek_9007 (PTPParams* params, unsigned char **data, unsigned int *size)
1011{
1012 PTPContainer ptp;
1013
1014 PTP_CNT_INIT(ptp);
1015 ptp.Code = 0x9007;
1016 ptp.Nparam = 0;
1017 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, data, size);
1018}
1019
1020/* unclear what it does yet */
1021uint16_t
1022ptp_ek_9009 (PTPParams* params, uint32_t *p1, uint32_t *p2)
1023{
1024 PTPContainer ptp;
1025 uint16_t ret;
1026
1027 PTP_CNT_INIT(ptp);
1028 ptp.Code = 0x9009;
1029 ptp.Nparam = 0;
1030 ret = ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL);
1031 *p1 = ptp.Param1;
1032 *p2 = ptp.Param2;
1033 return ret;
1034}
1035
1036/* unclear yet, but I guess it returns the info from 9008 */
1037uint16_t
1038ptp_ek_900c (PTPParams* params, unsigned char **data, unsigned int *size)
1039{
1040 PTPContainer ptp;
1041
1042 PTP_CNT_INIT(ptp);
1043 ptp.Code = 0x900c;
1044 ptp.Nparam = 0;
1045 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, data, size);
1046 /* returned data is 16bit,16bit,32bit,32bit */
1047}
1048
1049/**
1050 * ptp_ek_settext:
1051 * params: PTPParams*
1052 * PTPEKTextParams* - contains the texts to display.
1053 *
1054 * Displays the specified texts on the TFT of the camera.
1055 *
1056 * Return values: Some PTP_RC_* code.
1057 *
1058 */
1059uint16_t
1060ptp_ek_settext (PTPParams* params, PTPEKTextParams *text)
1061{
1062 PTPContainer ptp;
1063 uint16_t ret;
1064 unsigned int size;
1065 unsigned char *data;
1066
1067 PTP_CNT_INIT(ptp);
1068 ptp.Code = PTP_OC_EK_SetText;
1069 ptp.Nparam = 0;
1070 if (0 == (size = ptp_pack_EK_text(params, text, &data)))
1071 return PTP_ERROR_BADPARAM;
1072 ret = ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, &data, NULL);
1073 free(data);
1074 return ret;
1075}
1076
1077/**
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001078 * ptp_ek_sendfileobject:
1079 * params: PTPParams*
1080 * char* object - contains the object that is to be sent
1081 * uint32_t size - object size
1082 *
1083 * Sends object to Responder.
1084 *
1085 * Return values: Some PTP_RC_* code.
1086 *
1087 */
1088uint16_t
Linus Walleijb02a0662006-04-25 08:05:09 +00001089ptp_ek_sendfileobject (PTPParams* params, unsigned char* object, uint32_t size)
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001090{
1091 PTPContainer ptp;
1092
1093 PTP_CNT_INIT(ptp);
1094 ptp.Code=PTP_OC_EK_SendFileObject;
1095 ptp.Nparam=0;
1096
Linus Walleijb02a0662006-04-25 08:05:09 +00001097 return ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, &object, NULL);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001098}
1099
1100/*************************************************************************
1101 *
1102 * Canon PTP extensions support
1103 *
1104 * (C) Nikolai Kopanygin 2003
1105 *
1106 *************************************************************************/
1107
1108
1109/**
1110 * ptp_canon_getobjectsize:
1111 * params: PTPParams*
1112 * uint32_t handle - ObjectHandle
1113 * uint32_t p2 - Yet unknown parameter,
1114 * value 0 works.
1115 *
1116 * Gets form the responder the size of the specified object.
1117 *
1118 * Return values: Some PTP_RC_* code.
1119 * Upon success : uint32_t* size - The object size
1120 * uint32_t rp2 - Yet unknown parameter
1121 *
1122 **/
1123uint16_t
1124ptp_canon_getobjectsize (PTPParams* params, uint32_t handle, uint32_t p2,
1125 uint32_t* size, uint32_t* rp2)
1126{
1127 uint16_t ret;
1128 PTPContainer ptp;
1129
1130 PTP_CNT_INIT(ptp);
1131 ptp.Code=PTP_OC_CANON_GetObjectSize;
1132 ptp.Param1=handle;
1133 ptp.Param2=p2;
1134 ptp.Nparam=2;
Linus Walleijb02a0662006-04-25 08:05:09 +00001135 ret=ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001136 *size=ptp.Param1;
1137 *rp2=ptp.Param2;
1138 return ret;
1139}
1140
1141/**
1142 * ptp_canon_startshootingmode:
1143 * params: PTPParams*
1144 *
1145 * Starts shooting session. It emits a StorageInfoChanged
1146 * event via the interrupt pipe and pushes the StorageInfoChanged
1147 * and CANON_CameraModeChange events onto the event stack
1148 * (see operation PTP_OC_CANON_CheckEvent).
1149 *
1150 * Return values: Some PTP_RC_* code.
1151 *
1152 **/
1153uint16_t
1154ptp_canon_startshootingmode (PTPParams* params)
1155{
1156 PTPContainer ptp;
1157
1158 PTP_CNT_INIT(ptp);
1159 ptp.Code=PTP_OC_CANON_StartShootingMode;
1160 ptp.Nparam=0;
Linus Walleijb02a0662006-04-25 08:05:09 +00001161 return ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001162}
1163
1164/**
1165 * ptp_canon_endshootingmode:
1166 * params: PTPParams*
1167 *
1168 * This operation is observed after pressing the Disconnect
1169 * button on the Remote Capture app. It emits a StorageInfoChanged
1170 * event via the interrupt pipe and pushes the StorageInfoChanged
1171 * and CANON_CameraModeChange events onto the event stack
1172 * (see operation PTP_OC_CANON_CheckEvent).
1173 *
1174 * Return values: Some PTP_RC_* code.
1175 *
1176 **/
1177uint16_t
1178ptp_canon_endshootingmode (PTPParams* params)
1179{
1180 PTPContainer ptp;
1181
1182 PTP_CNT_INIT(ptp);
1183 ptp.Code=PTP_OC_CANON_EndShootingMode;
1184 ptp.Nparam=0;
Linus Walleijb02a0662006-04-25 08:05:09 +00001185 return ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001186}
1187
1188/**
1189 * ptp_canon_viewfinderon:
1190 * params: PTPParams*
1191 *
1192 * Prior to start reading viewfinder images, one must call this operation.
1193 * Supposedly, this operation affects the value of the CANON_ViewfinderMode
1194 * property.
1195 *
1196 * Return values: Some PTP_RC_* code.
1197 *
1198 **/
1199uint16_t
1200ptp_canon_viewfinderon (PTPParams* params)
1201{
1202 PTPContainer ptp;
1203
1204 PTP_CNT_INIT(ptp);
1205 ptp.Code=PTP_OC_CANON_ViewfinderOn;
1206 ptp.Nparam=0;
Linus Walleijb02a0662006-04-25 08:05:09 +00001207 return ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001208}
1209
1210/**
1211 * ptp_canon_viewfinderoff:
1212 * params: PTPParams*
1213 *
1214 * Before changing the shooting mode, or when one doesn't need to read
1215 * viewfinder images any more, one must call this operation.
1216 * Supposedly, this operation affects the value of the CANON_ViewfinderMode
1217 * property.
1218 *
1219 * Return values: Some PTP_RC_* code.
1220 *
1221 **/
1222uint16_t
1223ptp_canon_viewfinderoff (PTPParams* params)
1224{
1225 PTPContainer ptp;
1226
1227 PTP_CNT_INIT(ptp);
1228 ptp.Code=PTP_OC_CANON_ViewfinderOff;
1229 ptp.Nparam=0;
Linus Walleijb02a0662006-04-25 08:05:09 +00001230 return ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001231}
1232
1233/**
1234 * ptp_canon_reflectchanges:
1235 * params: PTPParams*
1236 * uint32_t p1 - Yet unknown parameter,
1237 * value 7 works
1238 *
1239 * Make viewfinder reflect changes.
1240 * There is a button for this operation in the Remote Capture app.
1241 * What it does exactly I don't know. This operation is followed
1242 * by the CANON_GetChanges(?) operation in the log.
1243 *
1244 * Return values: Some PTP_RC_* code.
1245 *
1246 **/
1247uint16_t
1248ptp_canon_reflectchanges (PTPParams* params, uint32_t p1)
1249{
1250 PTPContainer ptp;
1251
1252 PTP_CNT_INIT(ptp);
1253 ptp.Code=PTP_OC_CANON_ReflectChanges;
1254 ptp.Param1=p1;
1255 ptp.Nparam=1;
Linus Walleijb02a0662006-04-25 08:05:09 +00001256 return ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001257}
1258
1259
1260/**
1261 * ptp_canon_checkevent:
1262 * params: PTPParams*
1263 *
1264 * The camera has a FIFO stack, in which it accumulates events.
1265 * Partially these events are communicated also via the USB interrupt pipe
1266 * according to the PTP USB specification, partially not.
1267 * This operation returns from the device a block of data, empty,
1268 * if the event stack is empty, or filled with an event's data otherwise.
1269 * The event is removed from the stack in the latter case.
1270 * The Remote Capture app sends this command to the camera all the time
1271 * of connection, filling with it the gaps between other operations.
1272 *
1273 * Return values: Some PTP_RC_* code.
1274 * Upon success : PTPUSBEventContainer* event - is filled with the event data
1275 * if any
1276 * int *isevent - returns 1 in case of event
1277 * or 0 otherwise
1278 **/
1279uint16_t
1280ptp_canon_checkevent (PTPParams* params, PTPUSBEventContainer* event, int* isevent)
1281{
1282 uint16_t ret;
1283 PTPContainer ptp;
Linus Walleijb02a0662006-04-25 08:05:09 +00001284 unsigned char *evdata = NULL;
1285 unsigned int len;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001286
1287 *isevent=0;
1288 PTP_CNT_INIT(ptp);
1289 ptp.Code=PTP_OC_CANON_CheckEvent;
1290 ptp.Nparam=0;
Linus Walleijb02a0662006-04-25 08:05:09 +00001291 len=0;
1292 ret=ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &evdata, &len);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001293 if (evdata!=NULL) {
1294 if (ret == PTP_RC_OK) {
Linus Walleijb02a0662006-04-25 08:05:09 +00001295 ptp_unpack_EC(params, evdata, event, len);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001296 *isevent=1;
1297 }
1298 free(evdata);
1299 }
1300 return ret;
1301}
1302
1303
1304/**
1305 * ptp_canon_focuslock:
1306 *
1307 * This operation locks the focus. It is followed by the CANON_GetChanges(?)
1308 * operation in the log.
1309 * It affects the CANON_MacroMode property.
1310 *
1311 * params: PTPParams*
1312 *
1313 * Return values: Some PTP_RC_* code.
1314 *
1315 **/
1316uint16_t
1317ptp_canon_focuslock (PTPParams* params)
1318{
1319 PTPContainer ptp;
1320
1321 PTP_CNT_INIT(ptp);
1322 ptp.Code=PTP_OC_CANON_FocusLock;
1323 ptp.Nparam=0;
Linus Walleijb02a0662006-04-25 08:05:09 +00001324 return ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001325}
1326
1327/**
1328 * ptp_canon_focusunlock:
1329 *
1330 * This operation unlocks the focus. It is followed by the CANON_GetChanges(?)
1331 * operation in the log.
1332 * It sets the CANON_MacroMode property value to 1 (where it occurs in the log).
1333 *
1334 * params: PTPParams*
1335 *
1336 * Return values: Some PTP_RC_* code.
1337 *
1338 **/
1339uint16_t
1340ptp_canon_focusunlock (PTPParams* params)
1341{
1342 PTPContainer ptp;
1343
1344 PTP_CNT_INIT(ptp);
1345 ptp.Code=PTP_OC_CANON_FocusUnlock;
1346 ptp.Nparam=0;
Linus Walleijb02a0662006-04-25 08:05:09 +00001347 return ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001348}
1349
1350/**
1351 * ptp_canon_initiatecaptureinmemory:
1352 *
1353 * This operation starts the image capture according to the current camera
1354 * settings. When the capture has happened, the camera emits a CaptureComplete
1355 * event via the interrupt pipe and pushes the CANON_RequestObjectTransfer,
1356 * CANON_DeviceInfoChanged and CaptureComplete events onto the event stack
1357 * (see operation CANON_CheckEvent). From the CANON_RequestObjectTransfer
1358 * event's parameter one can learn the just captured image's ObjectHandle.
1359 * The image is stored in the camera's own RAM.
1360 * On the next capture the image will be overwritten!
1361 *
1362 * params: PTPParams*
1363 *
1364 * Return values: Some PTP_RC_* code.
1365 *
1366 **/
1367uint16_t
1368ptp_canon_initiatecaptureinmemory (PTPParams* params)
1369{
1370 PTPContainer ptp;
1371
1372 PTP_CNT_INIT(ptp);
1373 ptp.Code=PTP_OC_CANON_InitiateCaptureInMemory;
1374 ptp.Nparam=0;
Linus Walleijb02a0662006-04-25 08:05:09 +00001375 return ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL);
1376}
1377
1378uint16_t
1379ptp_canon_9012 (PTPParams* params)
1380{
1381 PTPContainer ptp;
1382
1383 PTP_CNT_INIT(ptp);
1384 ptp.Code=0x9012;
1385 ptp.Nparam=0;
1386 return ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001387}
1388
1389/**
1390 * ptp_canon_getpartialobject:
1391 *
1392 * This operation is used to read from the device a data
1393 * block of an object from a specified offset.
1394 *
1395 * params: PTPParams*
1396 * uint32_t handle - the handle of the requested object
1397 * uint32_t offset - the offset in bytes from the beginning of the object
1398 * uint32_t size - the requested size of data block to read
1399 * uint32_t pos - 1 for the first block, 2 - for a block in the middle,
1400 * 3 - for the last block
1401 *
1402 * Return values: Some PTP_RC_* code.
1403 * char **block - the pointer to the block of data read
1404 * uint32_t* readnum - the number of bytes read
1405 *
1406 **/
1407uint16_t
1408ptp_canon_getpartialobject (PTPParams* params, uint32_t handle,
1409 uint32_t offset, uint32_t size,
Linus Walleijb02a0662006-04-25 08:05:09 +00001410 uint32_t pos, unsigned char** block,
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001411 uint32_t* readnum)
1412{
1413 uint16_t ret;
1414 PTPContainer ptp;
Linus Walleijb02a0662006-04-25 08:05:09 +00001415 unsigned char *data=NULL;
1416 unsigned int len;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001417
1418 PTP_CNT_INIT(ptp);
1419 ptp.Code=PTP_OC_CANON_GetPartialObject;
1420 ptp.Param1=handle;
1421 ptp.Param2=offset;
1422 ptp.Param3=size;
1423 ptp.Param4=pos;
1424 ptp.Nparam=4;
Linus Walleijb02a0662006-04-25 08:05:09 +00001425 len=0;
1426 ret=ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &len);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001427 if (ret==PTP_RC_OK) {
1428 *block=data;
1429 *readnum=ptp.Param1;
1430 }
1431 return ret;
1432}
1433
1434/**
1435 * ptp_canon_getviewfinderimage:
1436 *
1437 * This operation can be used to read the image which is currently
1438 * in the camera's viewfinder. The image size is 320x240, format is JPEG.
1439 * Of course, prior to calling this operation, one must turn the viewfinder
1440 * on with the CANON_ViewfinderOn command.
1441 * Invoking this operation many times, one can get live video from the camera!
1442 *
1443 * params: PTPParams*
1444 *
1445 * Return values: Some PTP_RC_* code.
1446 * char **image - the pointer to the read image
1447 * unit32_t *size - the size of the image in bytes
1448 *
1449 **/
1450uint16_t
Linus Walleijb02a0662006-04-25 08:05:09 +00001451ptp_canon_getviewfinderimage (PTPParams* params, unsigned char** image, uint32_t* size)
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001452{
1453 uint16_t ret;
1454 PTPContainer ptp;
Linus Walleijb02a0662006-04-25 08:05:09 +00001455 unsigned int len;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001456
1457 PTP_CNT_INIT(ptp);
1458 ptp.Code=PTP_OC_CANON_GetViewfinderImage;
1459 ptp.Nparam=0;
Linus Walleijb02a0662006-04-25 08:05:09 +00001460 ret=ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, image, &len);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001461 if (ret==PTP_RC_OK) *size=ptp.Param1;
1462 return ret;
1463}
1464
1465/**
1466 * ptp_canon_getchanges:
1467 *
1468 * This is an interesting operation, about the effect of which I am not sure.
1469 * This command is called every time when a device property has been changed
1470 * with the SetDevicePropValue operation, and after some other operations.
1471 * This operation reads the array of Device Properties which have been changed
1472 * by the previous operation.
1473 * Probably, this operation is even required to make those changes work.
1474 *
1475 * params: PTPParams*
1476 *
1477 * Return values: Some PTP_RC_* code.
1478 * uint16_t** props - the pointer to the array of changed properties
1479 * uint32_t* propnum - the number of elements in the *props array
1480 *
1481 **/
1482uint16_t
1483ptp_canon_getchanges (PTPParams* params, uint16_t** props, uint32_t* propnum)
1484{
1485 uint16_t ret;
1486 PTPContainer ptp;
Linus Walleijb02a0662006-04-25 08:05:09 +00001487 unsigned char* data=NULL;
1488 unsigned int len;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001489
1490 PTP_CNT_INIT(ptp);
1491 ptp.Code=PTP_OC_CANON_GetChanges;
1492 ptp.Nparam=0;
Linus Walleijb02a0662006-04-25 08:05:09 +00001493 len=0;
1494 ret=ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &len);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001495 if (ret == PTP_RC_OK)
1496 *propnum=ptp_unpack_uint16_t_array(params,data,0,props);
1497 free(data);
1498 return ret;
1499}
1500
1501/**
1502 * ptp_canon_getfolderentries:
1503 *
1504 * This command reads a specified object's record in a device's filesystem,
1505 * or the records of all objects belonging to a specified folder (association).
1506 *
1507 * params: PTPParams*
1508 * uint32_t store - StorageID,
1509 * uint32_t p2 - Yet unknown (0 value works OK)
1510 * uint32_t parent - Parent Object Handle
1511 * # If Parent Object Handle is 0xffffffff,
1512 * # the Parent Object is the top level folder.
1513 * uint32_t handle - Object Handle
1514 * # If Object Handle is 0, the records of all objects
1515 * # belonging to the Parent Object are read.
1516 * # If Object Handle is not 0, only the record of this
1517 * # Object is read.
1518 *
1519 * Return values: Some PTP_RC_* code.
1520 * PTPCANONFolderEntry** entries - the pointer to the folder entry array
1521 * uint32_t* entnum - the number of elements of the array
1522 *
1523 **/
1524uint16_t
1525ptp_canon_getfolderentries (PTPParams* params, uint32_t store, uint32_t p2,
1526 uint32_t parent, uint32_t handle,
1527 PTPCANONFolderEntry** entries, uint32_t* entnum)
1528{
1529 uint16_t ret;
1530 PTPContainer ptp;
Linus Walleijb02a0662006-04-25 08:05:09 +00001531 unsigned char *data = NULL;
1532 unsigned int len;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001533
1534 PTP_CNT_INIT(ptp);
1535 ptp.Code=PTP_OC_CANON_GetFolderEntries;
1536 ptp.Param1=store;
1537 ptp.Param2=p2;
1538 ptp.Param3=parent;
1539 ptp.Param4=handle;
1540 ptp.Nparam=4;
Linus Walleijb02a0662006-04-25 08:05:09 +00001541 len=0;
1542 ret=ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &len);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001543 if (ret == PTP_RC_OK) {
1544 int i;
1545 *entnum=ptp.Param1;
1546 *entries=calloc(*entnum, sizeof(PTPCANONFolderEntry));
1547 if (*entries!=NULL) {
1548 for(i=0; i<(*entnum); i++)
1549 ptp_unpack_Canon_FE(params,
1550 data+i*PTP_CANON_FolderEntryLen,
1551 &((*entries)[i]) );
1552 } else {
1553 ret=PTP_ERROR_IO; /* Cannot allocate memory */
1554 }
1555 }
1556 free(data);
1557 return ret;
1558}
1559
Linus Walleijb02a0662006-04-25 08:05:09 +00001560/**
1561 * ptp_canon_theme_download:
1562 *
1563 * This command downloads the specified theme slot, including jpegs
1564 * and wav files.
1565 *
1566 * params: PTPParams*
1567 * uint32_t themenr - nr of theme
1568 *
1569 * Return values: Some PTP_RC_* code.
1570 * unsigned char **data - pointer to data pointer
1571 * unsigned int *size - size of data returned
1572 *
1573 **/
1574uint16_t
1575ptp_canon_theme_download (PTPParams* params, uint32_t themenr,
1576 unsigned char **data, unsigned int *size)
1577{
1578 PTPContainer ptp;
1579
1580 *data = NULL;
1581 *size = 0;
1582 PTP_CNT_INIT(ptp);
1583 ptp.Code = PTP_OC_CANON_ThemeDownload;
1584 ptp.Param1 = themenr;
1585 ptp.Nparam = 1;
1586 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, data, size);
1587}
1588
1589
1590
1591uint16_t
1592ptp_nikon_curve_download (PTPParams* params, unsigned char **data, unsigned int *size) {
1593 PTPContainer ptp;
1594 *data = NULL;
1595 *size = 0;
1596 PTP_CNT_INIT(ptp);
1597 ptp.Code = PTP_OC_NIKON_CurveDownload;
1598 ptp.Nparam = 0;
1599 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, data, size);
1600}
1601
1602uint16_t
1603ptp_nikon_getfileinfoinblock ( PTPParams* params,
1604 uint32_t p1, uint32_t p2, uint32_t p3,
1605 unsigned char **data, unsigned int *size
1606) {
1607 PTPContainer ptp;
1608 *data = NULL;
1609 *size = 0;
1610 PTP_CNT_INIT(ptp);
1611 ptp.Code = PTP_OC_NIKON_GetFileInfoInBlock;
1612 ptp.Nparam = 3;
1613 ptp.Param1 = p1;
1614 ptp.Param2 = p2;
1615 ptp.Param3 = p3;
1616 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, data, size);
1617}
1618
1619/**
1620 * ptp_nikon_setcontrolmode:
1621 *
1622 * This command can switch the camera to full PC control mode.
1623 *
1624 * params: PTPParams*
1625 * uint32_t mode - mode
1626 *
1627 * Return values: Some PTP_RC_* code.
1628 *
1629 **/
1630uint16_t
1631ptp_nikon_setcontrolmode (PTPParams* params, uint32_t mode)
1632{
1633 PTPContainer ptp;
1634
1635 PTP_CNT_INIT(ptp);
1636 ptp.Code=PTP_OC_NIKON_SetControlMode;
1637 ptp.Param1=mode;
1638 ptp.Nparam=1;
1639 return ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL);
1640}
1641
1642/**
1643 * ptp_nikon_capture:
1644 *
1645 * This command captures a picture on the Nikon.
1646 *
1647 * params: PTPParams*
1648 * uint32_t x - unknown parameter. seen to be -1.
1649 *
1650 * Return values: Some PTP_RC_* code.
1651 *
1652 **/
1653uint16_t
1654ptp_nikon_capture (PTPParams* params, uint32_t x)
1655{
1656 PTPContainer ptp;
1657
1658 PTP_CNT_INIT(ptp);
1659 ptp.Code=PTP_OC_NIKON_Capture;
1660 ptp.Param1=x;
1661 ptp.Nparam=1;
1662 return ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL);
1663}
1664
1665/**
1666 * ptp_nikon_check_event:
1667 *
1668 * This command checks the event queue on the Nikon.
1669 *
1670 * params: PTPParams*
1671 * PTPUSBEventContainer **event - list of usb events.
1672 * int *evtcnt - number of usb events in event structure.
1673 *
1674 * Return values: Some PTP_RC_* code.
1675 *
1676 **/
1677uint16_t
1678ptp_nikon_check_event (PTPParams* params, PTPUSBEventContainer** event, int* evtcnt)
1679{
1680 PTPContainer ptp;
1681 uint16_t ret;
1682 unsigned char *data = NULL;
1683 unsigned int size = 0;
1684
1685 PTP_CNT_INIT(ptp);
1686 ptp.Code=PTP_OC_NIKON_CheckEvent;
1687 ptp.Nparam=0;
1688 *evtcnt = 0;
1689 ret = ptp_transaction (params, &ptp, PTP_DP_GETDATA, 0, &data, &size);
1690 if (ret == PTP_RC_OK) {
1691 ptp_unpack_Nikon_EC (params, data, size, event, evtcnt);
1692 free (data);
1693 }
1694 return ret;
1695}
1696
1697/**
1698 * ptp_nikon_device_ready:
1699 *
1700 * This command checks if the device is ready. Used after
1701 * a capture.
1702 *
1703 * params: PTPParams*
1704 *
1705 * Return values: Some PTP_RC_* code.
1706 *
1707 **/
1708uint16_t
1709ptp_nikon_device_ready (PTPParams* params)
1710{
1711 PTPContainer ptp;
1712
1713 PTP_CNT_INIT(ptp);
1714 ptp.Code=PTP_OC_NIKON_DeviceReady;
1715 ptp.Nparam=0;
1716 return ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL);
1717}
1718
1719/**
1720 * ptp_nikon_getptpipinfo:
1721 *
1722 * This command gets the ptpip info data.
1723 *
1724 * params: PTPParams*
1725 * unsigned char *data - data
1726 * unsigned int size - size of returned data
1727 *
1728 * Return values: Some PTP_RC_* code.
1729 *
1730 **/
1731uint16_t
1732ptp_nikon_getptpipinfo (PTPParams* params, unsigned char **data, unsigned int *size)
1733{
1734 PTPContainer ptp;
1735
1736 PTP_CNT_INIT(ptp);
1737 ptp.Code=PTP_OC_NIKON_GetDevicePTPIPInfo;
1738 ptp.Nparam=0;
1739 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, data, size);
1740}
1741
1742/**
1743 * ptp_nikon_getprofilealldata:
1744 *
1745 * This command gets the ptpip info data.
1746 *
1747 * params: PTPParams*
1748 * unsigned char *data - data
1749 * unsigned int size - size of returned data
1750 *
1751 * Return values: Some PTP_RC_* code.
1752 *
1753 **/
1754uint16_t
1755ptp_nikon_getprofilealldata (PTPParams* params, unsigned char **data, unsigned int *size)
1756{
1757 PTPContainer ptp;
1758
1759 PTP_CNT_INIT(ptp);
1760 ptp.Code=PTP_OC_NIKON_GetProfileAllData;
1761 ptp.Nparam=0;
1762 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, data, size);
1763}
1764
1765/**
1766 * ptp_nikon_sendprofiledata:
1767 *
1768 * This command gets the ptpip info data.
1769 *
1770 * params: PTPParams*
1771 * unsigned char *data - data
1772 * unsigned int size - size of returned data
1773 *
1774 * Return values: Some PTP_RC_* code.
1775 *
1776 **/
1777uint16_t
1778ptp_nikon_sendprofiledata (PTPParams* params, uint32_t profilenr, unsigned char *data, unsigned int size)
1779{
1780 PTPContainer ptp;
1781
1782 PTP_CNT_INIT(ptp);
1783 ptp.Code=PTP_OC_NIKON_SendProfileData;
1784 ptp.Nparam=1;
1785 ptp.Param1=profilenr;
1786 return ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, &data, NULL);
1787}
1788
1789/**
1790 * ptp_mtp_getobjectpropssupported:
1791 *
1792 * This command gets the object properties possible from the device.
1793 *
1794 * params: PTPParams*
1795 * uint ofc - object format code
1796 * unsigned int *propnum - number of elements in returned array
1797 * uint16_t *props - array of supported properties
1798 *
1799 * Return values: Some PTP_RC_* code.
1800 *
1801 **/
1802uint16_t
1803ptp_mtp_getobjectpropssupported (PTPParams* params, uint16_t ofc,
1804 uint32_t *propnum, uint16_t **props
1805) {
1806 PTPContainer ptp;
1807 uint16_t ret;
1808 unsigned char *data = NULL;
1809 unsigned int size = 0;
1810
1811 PTP_CNT_INIT(ptp);
1812 ptp.Code=PTP_OC_MTP_GetObjectPropsSupported;
1813 ptp.Nparam = 1;
1814 ptp.Param1 = ofc;
1815 ret = ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size);
1816 if (ret == PTP_RC_OK)
1817 *propnum=ptp_unpack_uint16_t_array(params,data,0,props);
1818 free(data);
1819 return ret;
1820}
1821
1822/**
1823 * ptp_mtp_getobjectpropdesc:
1824 *
1825 * This command gets the object property description.
1826 *
1827 * params: PTPParams*
1828 * uint16_t opc - object property code
1829 * uint16_t ofc - object format code
1830 *
1831 * Return values: Some PTP_RC_* code.
1832 *
1833 **/
1834uint16_t
1835ptp_mtp_getobjectpropdesc (
1836 PTPParams* params, uint16_t opc, uint16_t ofc, PTPObjectPropDesc *opd
1837) {
1838 PTPContainer ptp;
1839 uint16_t ret;
1840 unsigned char *data = NULL;
1841 unsigned int size = 0;
1842
1843 PTP_CNT_INIT(ptp);
1844 ptp.Code=PTP_OC_MTP_GetObjectPropDesc;
1845 ptp.Nparam = 2;
1846 ptp.Param1 = opc;
1847 ptp.Param2 = ofc;
1848 ret = ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size);
1849 if (ret == PTP_RC_OK)
1850 ptp_unpack_OPD (params, data, opd, size);
1851 free(data);
1852 return ret;
1853}
1854
1855/**
1856 * ptp_mtp_getobjectpropvalue:
1857 *
1858 * This command gets the object properties of an object handle.
1859 *
1860 * params: PTPParams*
1861 * uint32_t objectid - object format code
1862 * uint16_t opc - object prop code
1863 *
1864 * Return values: Some PTP_RC_* code.
1865 *
1866 **/
1867uint16_t
1868ptp_mtp_getobjectpropvalue (
1869 PTPParams* params, uint32_t oid, uint16_t opc,
1870 PTPPropertyValue *value, uint16_t datatype
1871) {
1872 PTPContainer ptp;
1873 uint16_t ret;
1874 unsigned char *data = NULL;
1875 unsigned int size = 0;
1876 int offset = 0;
1877
1878 PTP_CNT_INIT(ptp);
1879 ptp.Code=PTP_OC_MTP_GetObjectPropValue;
1880 ptp.Nparam = 2;
1881 ptp.Param1 = oid;
1882 ptp.Param2 = opc;
1883 ret = ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size);
1884 if (ret == PTP_RC_OK)
1885 ptp_unpack_DPV(params, data, &offset, size, value, datatype);
1886 free(data);
1887 return ret;
1888}
1889
1890/**
1891 * ptp_mtp_setobjectpropvalue:
1892 *
1893 * This command gets the object properties of an object handle.
1894 *
1895 * params: PTPParams*
1896 * uint32_t objectid - object format code
1897 * uint16_t opc - object prop code
1898 *
1899 * Return values: Some PTP_RC_* code.
1900 *
1901 **/
1902uint16_t
1903ptp_mtp_setobjectpropvalue (
1904 PTPParams* params, uint32_t oid, uint16_t opc,
1905 PTPPropertyValue *value, uint16_t datatype
1906) {
1907 PTPContainer ptp;
1908 uint16_t ret;
1909 unsigned char *data = NULL;
1910 unsigned int size ;
1911
1912 PTP_CNT_INIT(ptp);
1913 ptp.Code=PTP_OC_MTP_SetObjectPropValue;
1914 ptp.Nparam = 2;
1915 ptp.Param1 = oid;
1916 ptp.Param2 = opc;
1917 size = ptp_pack_DPV(params, value, &data, datatype);
Linus Walleijf67bca92006-05-29 09:33:39 +00001918 ret = ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, &data, NULL);
Linus Walleijb02a0662006-04-25 08:05:09 +00001919 free(data);
1920 return ret;
1921}
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001922
Linus Walleijf67bca92006-05-29 09:33:39 +00001923uint16_t
1924ptp_mtp_getobjectreferences (PTPParams* params, uint32_t handle, uint32_t** ohArray, uint32_t* arraylen)
1925{
1926 PTPContainer ptp;
1927 uint16_t ret;
1928 unsigned char* dpv=NULL;
1929
1930 PTP_CNT_INIT(ptp);
1931 ptp.Code=PTP_OC_MTP_GetObjectReferences;
1932 ptp.Param1=handle;
1933 ptp.Nparam=1;
1934 ret=ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &dpv, NULL);
1935 if (ret == PTP_RC_OK) *arraylen = ptp_unpack_uint32_t_array(params, dpv, 0, ohArray);
1936 free(dpv);
1937 return ret;
1938}
1939
1940uint16_t
1941ptp_mtp_setobjectreferences (PTPParams* params, uint32_t handle, uint32_t* ohArray, uint32_t arraylen)
1942{
1943 PTPContainer ptp;
1944 uint16_t ret;
1945 uint32_t size;
1946 unsigned char* dpv=NULL;
1947
1948 PTP_CNT_INIT(ptp);
1949 ptp.Code = PTP_OC_MTP_SetObjectReferences;
1950 ptp.Param1 = handle;
1951 ptp.Nparam = 1;
1952 size = ptp_pack_uint32_t_array(params, ohArray, arraylen, &dpv);
1953 ret = ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, (unsigned char **)&dpv, NULL);
1954 free(dpv);
1955 return ret;
1956}
1957
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001958/* Non PTP protocol functions */
1959/* devinfo testing functions */
1960
1961int
1962ptp_operation_issupported(PTPParams* params, uint16_t operation)
1963{
1964 int i=0;
1965
1966 for (;i<params->deviceinfo.OperationsSupported_len;i++) {
1967 if (params->deviceinfo.OperationsSupported[i]==operation)
1968 return 1;
1969 }
1970 return 0;
1971}
1972
1973
1974int
Linus Walleijb02a0662006-04-25 08:05:09 +00001975ptp_event_issupported(PTPParams* params, uint16_t event)
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001976{
1977 int i=0;
1978
Linus Walleijb02a0662006-04-25 08:05:09 +00001979 for (;i<params->deviceinfo.EventsSupported_len;i++) {
1980 if (params->deviceinfo.EventsSupported[i]==event)
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001981 return 1;
1982 }
1983 return 0;
1984}
1985
Linus Walleijb02a0662006-04-25 08:05:09 +00001986
1987int
1988ptp_property_issupported(PTPParams* params, uint16_t property)
1989{
1990 int i=0;
1991
1992 for (;i<params->deviceinfo.DevicePropertiesSupported_len;i++)
1993 if (params->deviceinfo.DevicePropertiesSupported[i]==property)
1994 return 1;
1995 return 0;
1996}
1997
1998/* ptp structures freeing functions */
1999void
2000ptp_free_devicepropvalue(uint16_t dt, PTPPropertyValue* dpd) {
2001 switch (dt) {
2002 case PTP_DTC_INT8: case PTP_DTC_UINT8:
2003 case PTP_DTC_UINT16: case PTP_DTC_INT16:
2004 case PTP_DTC_UINT32: case PTP_DTC_INT32:
2005 case PTP_DTC_UINT64: case PTP_DTC_INT64:
2006 case PTP_DTC_UINT128: case PTP_DTC_INT128:
2007 /* Nothing to free */
2008 break;
2009 case PTP_DTC_AINT8: case PTP_DTC_AUINT8:
2010 case PTP_DTC_AUINT16: case PTP_DTC_AINT16:
2011 case PTP_DTC_AUINT32: case PTP_DTC_AINT32:
2012 case PTP_DTC_AUINT64: case PTP_DTC_AINT64:
2013 case PTP_DTC_AUINT128: case PTP_DTC_AINT128:
2014 if (dpd->a.v)
2015 free(dpd->a.v);
2016 break;
2017 case PTP_DTC_STR:
2018 if (dpd->str)
2019 free(dpd->str);
2020 break;
Linus Walleij16c51f02006-05-04 13:20:22 +00002021 case PTP_DTC_UNISTR:
2022 if (dpd->unistr)
2023 free(dpd->unistr);
2024 break;
Linus Walleijb02a0662006-04-25 08:05:09 +00002025 }
2026}
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002027
2028void
2029ptp_free_devicepropdesc(PTPDevicePropDesc* dpd)
2030{
2031 uint16_t i;
2032
Linus Walleijb02a0662006-04-25 08:05:09 +00002033 ptp_free_devicepropvalue (dpd->DataType, &dpd->FactoryDefaultValue);
2034 ptp_free_devicepropvalue (dpd->DataType, &dpd->CurrentValue);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002035 switch (dpd->FormFlag) {
Linus Walleijb02a0662006-04-25 08:05:09 +00002036 case PTP_DPFF_Range:
2037 ptp_free_devicepropvalue (dpd->DataType, &dpd->FORM.Range.MinimumValue);
2038 ptp_free_devicepropvalue (dpd->DataType, &dpd->FORM.Range.MaximumValue);
2039 ptp_free_devicepropvalue (dpd->DataType, &dpd->FORM.Range.StepSize);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002040 break;
Linus Walleijb02a0662006-04-25 08:05:09 +00002041 case PTP_DPFF_Enumeration:
2042 if (dpd->FORM.Enum.SupportedValue) {
2043 for (i=0;i<dpd->FORM.Enum.NumberOfValues;i++)
2044 ptp_free_devicepropvalue (dpd->DataType, dpd->FORM.Enum.SupportedValue+i);
2045 free (dpd->FORM.Enum.SupportedValue);
2046 }
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002047 }
2048}
2049
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002050void
Linus Walleijb02a0662006-04-25 08:05:09 +00002051ptp_free_objectpropdesc(PTPObjectPropDesc* opd)
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002052{
Linus Walleijb02a0662006-04-25 08:05:09 +00002053 uint16_t i;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002054
Linus Walleijb02a0662006-04-25 08:05:09 +00002055 ptp_free_devicepropvalue (opd->DataType, &opd->FactoryDefaultValue);
2056 switch (opd->FormFlag) {
2057 case PTP_OPFF_None:
2058 break;
2059 case PTP_OPFF_Range:
2060 ptp_free_devicepropvalue (opd->DataType, &opd->FORM.Range.MinimumValue);
2061 ptp_free_devicepropvalue (opd->DataType, &opd->FORM.Range.MaximumValue);
2062 ptp_free_devicepropvalue (opd->DataType, &opd->FORM.Range.StepSize);
2063 break;
2064 case PTP_OPFF_Enumeration:
2065 if (opd->FORM.Enum.SupportedValue) {
2066 for (i=0;i<opd->FORM.Enum.NumberOfValues;i++)
2067 ptp_free_devicepropvalue (opd->DataType, opd->FORM.Enum.SupportedValue+i);
2068 free (opd->FORM.Enum.SupportedValue);
2069 }
2070 default:
2071 fprintf (stderr, "Unknown OPFF type %d\n", opd->FormFlag);
2072 break;
2073 }
2074}
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002075
2076void
2077ptp_perror(PTPParams* params, uint16_t error) {
2078
2079 int i;
2080 /* PTP error descriptions */
2081 static struct {
Linus Walleijb02a0662006-04-25 08:05:09 +00002082 short n;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002083 const char *txt;
2084 } ptp_errors[] = {
2085 {PTP_RC_Undefined, N_("PTP: Undefined Error")},
2086 {PTP_RC_OK, N_("PTP: OK!")},
2087 {PTP_RC_GeneralError, N_("PTP: General Error")},
2088 {PTP_RC_SessionNotOpen, N_("PTP: Session Not Open")},
2089 {PTP_RC_InvalidTransactionID, N_("PTP: Invalid Transaction ID")},
2090 {PTP_RC_OperationNotSupported, N_("PTP: Operation Not Supported")},
2091 {PTP_RC_ParameterNotSupported, N_("PTP: Parameter Not Supported")},
2092 {PTP_RC_IncompleteTransfer, N_("PTP: Incomplete Transfer")},
2093 {PTP_RC_InvalidStorageId, N_("PTP: Invalid Storage ID")},
2094 {PTP_RC_InvalidObjectHandle, N_("PTP: Invalid Object Handle")},
2095 {PTP_RC_DevicePropNotSupported, N_("PTP: Device Prop Not Supported")},
2096 {PTP_RC_InvalidObjectFormatCode, N_("PTP: Invalid Object Format Code")},
2097 {PTP_RC_StoreFull, N_("PTP: Store Full")},
2098 {PTP_RC_ObjectWriteProtected, N_("PTP: Object Write Protected")},
2099 {PTP_RC_StoreReadOnly, N_("PTP: Store Read Only")},
2100 {PTP_RC_AccessDenied, N_("PTP: Access Denied")},
2101 {PTP_RC_NoThumbnailPresent, N_("PTP: No Thumbnail Present")},
2102 {PTP_RC_SelfTestFailed, N_("PTP: Self Test Failed")},
2103 {PTP_RC_PartialDeletion, N_("PTP: Partial Deletion")},
2104 {PTP_RC_StoreNotAvailable, N_("PTP: Store Not Available")},
2105 {PTP_RC_SpecificationByFormatUnsupported,
2106 N_("PTP: Specification By Format Unsupported")},
2107 {PTP_RC_NoValidObjectInfo, N_("PTP: No Valid Object Info")},
2108 {PTP_RC_InvalidCodeFormat, N_("PTP: Invalid Code Format")},
2109 {PTP_RC_UnknownVendorCode, N_("PTP: Unknown Vendor Code")},
2110 {PTP_RC_CaptureAlreadyTerminated,
2111 N_("PTP: Capture Already Terminated")},
Linus Walleijb02a0662006-04-25 08:05:09 +00002112 {PTP_RC_DeviceBusy, N_("PTP: Device Busy")},
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002113 {PTP_RC_InvalidParentObject, N_("PTP: Invalid Parent Object")},
2114 {PTP_RC_InvalidDevicePropFormat, N_("PTP: Invalid Device Prop Format")},
2115 {PTP_RC_InvalidDevicePropValue, N_("PTP: Invalid Device Prop Value")},
2116 {PTP_RC_InvalidParameter, N_("PTP: Invalid Parameter")},
2117 {PTP_RC_SessionAlreadyOpened, N_("PTP: Session Already Opened")},
2118 {PTP_RC_TransactionCanceled, N_("PTP: Transaction Canceled")},
2119 {PTP_RC_SpecificationOfDestinationUnsupported,
2120 N_("PTP: Specification Of Destination Unsupported")},
Linus Walleijb02a0662006-04-25 08:05:09 +00002121 {PTP_RC_EK_FilenameRequired, N_("PTP: EK Filename Required")},
2122 {PTP_RC_EK_FilenameConflicts, N_("PTP: EK Filename Conflicts")},
2123 {PTP_RC_EK_FilenameInvalid, N_("PTP: EK Filename Invalid")},
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002124
2125 {PTP_ERROR_IO, N_("PTP: I/O error")},
2126 {PTP_ERROR_BADPARAM, N_("PTP: Error: bad parameter")},
2127 {PTP_ERROR_DATA_EXPECTED, N_("PTP: Protocol error, data expected")},
2128 {PTP_ERROR_RESP_EXPECTED, N_("PTP: Protocol error, response expected")},
2129 {0, NULL}
Linus Walleijb02a0662006-04-25 08:05:09 +00002130};
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002131
2132 for (i=0; ptp_errors[i].txt!=NULL; i++)
Linus Walleijb02a0662006-04-25 08:05:09 +00002133 if (ptp_errors[i].n == error)
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002134 ptp_error(params, ptp_errors[i].txt);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002135}
2136
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002137const char*
Linus Walleijb02a0662006-04-25 08:05:09 +00002138ptp_get_property_description(PTPParams* params, uint16_t dpc)
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002139{
2140 int i;
Linus Walleijb02a0662006-04-25 08:05:09 +00002141 // Device Property descriptions
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002142 struct {
2143 uint16_t dpc;
2144 const char *txt;
2145 } ptp_device_properties[] = {
Linus Walleijb02a0662006-04-25 08:05:09 +00002146 {PTP_DPC_Undefined, N_("Undefined PTP Property")},
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002147 {PTP_DPC_BatteryLevel, N_("Battery Level")},
2148 {PTP_DPC_FunctionalMode, N_("Functional Mode")},
2149 {PTP_DPC_ImageSize, N_("Image Size")},
2150 {PTP_DPC_CompressionSetting, N_("Compression Setting")},
2151 {PTP_DPC_WhiteBalance, N_("White Balance")},
2152 {PTP_DPC_RGBGain, N_("RGB Gain")},
2153 {PTP_DPC_FNumber, N_("F-Number")},
2154 {PTP_DPC_FocalLength, N_("Focal Length")},
2155 {PTP_DPC_FocusDistance, N_("Focus Distance")},
2156 {PTP_DPC_FocusMode, N_("Focus Mode")},
2157 {PTP_DPC_ExposureMeteringMode, N_("Exposure Metering Mode")},
2158 {PTP_DPC_FlashMode, N_("Flash Mode")},
2159 {PTP_DPC_ExposureTime, N_("Exposure Time")},
2160 {PTP_DPC_ExposureProgramMode, N_("Exposure Program Mode")},
2161 {PTP_DPC_ExposureIndex,
2162 N_("Exposure Index (film speed ISO)")},
2163 {PTP_DPC_ExposureBiasCompensation,
2164 N_("Exposure Bias Compensation")},
2165 {PTP_DPC_DateTime, N_("Date Time")},
2166 {PTP_DPC_CaptureDelay, N_("Pre-Capture Delay")},
2167 {PTP_DPC_StillCaptureMode, N_("Still Capture Mode")},
2168 {PTP_DPC_Contrast, N_("Contrast")},
2169 {PTP_DPC_Sharpness, N_("Sharpness")},
2170 {PTP_DPC_DigitalZoom, N_("Digital Zoom")},
2171 {PTP_DPC_EffectMode, N_("Effect Mode")},
2172 {PTP_DPC_BurstNumber, N_("Burst Number")},
2173 {PTP_DPC_BurstInterval, N_("Burst Interval")},
2174 {PTP_DPC_TimelapseNumber, N_("Timelapse Number")},
2175 {PTP_DPC_TimelapseInterval, N_("Timelapse Interval")},
2176 {PTP_DPC_FocusMeteringMode, N_("Focus Metering Mode")},
2177 {PTP_DPC_UploadURL, N_("Upload URL")},
2178 {PTP_DPC_Artist, N_("Artist")},
2179 {PTP_DPC_CopyrightInfo, N_("Copyright Info")},
2180 {0,NULL}
2181 };
2182 struct {
2183 uint16_t dpc;
2184 const char *txt;
2185 } ptp_device_properties_EK[] = {
Linus Walleijb02a0662006-04-25 08:05:09 +00002186 {PTP_DPC_EK_ColorTemperature, N_("Color Temperature")},
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002187 {PTP_DPC_EK_DateTimeStampFormat,
Linus Walleijb02a0662006-04-25 08:05:09 +00002188 N_("Date Time Stamp Format")},
2189 {PTP_DPC_EK_BeepMode, N_("Beep Mode")},
2190 {PTP_DPC_EK_VideoOut, N_("Video Out")},
2191 {PTP_DPC_EK_PowerSaving, N_("Power Saving")},
2192 {PTP_DPC_EK_UI_Language, N_("UI Language")},
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002193 {0,NULL}
2194 };
2195
2196 struct {
2197 uint16_t dpc;
2198 const char *txt;
Linus Walleijb02a0662006-04-25 08:05:09 +00002199 } ptp_device_properties_Canon[] = {
2200 {PTP_DPC_CANON_BeepMode, N_("Beep Mode")},
2201 {PTP_DPC_CANON_ViewfinderMode, N_("Viewfinder Mode")},
2202 {PTP_DPC_CANON_ImageQuality, N_("Image Quality")},
2203 {PTP_DPC_CANON_ImageSize, N_("Image Size")},
2204 {PTP_DPC_CANON_FlashMode, N_("Flash Mode")},
2205 {PTP_DPC_CANON_ShootingMode, N_("Shooting Mode")},
2206 {PTP_DPC_CANON_MeteringMode, N_("Metering Mode")},
2207 {PTP_DPC_CANON_AFDistance, N_("AF Distance")},
2208 {PTP_DPC_CANON_FocusingPoint, N_("Focusing Point")},
2209 {PTP_DPC_CANON_WhiteBalance, N_("White Balance")},
2210 {PTP_DPC_CANON_ISOSpeed, N_("ISO Speed")},
2211 {PTP_DPC_CANON_Aperture, N_("Aperture")},
2212 {PTP_DPC_CANON_ShutterSpeed, N_("ShutterSpeed")},
2213 {PTP_DPC_CANON_ExpCompensation, N_("Exposure Compensation")},
2214 {PTP_DPC_CANON_Zoom, N_("Zoom")},
2215 {PTP_DPC_CANON_SizeQualityMode, N_("Size Quality Mode")},
2216 {PTP_DPC_CANON_FirmwareVersion, N_("Firmware Version")},
2217 {PTP_DPC_CANON_CameraModel, N_("Camera Model")},
2218 {PTP_DPC_CANON_CameraOwner, N_("Camera Owner")},
2219 {PTP_DPC_CANON_UnixTime, N_("UNIX Time")},
2220 {PTP_DPC_CANON_DZoomMagnification, N_("Digital Zoom Magnification")},
2221 {PTP_DPC_CANON_PhotoEffect, N_("Photo Effect")},
2222 {PTP_DPC_CANON_AssistLight, N_("Assist Light")},
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002223 {0,NULL}
2224 };
Linus Walleijb02a0662006-04-25 08:05:09 +00002225
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002226 struct {
2227 uint16_t dpc;
2228 const char *txt;
Linus Walleijb02a0662006-04-25 08:05:09 +00002229 } ptp_device_properties_Nikon[] = {
2230 {PTP_DPC_NIKON_WhiteBalanceAutoBias, /* 0xD017 */
2231 N_("Auto White Balance Bias")},
2232 {PTP_DPC_NIKON_WhiteBalanceTungstenBias, /* 0xD018 */
2233 N_("Tungsten White Balance Bias")},
2234 {PTP_DPC_NIKON_WhiteBalanceFlourescentBias, /* 0xD019 */
2235 N_("Flourescent White Balance Bias")},
2236 {PTP_DPC_NIKON_WhiteBalanceDaylightBias, /* 0xD01a */
2237 N_("Daylight White Balance Bias")},
2238 {PTP_DPC_NIKON_WhiteBalanceFlashBias, /* 0xD01b */
2239 N_("Flash White Balance Bias")},
2240 {PTP_DPC_NIKON_WhiteBalanceCloudyBias, /* 0xD01c */
2241 N_("Cloudy White Balance Bias")},
2242 {PTP_DPC_NIKON_WhiteBalanceShadeBias, /* 0xD01d */
2243 N_("Shady White Balance Bias")},
2244 {PTP_DPC_NIKON_WhiteBalanceColorTemperature, /* 0xD01e */
2245 N_("White Balance Colour Temperature")},
2246 {PTP_DPC_NIKON_ImageSharpening, /* 0xD02a */
2247 N_("Sharpening")},
2248 {PTP_DPC_NIKON_ToneCompensation, /* 0xD02b */
2249 N_("Tone Compensation")},
2250 {PTP_DPC_NIKON_ColorModel, /* 0xD02c */
2251 N_("Color Model")},
2252 {PTP_DPC_NIKON_HueAdjustment, /* 0xD02d */
2253 N_("Hue Adjustment")},
2254 {PTP_DPC_NIKON_NonCPULensDataFocalLength, /* 0xD02e */
2255 N_("Lens Focal Length (Non CPU)")},
2256 {PTP_DPC_NIKON_NonCPULensDataMaximumAperture, /* 0xD02f */
2257 N_("Lens Max. Aperture (Non CPU)")},
2258 {PTP_DPC_NIKON_CSMMenuBankSelect, /* 0xD040 */
2259 "PTP_DPC_NIKON_CSMMenuBankSelect"},
2260 {PTP_DPC_NIKON_MenuBankNameA, /* 0xD041 */
2261 "PTP_DPC_NIKON_MenuBankNameA"},
2262 {PTP_DPC_NIKON_MenuBankNameB, /* 0xD042 */
2263 "PTP_DPC_NIKON_MenuBankNameB"},
2264 {PTP_DPC_NIKON_MenuBankNameC, /* 0xD043 */
2265 "PTP_DPC_NIKON_MenuBankNameC"},
2266 {PTP_DPC_NIKON_MenuBankNameD, /* 0xD044 */
2267 "PTP_DPC_NIKON_MenuBankNameD"},
2268 {PTP_DPC_NIKON_A1AFCModePriority, /* 0xD048 */
2269 "PTP_DPC_NIKON_A1AFCModePriority"},
2270 {PTP_DPC_NIKON_A2AFSModePriority, /* 0xD049 */
2271 "PTP_DPC_NIKON_A2AFSModePriority"},
2272 {PTP_DPC_NIKON_A3GroupDynamicAF, /* 0xD04a */
2273 "PTP_DPC_NIKON_A3GroupDynamicAF"},
2274 {PTP_DPC_NIKON_A4AFActivation, /* 0xD04b */
2275 "PTP_DPC_NIKON_A4AFActivation"},
2276 {PTP_DPC_NIKON_A5FocusAreaIllumManualFocus, /* 0xD04c */
2277 "PTP_DPC_NIKON_A5FocusAreaIllumManualFocus"},
2278 {PTP_DPC_NIKON_FocusAreaIllumContinuous, /* 0xD04d */
2279 "PTP_DPC_NIKON_FocusAreaIllumContinuous"},
2280 {PTP_DPC_NIKON_FocusAreaIllumWhenSelected, /* 0xD04e */
2281 "PTP_DPC_NIKON_FocusAreaIllumWhenSelected"},
2282 {PTP_DPC_NIKON_FocusAreaWrap, /* 0xD04f */
2283 N_("Focus Area Wrap")},
2284 {PTP_DPC_NIKON_A7VerticalAFON, /* 0xD050 */
2285 N_("Vertical AF On")},
2286 {PTP_DPC_NIKON_ISOAuto, /* 0xD054 */
2287 N_("Auto ISO")},
2288 {PTP_DPC_NIKON_B2ISOStep, /* 0xD055 */
2289 N_("ISO Step")},
2290 {PTP_DPC_NIKON_EVStep, /* 0xD056 */
2291 N_("Exposure Step")},
2292 {PTP_DPC_NIKON_B4ExposureCompEv, /* 0xD057 */
2293 N_("Exposure Compensation (EV)")},
2294 {PTP_DPC_NIKON_ExposureCompensation, /* 0xD058 */
2295 N_("Exposure Compensation")},
2296 {PTP_DPC_NIKON_CenterWeightArea, /* 0xD059 */
2297 N_("Centre Weight Area")},
2298 {PTP_DPC_NIKON_AELockMode, /* 0xD05e */
2299 N_("Exposure Lock")},
2300 {PTP_DPC_NIKON_AELAFLMode, /* 0xD05f */
2301 N_("Focus Lock")},
2302 {PTP_DPC_NIKON_MeterOff, /* 0xD062 */
2303 N_("Auto Meter Off Time")},
2304 {PTP_DPC_NIKON_SelfTimer, /* 0xD063 */
2305 N_("Self Timer Delay")},
2306 {PTP_DPC_NIKON_MonitorOff, /* 0xD064 */
2307 N_("LCD Off Time")},
2308 {PTP_DPC_NIKON_D1ShootingSpeed, /* 0xD068 */
2309 N_("Shooting Speed")},
2310 {PTP_DPC_NIKON_D2MaximumShots, /* 0xD069 */
2311 N_("Max. Shots")},
2312 {PTP_DPC_NIKON_D3ExpDelayMode, /* 0xD06a */
Linus Walleijd208f9c2006-04-27 14:16:06 +00002313 "PTP_DPC_NIKON_D3ExpDelayMode"},
Linus Walleijb02a0662006-04-25 08:05:09 +00002314 {PTP_DPC_NIKON_LongExposureNoiseReduction, /* 0xD06b */
2315 N_("Long Exposure Noise Reduction")},
2316 {PTP_DPC_NIKON_FileNumberSequence, /* 0xD06c */
2317 N_("File Number Sequencing")},
2318 {PTP_DPC_NIKON_D6ControlPanelFinderRearControl, /* 0xD06d */
Linus Walleijd208f9c2006-04-27 14:16:06 +00002319 "PTP_DPC_NIKON_D6ControlPanelFinderRearControl"},
Linus Walleijb02a0662006-04-25 08:05:09 +00002320 {PTP_DPC_NIKON_ControlPanelFinderViewfinder, /* 0xD06e */
Linus Walleijd208f9c2006-04-27 14:16:06 +00002321 "PTP_DPC_NIKON_ControlPanelFinderViewfinder"},
Linus Walleijb02a0662006-04-25 08:05:09 +00002322 {PTP_DPC_NIKON_D7Illumination, /* 0xD06f */
Linus Walleijd208f9c2006-04-27 14:16:06 +00002323 "PTP_DPC_NIKON_D7Illumination"},
Linus Walleijb02a0662006-04-25 08:05:09 +00002324 {PTP_DPC_NIKON_E1FlashSyncSpeed, /* 0xD074 */
2325 N_("Flash Sync. Speed")},
2326 {PTP_DPC_NIKON_FlashShutterSpeed, /* 0xD075 */
2327 N_("Flash Shutter Speed")},
2328 {PTP_DPC_NIKON_E3AAFlashMode, /* 0xD076 */
2329 N_("Flash Mode")},
2330 {PTP_DPC_NIKON_E4ModelingFlash, /* 0xD077 */
2331 N_("Modeling Flash")},
2332 {PTP_DPC_NIKON_BracketSet, /* 0xD078 */
2333 N_("Bracket Set")},
2334 {PTP_DPC_NIKON_E6ManualModeBracketing, /* 0xD079 */
2335 N_("Manual Mode Bracketing")},
2336 {PTP_DPC_NIKON_BracketOrder, /* 0xD07a */
2337 N_("Bracket Order")},
2338 {PTP_DPC_NIKON_E8AutoBracketSelection, /* 0xD07b */
2339 N_("Auto Bracket Selection")},
2340 {PTP_DPC_NIKON_F1CenterButtonShootingMode, /* 0xD080 */
2341 N_("Center Button Shooting Mode")},
2342 {PTP_DPC_NIKON_CenterButtonPlaybackMode, /* 0xD081 */
2343 N_("Center Button Playback Mode")},
2344 {PTP_DPC_NIKON_F2Multiselector, /* 0xD082 */
2345 N_("Multiselector")},
2346 {PTP_DPC_NIKON_F3PhotoInfoPlayback, /* 0xD083 */
2347 N_("Photo Info. Playback")},
2348 {PTP_DPC_NIKON_F4AssignFuncButton, /* 0xD084 */
2349 N_("Assign Func. Button")},
2350 {PTP_DPC_NIKON_F5CustomizeCommDials, /* 0xD085 */
2351 N_("Customise Command Dials")},
2352 {PTP_DPC_NIKON_ReverseCommandDial, /* 0xD086 */
2353 N_("Reverse Command Dial")},
2354 {PTP_DPC_NIKON_ApertureSetting, /* 0xD087 */
2355 N_("Aperture Setting")},
2356 {PTP_DPC_NIKON_MenusAndPlayback, /* 0xD088 */
2357 N_("Menus and Playback")},
2358 {PTP_DPC_NIKON_F6ButtonsAndDials, /* 0xD089 */
2359 N_("Buttons and Dials")},
2360 {PTP_DPC_NIKON_NoCFCard, /* 0xD08a */
2361 N_("No CF Card Release")},
2362 {PTP_DPC_NIKON_ImageRotation, /* 0xD092 */
2363 N_("Image Rotation")},
2364 {PTP_DPC_NIKON_Bracketing, /* 0xD0c0 */
2365 N_("Exposure Bracketing")},
2366 {PTP_DPC_NIKON_ExposureBracketingIntervalDist, /* 0xD0c1 */
2367 N_("Exposure Bracketing Distance")},
2368 {PTP_DPC_NIKON_BracketingProgram, /* 0xD0c2 */
2369 N_("Exposure Bracketing Number")},
2370 {PTP_DPC_NIKON_AutofocusLCDTopMode2, /* 0xD107 */
2371 N_("AF LCD Top Mode 2")},
2372 {PTP_DPC_NIKON_AutofocusArea, /* 0xD108 */
2373 N_("Active AF Sensor")},
2374 {PTP_DPC_NIKON_LightMeter, /* 0xD10a */
2375 N_("Exposure Meter")},
2376 {PTP_DPC_NIKON_ExposureApertureLock, /* 0xD111 */
2377 N_("Exposure Aperture Lock")},
2378 {PTP_DPC_NIKON_MaximumShots, /* 0xD103 */
2379 N_("Maximum Shots")},
2380 {PTP_DPC_NIKON_OptimizeImage, /* 0xD140 */
2381 N_("Optimize Image")},
2382 {PTP_DPC_NIKON_Saturation, /* 0xD142 */
2383 N_("Saturation")},
2384 {PTP_DPC_NIKON_CSMMenu, /* 0xD180 */
2385 N_("CSM Menu")},
2386 {PTP_DPC_NIKON_BeepOff,
2387 N_("AF Beep Mode")},
2388 {PTP_DPC_NIKON_AutofocusMode,
2389 N_("Autofocus Mode")},
2390 {PTP_DPC_NIKON_AFAssist,
2391 N_("AF Assist Lamp")},
2392 {PTP_DPC_NIKON_PADVPMode,
2393 N_("Auto ISO P/A/DVP Setting")},
2394 {PTP_DPC_NIKON_ImageReview,
2395 N_("Image Review")},
2396 {PTP_DPC_NIKON_GridDisplay,
2397 N_("Viewfinder Grid Display")},
2398 {PTP_DPC_NIKON_AFAreaIllumination,
2399 N_("AF Area Illumination")},
2400 {PTP_DPC_NIKON_FlashMode,
2401 N_("Flash Mode")},
2402 {PTP_DPC_NIKON_FlashModeManualPower,
2403 N_("Flash Mode Manual Power")},
2404 {PTP_DPC_NIKON_FlashSign,
2405 N_("Flash Sign")},
2406 {PTP_DPC_NIKON_FlashExposureCompensation,
2407 N_("Flash Exposure Compensation")},
2408 {PTP_DPC_NIKON_RemoteTimeout,
2409 N_("Remote Timeout")},
2410 {PTP_DPC_NIKON_ImageCommentString,
2411 N_("Image Comment String")},
2412 {PTP_DPC_NIKON_FlashOpen,
2413 N_("Flash Open")},
2414 {PTP_DPC_NIKON_FlashCharged,
2415 N_("Flash Charged")},
2416 {PTP_DPC_NIKON_LensID,
2417 N_("Lens ID")},
2418 {PTP_DPC_NIKON_FocalLengthMin,
2419 N_("Min. Focal Length")},
2420 {PTP_DPC_NIKON_FocalLengthMax,
2421 N_("Max. Focal Length")},
2422 {PTP_DPC_NIKON_MaxApAtMinFocalLength,
2423 N_("Max. Aperture at Min. Focal Length")},
2424 {PTP_DPC_NIKON_MaxApAtMaxFocalLength,
2425 N_("Max. Aperture at Max. Focal Length")},
2426 {PTP_DPC_NIKON_LowLight,
2427 N_("Low Light")},
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002428 {0,NULL}
2429 };
2430
2431 for (i=0; ptp_device_properties[i].txt!=NULL; i++)
2432 if (ptp_device_properties[i].dpc==dpc)
2433 return (ptp_device_properties[i].txt);
2434
Linus Walleijb02a0662006-04-25 08:05:09 +00002435 if (params->deviceinfo.VendorExtensionID==PTP_VENDOR_EASTMAN_KODAK)
2436 for (i=0; ptp_device_properties_EK[i].txt!=NULL; i++)
2437 if (ptp_device_properties_EK[i].dpc==dpc)
2438 return (ptp_device_properties_EK[i].txt);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002439
Linus Walleijb02a0662006-04-25 08:05:09 +00002440 if (params->deviceinfo.VendorExtensionID==PTP_VENDOR_CANON)
2441 for (i=0; ptp_device_properties_Canon[i].txt!=NULL; i++)
2442 if (ptp_device_properties_Canon[i].dpc==dpc)
2443 return (ptp_device_properties_Canon[i].txt);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002444
Linus Walleijb02a0662006-04-25 08:05:09 +00002445 if (params->deviceinfo.VendorExtensionID==PTP_VENDOR_NIKON)
2446 for (i=0; ptp_device_properties_Nikon[i].txt!=NULL; i++)
2447 if (ptp_device_properties_Nikon[i].dpc==dpc)
2448 return (ptp_device_properties_Nikon[i].txt);
2449
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002450 return NULL;
2451}
2452
Linus Walleijb02a0662006-04-25 08:05:09 +00002453static int64_t
2454_value_to_num(PTPPropertyValue *data, uint16_t dt) {
2455 if (dt == PTP_DTC_STR) {
2456 if (!data->str)
2457 return 0;
2458 return atol(data->str);
2459 }
2460 if (dt & PTP_DTC_ARRAY_MASK) {
2461 return 0;
2462 } else {
2463 switch (dt) {
2464 case PTP_DTC_UNDEF:
2465 return 0;
2466 case PTP_DTC_INT8:
2467 return data->i8;
2468 case PTP_DTC_UINT8:
2469 return data->u8;
2470 case PTP_DTC_INT16:
2471 return data->i16;
2472 case PTP_DTC_UINT16:
2473 return data->u16;
2474 case PTP_DTC_INT32:
2475 return data->i32;
2476 case PTP_DTC_UINT32:
2477 return data->u32;
2478 /*
2479 PTP_DTC_INT64
2480 PTP_DTC_UINT64
2481 PTP_DTC_INT128
2482 PTP_DTC_UINT128
2483 */
2484 default:
2485 return 0;
2486 }
2487 }
2488
2489 return 0;
2490}
2491
2492#define PTP_VAL_BOOL(dpc) {dpc, 0, N_("Off")}, {dpc, 1, N_("On")}
2493#define PTP_VAL_RBOOL(dpc) {dpc, 0, N_("On")}, {dpc, 1, N_("Off")}
2494#define PTP_VAL_YN(dpc) {dpc, 0, N_("No")}, {dpc, 1, N_("Yes")}
2495
2496int
2497ptp_render_property_value(PTPParams* params, uint16_t dpc,
2498 PTPDevicePropDesc *dpd, int length, char *out)
2499{
2500 int i;
2501
2502 struct {
2503 uint16_t dpc;
2504 double coef;
2505 double bias;
2506 const char *format;
2507 } ptp_value_trans[] = {
2508 {PTP_DPC_ExposureIndex, 1.0, 0.0, "ISO %.0f"},
2509 {0, 0.0, 0.0, NULL}
2510 };
2511
2512 struct {
2513 uint16_t dpc;
2514 double coef;
2515 double bias;
2516 const char *format;
2517 } ptp_value_trans_Nikon[] = {
2518 {PTP_DPC_BatteryLevel, 1.0, 0.0, "%.0f%%"},
2519 {PTP_DPC_FNumber, 0.01, 0.0, "f/%.2g"},
2520 {PTP_DPC_FocalLength, 0.01, 0.0, "%.0f mm"},
2521 {PTP_DPC_ExposureTime, 0.00001, 0.0, "%.2g sec"},
2522 {PTP_DPC_ExposureBiasCompensation, 0.001, 0.0, N_("%.1f stops")},
2523 {PTP_DPC_NIKON_LightMeter, 0.08333, 0.0, N_("%.1f stops")},
2524 {PTP_DPC_NIKON_FlashExposureCompensation, 0.16666, 0.0, N_("%.1f stops")},
2525 {PTP_DPC_NIKON_CenterWeightArea, 2.0, 6.0, N_("%.0f mm")},
2526 {PTP_DPC_NIKON_FocalLengthMin, 0.01, 0.0, "%.0f mm"},
2527 {PTP_DPC_NIKON_FocalLengthMax, 0.01, 0.0, "%.0f mm"},
2528 {PTP_DPC_NIKON_MaxApAtMinFocalLength, 0.01, 0.0, "f/%.2g"},
2529 {PTP_DPC_NIKON_MaxApAtMaxFocalLength, 0.01, 0.0, "f/%.2g"},
2530 {0, 0.0, 0.0, NULL}
2531 };
2532
2533 struct {
2534 uint16_t dpc;
2535 int64_t key;
2536 char *value;
2537 } ptp_value_list_Nikon[] = {
2538 {PTP_DPC_CompressionSetting, 0, N_("JPEG Basic")},
2539 {PTP_DPC_CompressionSetting, 1, N_("JPEG Norm")},
2540 {PTP_DPC_CompressionSetting, 2, N_("JPEG Fine")},
2541 {PTP_DPC_CompressionSetting, 4, N_("RAW")},
2542 {PTP_DPC_CompressionSetting, 5, N_("RAW + JPEG Basic")},
2543 {PTP_DPC_WhiteBalance, 2, N_("Auto")},
2544 {PTP_DPC_WhiteBalance, 6, N_("Incandescent")},
2545 {PTP_DPC_WhiteBalance, 5, N_("Fluorescent")},
2546 {PTP_DPC_WhiteBalance, 4, N_("Daylight")},
2547 {PTP_DPC_WhiteBalance, 7, N_("Flash")},
2548 {PTP_DPC_WhiteBalance, 32784, N_("Cloudy")},
2549 {PTP_DPC_WhiteBalance, 32785, N_("Shade")},
2550 {PTP_DPC_WhiteBalance, 32787, N_("Preset")},
2551 {PTP_DPC_FlashMode, 32784, N_("Default")},
2552 {PTP_DPC_FlashMode, 4, N_("Red-eye Reduction")},
2553 {PTP_DPC_FlashMode, 32787, N_("Red-eye Reduction + Slow Sync")},
2554 {PTP_DPC_FlashMode, 32785, N_("Slow Sync")},
2555 {PTP_DPC_FlashMode, 32785, N_("Rear Curtain Sync + Slow Sync")},
2556 {PTP_DPC_FocusMeteringMode, 2, N_("Dynamic Area")},
2557 {PTP_DPC_FocusMeteringMode, 32784, N_("Single Area")},
2558 {PTP_DPC_FocusMeteringMode, 32785, N_("Closest Subject")},
2559 {PTP_DPC_FocusMode, 1, N_("Manual Focus")},
2560 {PTP_DPC_FocusMode, 32784, "AF-S"},
2561 {PTP_DPC_FocusMode, 32785, "AF-C"},
2562 PTP_VAL_BOOL(PTP_DPC_NIKON_ISOAuto),
2563 PTP_VAL_BOOL(PTP_DPC_NIKON_ExposureCompensation),
2564 PTP_VAL_BOOL(PTP_DPC_NIKON_AELockMode),
2565 {PTP_DPC_NIKON_AELAFLMode, 0, N_("AE/AF Lock")},
2566 {PTP_DPC_NIKON_AELAFLMode, 1, N_("AF Lock only")},
2567 {PTP_DPC_NIKON_AELAFLMode, 2, N_("AE Lock only")},
2568 {PTP_DPC_NIKON_AELAFLMode, 3, N_("AF Lock Hold")},
2569 {PTP_DPC_NIKON_AELAFLMode, 4, N_("AF On")},
2570 {PTP_DPC_NIKON_AELAFLMode, 5, N_("Flash Lock")},
2571 {PTP_DPC_ExposureMeteringMode, 2, N_("Center Weighted")},
2572 {PTP_DPC_ExposureMeteringMode, 3, N_("Matrix")},
2573 {PTP_DPC_ExposureMeteringMode, 4, N_("Spot")},
2574 {PTP_DPC_ExposureProgramMode, 1, "M"},
2575 {PTP_DPC_ExposureProgramMode, 3, "A"},
2576 {PTP_DPC_ExposureProgramMode, 4, "S"},
2577 {PTP_DPC_ExposureProgramMode, 2, "P"},
2578 {PTP_DPC_ExposureProgramMode, 32784, N_("Auto")},
2579 {PTP_DPC_ExposureProgramMode, 32785, N_("Portrait")},
2580 {PTP_DPC_ExposureProgramMode, 32786, N_("Landscape")},
2581 {PTP_DPC_ExposureProgramMode, 32787, N_("Macro")},
2582 {PTP_DPC_ExposureProgramMode, 32788, N_("Sports")},
2583 {PTP_DPC_ExposureProgramMode, 32790, N_("Night Landscape")},
2584 {PTP_DPC_ExposureProgramMode, 32789, N_("Night Portrait")},
2585 {PTP_DPC_StillCaptureMode, 1, N_("Single Shot")},
2586 {PTP_DPC_StillCaptureMode, 2, N_("Power Wind")},
2587 {PTP_DPC_StillCaptureMode, 32785, N_("Timer")},
2588 {PTP_DPC_StillCaptureMode, 32787, N_("Remote")},
2589 {PTP_DPC_StillCaptureMode, 32788, N_("Timer + Remote")},
2590 PTP_VAL_BOOL(PTP_DPC_NIKON_AutofocusMode),
2591 PTP_VAL_RBOOL(PTP_DPC_NIKON_AFAssist),
2592 PTP_VAL_RBOOL(PTP_DPC_NIKON_ImageReview),
2593 PTP_VAL_BOOL(PTP_DPC_NIKON_GridDisplay),
2594 {PTP_DPC_NIKON_AFAreaIllumination, 0, N_("Auto")},
2595 {PTP_DPC_NIKON_AFAreaIllumination, 1, N_("Off")},
2596 {PTP_DPC_NIKON_AFAreaIllumination, 2, N_("On")},
2597 {PTP_DPC_NIKON_ColorModel, 0, "sRGB"},
2598 {PTP_DPC_NIKON_ColorModel, 1, "AdobeRGB"},
2599 {PTP_DPC_NIKON_ColorModel, 2, "sRGB"},
2600 {PTP_DPC_NIKON_FlashMode, 0, "iTTL"},
2601 {PTP_DPC_NIKON_FlashMode, 1, N_("Manual")},
2602 {PTP_DPC_NIKON_FlashMode, 2, N_("Commander")},
2603 {PTP_DPC_NIKON_FlashModeManualPower, 0, N_("Full")},
2604 {PTP_DPC_NIKON_FlashModeManualPower, 1, "1/2"},
2605 {PTP_DPC_NIKON_FlashModeManualPower, 2, "1/4"},
2606 {PTP_DPC_NIKON_FlashModeManualPower, 3, "1/8"},
2607 {PTP_DPC_NIKON_FlashModeManualPower, 4, "1/16"},
2608 PTP_VAL_RBOOL(PTP_DPC_NIKON_FlashSign),
2609 {PTP_DPC_NIKON_RemoteTimeout, 0, N_("1 min")},
2610 {PTP_DPC_NIKON_RemoteTimeout, 1, N_("5 mins")},
2611 {PTP_DPC_NIKON_RemoteTimeout, 2, N_("10 mins")},
2612 {PTP_DPC_NIKON_RemoteTimeout, 3, N_("15 mins")},
2613 PTP_VAL_YN(PTP_DPC_NIKON_FlashOpen),
2614 PTP_VAL_YN(PTP_DPC_NIKON_FlashCharged),
2615 PTP_VAL_BOOL(PTP_DPC_NIKON_LongExposureNoiseReduction),
2616 PTP_VAL_BOOL(PTP_DPC_NIKON_FileNumberSequence),
2617 PTP_VAL_BOOL(PTP_DPC_NIKON_ReverseCommandDial),
2618 PTP_VAL_RBOOL(PTP_DPC_NIKON_NoCFCard),
2619 PTP_VAL_RBOOL(PTP_DPC_NIKON_ImageRotation),
2620 PTP_VAL_BOOL(PTP_DPC_NIKON_Bracketing),
2621 {PTP_DPC_NIKON_AutofocusArea, 0, N_("Centre")},
2622 {PTP_DPC_NIKON_AutofocusArea, 1, N_("Top")},
2623 {PTP_DPC_NIKON_AutofocusArea, 2, N_("Bottom")},
2624 {PTP_DPC_NIKON_AutofocusArea, 3, N_("Left")},
2625 {PTP_DPC_NIKON_AutofocusArea, 4, N_("Right")},
2626 {PTP_DPC_NIKON_OptimizeImage, 0, N_("Normal")},
2627 {PTP_DPC_NIKON_OptimizeImage, 1, N_("Vivid")},
2628 {PTP_DPC_NIKON_OptimizeImage, 2, N_("Sharper")},
2629 {PTP_DPC_NIKON_OptimizeImage, 3, N_("Softer")},
2630 {PTP_DPC_NIKON_OptimizeImage, 4, N_("Direct Print")},
2631 {PTP_DPC_NIKON_OptimizeImage, 5, N_("Portrait")},
2632 {PTP_DPC_NIKON_OptimizeImage, 6, N_("Landscape")},
2633 {PTP_DPC_NIKON_OptimizeImage, 7, N_("Custom")},
2634
2635 {PTP_DPC_NIKON_ImageSharpening, 0, N_("Auto")},
2636 {PTP_DPC_NIKON_ImageSharpening, 1, N_("Normal")},
2637 {PTP_DPC_NIKON_ImageSharpening, 2, N_("Low")},
2638 {PTP_DPC_NIKON_ImageSharpening, 3, N_("Medium Low")},
2639 {PTP_DPC_NIKON_ImageSharpening, 4, N_("Medium high")},
2640 {PTP_DPC_NIKON_ImageSharpening, 5, N_("High")},
2641 {PTP_DPC_NIKON_ImageSharpening, 6, N_("None")},
2642
2643 {PTP_DPC_NIKON_ToneCompensation, 0, N_("Auto")},
2644 {PTP_DPC_NIKON_ToneCompensation, 1, N_("Normal")},
2645 {PTP_DPC_NIKON_ToneCompensation, 2, N_("Low contrast")},
2646 {PTP_DPC_NIKON_ToneCompensation, 3, N_("Medium low")},
2647 {PTP_DPC_NIKON_ToneCompensation, 4, N_("Medium high")},
2648 {PTP_DPC_NIKON_ToneCompensation, 5, N_("High control")},
2649 {PTP_DPC_NIKON_ToneCompensation, 6, N_("Custom")},
2650
2651 {PTP_DPC_NIKON_Saturation, 0, N_("Normal")},
2652 {PTP_DPC_NIKON_Saturation, 1, N_("Moderate")},
2653 {PTP_DPC_NIKON_Saturation, 2, N_("Enhanced")},
2654
2655 {PTP_DPC_NIKON_LensID, 0, N_("Unknown")},
2656 {PTP_DPC_NIKON_LensID, 38, "Sigma 70-300mm 1:4-5.6 D APO Macro"},
2657 {PTP_DPC_NIKON_LensID, 83, "AF Nikkor 80-200mm 1:2.8 D ED"},
2658 {PTP_DPC_NIKON_LensID, 118, "AF Nikkor 50mm 1:1.8 D"},
2659 {PTP_DPC_NIKON_LensID, 127, "AF-S Nikkor 18-70mm 1:3.5-4.5G ED DX"},
2660 PTP_VAL_YN(PTP_DPC_NIKON_LowLight),
2661 PTP_VAL_YN(PTP_DPC_NIKON_CSMMenu),
2662 PTP_VAL_RBOOL(PTP_DPC_NIKON_BeepOff),
2663 {0, 0, NULL}
2664 };
2665
2666 if (params->deviceinfo.VendorExtensionID==PTP_VENDOR_NIKON) {
2667 int64_t kval;
2668
2669 for (i=0; ptp_value_trans[i].dpc!=0; i++)
2670 if (ptp_value_trans[i].dpc==dpc) {
2671 double value = _value_to_num(&(dpd->CurrentValue), dpd->DataType);
2672
2673 return snprintf(out, length,
2674 _(ptp_value_trans[i].format),
2675 value * ptp_value_trans[i].coef +
2676 ptp_value_trans[i].bias);
2677 }
2678
2679 for (i=0; ptp_value_trans_Nikon[i].dpc!=0; i++)
2680 if (ptp_value_trans_Nikon[i].dpc==dpc) {
2681 double value = _value_to_num(&(dpd->CurrentValue), dpd->DataType);
2682
2683 return snprintf(out, length,
2684 _(ptp_value_trans_Nikon[i].format),
2685 value * ptp_value_trans_Nikon[i].coef +
2686 ptp_value_trans_Nikon[i].bias);
2687 }
2688
2689 kval = _value_to_num(&(dpd->CurrentValue), dpd->DataType);
2690
2691 for (i=0; ptp_value_list_Nikon[i].dpc!=0; i++)
2692 if (ptp_value_list_Nikon[i].dpc==dpc &&
2693 ptp_value_list_Nikon[i].key==kval)
2694 return snprintf(out, length, "%s",
2695 _(ptp_value_list_Nikon[i].value));
2696 }
2697 if (params->deviceinfo.VendorExtensionID==PTP_VENDOR_MICROSOFT) {
2698 switch (dpc) {
2699 case PTP_DPC_MTP_Synchronization_Partner:
2700 case PTP_DPC_MTP_Device_Friendly_Name:
2701 return snprintf(out, length, "%s", dpd->CurrentValue.str);
2702 case 0xd101:
2703 case 0xd102: {
2704 for (i=0;(i<dpd->CurrentValue.a.count) && (i<length);i++)
2705 out[i] = dpd->CurrentValue.a.v[i].u16;
2706 if ( dpd->CurrentValue.a.count &&
2707 (dpd->CurrentValue.a.count < length)) {
2708 out[dpd->CurrentValue.a.count-1] = 0;
2709 return dpd->CurrentValue.a.count-1;
2710 } else {
2711 out[length-1] = 0;
2712 return length;
2713 }
2714 break;
2715 }
2716 default:
2717 break;
2718 }
2719 }
2720
2721 return 0;
2722}
2723
2724struct {
2725 uint16_t ofc;
2726 const char *format;
2727} ptp_ofc_trans[] = {
2728 {PTP_OFC_Undefined,"Undefined Type"},
2729 {PTP_OFC_Association,"Association/Directory"},
2730 {PTP_OFC_Script,"Script"},
2731 {PTP_OFC_Executable,"Executable"},
2732 {PTP_OFC_Text,"Text"},
2733 {PTP_OFC_HTML,"HTML"},
2734 {PTP_OFC_DPOF,"DPOF"},
2735 {PTP_OFC_AIFF,"AIFF"},
2736 {PTP_OFC_WAV,"MS Wave"},
2737 {PTP_OFC_MP3,"MP3"},
2738 {PTP_OFC_AVI,"MS AVI"},
2739 {PTP_OFC_MPEG,"MPEG"},
2740 {PTP_OFC_ASF,"ASF"},
2741 {PTP_OFC_QT,"Apple Quicktime"},
2742 {PTP_OFC_EXIF_JPEG,"JPEG"},
2743 {PTP_OFC_TIFF_EP,"TIFF EP"},
2744 {PTP_OFC_FlashPix,"FlashPix"},
2745 {PTP_OFC_BMP,"BMP"},
2746 {PTP_OFC_CIFF,"CIFF"},
2747 {PTP_OFC_GIF,"GIF"},
2748 {PTP_OFC_JFIF,"JFIF"},
2749 {PTP_OFC_PCD,"PCD"},
2750 {PTP_OFC_PICT,"PICT"},
2751 {PTP_OFC_PNG,"PNG"},
2752 {PTP_OFC_TIFF,"TIFF"},
2753 {PTP_OFC_TIFF_IT,"TIFF_IT"},
2754 {PTP_OFC_JP2,"JP2"},
2755 {PTP_OFC_JPX,"JPX"},
2756};
2757
2758struct {
2759 uint16_t ofc;
2760 const char *format;
2761} ptp_ofc_mtp_trans[] = {
2762 {PTP_OFC_MTP_Firmware,N_("Firmware")},
2763 {PTP_OFC_MTP_WindowsImageFormat,N_("WindowsImageFormat")},
2764 {PTP_OFC_MTP_UndefinedAudio,N_("Undefined Audio")},
2765 {PTP_OFC_MTP_WMA,"WMA"},
2766 {PTP_OFC_MTP_OGG,"OGG"},
2767 {PTP_OFC_MTP_UndefinedVideo,N_("Undefined Video")},
2768 {PTP_OFC_MTP_WMV,"WMV"},
2769 {PTP_OFC_MTP_MP4,"MP4"},
2770 {PTP_OFC_MTP_UndefinedCollection,N_("Undefined Collection")},
2771 {PTP_OFC_MTP_AbstractMultimediaAlbum,N_("Abstract Multimedia Album")},
2772 {PTP_OFC_MTP_AbstractImageAlbum,N_("Abstract Image Album")},
2773 {PTP_OFC_MTP_AbstractAudioAlbum,N_("Abstract Audio Album")},
2774 {PTP_OFC_MTP_AbstractVideoAlbum,N_("Abstract Video Album")},
2775 {PTP_OFC_MTP_AbstractAudioVideoPlaylist,N_("Abstract Audio Video Playlist")},
2776 {PTP_OFC_MTP_AbstractContactGroup,N_("Abstract Contact Group")},
2777 {PTP_OFC_MTP_AbstractMessageFolder,N_("Abstract Message Folder")},
2778 {PTP_OFC_MTP_AbstractChapteredProduction,N_("Abstract Chaptered Production")},
2779 {PTP_OFC_MTP_WPLPlaylist,N_("WPL Playlist")},
2780 {PTP_OFC_MTP_M3UPlaylist,N_("M3U Playlist")},
2781 {PTP_OFC_MTP_MPLPlaylist,N_("MPL Playlist")},
2782 {PTP_OFC_MTP_ASXPlaylist,N_("ASX Playlist")},
2783 {PTP_OFC_MTP_PLSPlaylist,N_("PLS Playlist")},
2784 {PTP_OFC_MTP_UndefinedDocument,N_("UndefinedDocument")},
2785 {PTP_OFC_MTP_AbstractDocument,N_("AbstractDocument")},
2786 {PTP_OFC_MTP_UndefinedMessage,N_("UndefinedMessage")},
2787 {PTP_OFC_MTP_AbstractMessage,N_("AbstractMessage")},
2788 {PTP_OFC_MTP_UndefinedContact,N_("UndefinedContact")},
2789 {PTP_OFC_MTP_AbstractContact,N_("AbstractContact")},
2790 {PTP_OFC_MTP_vCard2,N_("vCard2")},
2791 {PTP_OFC_MTP_vCard3,N_("vCard3")},
2792 {PTP_OFC_MTP_UndefinedCalendarItem,N_("UndefinedCalendarItem")},
2793 {PTP_OFC_MTP_AbstractCalendarItem,N_("AbstractCalendarItem")},
2794 {PTP_OFC_MTP_vCalendar1,N_("vCalendar1")},
2795 {PTP_OFC_MTP_vCalendar2,N_("vCalendar2")},
2796 {PTP_OFC_MTP_UndefinedWindowsExecutable,N_("Undefined Windows Executable")},
2797};
2798
2799int
2800ptp_render_ofc(PTPParams* params, uint16_t ofc, int spaceleft, char *txt)
2801{
2802 int i;
2803
2804 if (!(ofc & 0x8000)) {
2805 for (i=0;i<sizeof(ptp_ofc_trans)/sizeof(ptp_ofc_trans[0]);i++)
2806 if (ofc == ptp_ofc_trans[i].ofc)
2807 return snprintf(txt, spaceleft,_(ptp_ofc_trans[i].format));
2808 } else {
2809 switch (params->deviceinfo.VendorExtensionID) {
2810 case PTP_VENDOR_EASTMAN_KODAK:
2811 switch (ofc) {
2812 case PTP_OFC_EK_M3U:
2813 return snprintf (txt, spaceleft,_("M3U"));
2814 default:
2815 break;
2816 }
2817 break;
2818 case PTP_VENDOR_MICROSOFT:
2819 for (i=0;i<sizeof(ptp_ofc_mtp_trans)/sizeof(ptp_ofc_mtp_trans[0]);i++)
2820 if (ofc == ptp_ofc_mtp_trans[i].ofc)
2821 return snprintf(txt, spaceleft,_(ptp_ofc_mtp_trans[i].format));
2822 break;
2823 default:break;
2824 }
2825 }
2826 return snprintf (txt, spaceleft,_("Unknown(%04x)"), ofc);
2827}
2828
2829struct {
2830 uint16_t id;
2831 const char *name;
2832} ptp_opc_trans[] = {
2833 {PTP_OPC_StorageID,"StorageID"},
2834 {PTP_OPC_ObjectFormat,"ObjectFormat"},
2835 {PTP_OPC_ProtectionStatus,"ProtectionStatus"},
2836 {PTP_OPC_ObjectSize,"ObjectSize"},
2837 {PTP_OPC_AssociationType,"AssociationType"},
2838 {PTP_OPC_AssociationDesc,"AssociationDesc"},
2839 {PTP_OPC_ObjectFileName,"ObjectFileName"},
2840 {PTP_OPC_DateCreated,"DateCreated"},
2841 {PTP_OPC_DateModified,"DateModified"},
2842 {PTP_OPC_Keywords,"Keywords"},
2843 {PTP_OPC_ParentObject,"ParentObject"},
2844 {PTP_OPC_PersistantUniqueObjectIdentifier,"PersistantUniqueObjectIdentifier"},
2845 {PTP_OPC_SyncID,"SyncID"},
2846 {PTP_OPC_PropertyBag,"PropertyBag"},
2847 {PTP_OPC_Name,"Name"},
2848 {PTP_OPC_CreatedBy,"CreatedBy"},
2849 {PTP_OPC_Artist,"Artist"},
2850 {PTP_OPC_DateAuthored,"DateAuthored"},
2851 {PTP_OPC_Description,"Description"},
2852 {PTP_OPC_URLReference,"URLReference"},
2853 {PTP_OPC_LanguageLocale,"LanguageLocale"},
2854 {PTP_OPC_CopyrightInformation,"CopyrightInformation"},
2855 {PTP_OPC_Source,"Source"},
2856 {PTP_OPC_OriginLocation,"OriginLocation"},
2857 {PTP_OPC_DateAdded,"DateAdded"},
2858 {PTP_OPC_NonConsumable,"NonConsumable"},
2859 {PTP_OPC_CorruptOrUnplayable,"CorruptOrUnplayable"},
2860 {PTP_OPC_RepresentativeSampleFormat,"RepresentativeSampleFormat"},
2861 {PTP_OPC_RepresentativeSampleSize,"RepresentativeSampleSize"},
2862 {PTP_OPC_RepresentativeSampleHeight,"RepresentativeSampleHeight"},
2863 {PTP_OPC_RepresentativeSampleWidth,"RepresentativeSampleWidth"},
2864 {PTP_OPC_RepresentativeSampleDuration,"RepresentativeSampleDuration"},
2865 {PTP_OPC_RepresentativeSampleData,"RepresentativeSampleData"},
2866 {PTP_OPC_Width,"Width"},
2867 {PTP_OPC_Height,"Height"},
2868 {PTP_OPC_Duration,"Duration"},
2869 {PTP_OPC_Rating,"Rating"},
2870 {PTP_OPC_Track,"Track"},
2871 {PTP_OPC_Genre,"Genre"},
2872 {PTP_OPC_Credits,"Credits"},
2873 {PTP_OPC_Lyrics,"Lyrics"},
2874 {PTP_OPC_SubscriptionContentID,"SubscriptionContentID"},
2875 {PTP_OPC_ProducedBy,"ProducedBy"},
2876 {PTP_OPC_UseCount,"UseCount"},
2877 {PTP_OPC_SkipCount,"SkipCount"},
2878 {PTP_OPC_LastAccessed,"LastAccessed"},
2879 {PTP_OPC_ParentalRating,"ParentalRating"},
2880 {PTP_OPC_MetaGenre,"MetaGenre"},
2881 {PTP_OPC_Composer,"Composer"},
2882 {PTP_OPC_EffectiveRating,"EffectiveRating"},
2883 {PTP_OPC_Subtitle,"Subtitle"},
2884 {PTP_OPC_OriginalReleaseDate,"OriginalReleaseDate"},
2885 {PTP_OPC_AlbumName,"AlbumName"},
2886 {PTP_OPC_AlbumArtist,"AlbumArtist"},
2887 {PTP_OPC_Mood,"Mood"},
2888 {PTP_OPC_DRMStatus,"DRMStatus"},
2889 {PTP_OPC_SubDescription,"SubDescription"},
2890 {PTP_OPC_IsCropped,"IsCropped"},
2891 {PTP_OPC_IsColorCorrected,"IsColorCorrected"},
2892 {PTP_OPC_TotalBitRate,"TotalBitRate"},
2893 {PTP_OPC_BitRateType,"BitRateType"},
2894 {PTP_OPC_SampleRate,"SampleRate"},
2895 {PTP_OPC_NumberOfChannels,"NumberOfChannels"},
2896 {PTP_OPC_AudioBitDepth,"AudioBitDepth"},
2897 {PTP_OPC_ScanDepth,"ScanDepth"},
2898 {PTP_OPC_AudioWAVECodec,"AudioWAVECodec"},
2899 {PTP_OPC_AudioBitRate,"AudioBitRate"},
2900 {PTP_OPC_VideoFourCCCodec,"VideoFourCCCodec"},
2901 {PTP_OPC_VideoBitRate,"VideoBitRate"},
2902 {PTP_OPC_FramesPerThousandSeconds,"FramesPerThousandSeconds"},
2903 {PTP_OPC_KeyFrameDistance,"KeyFrameDistance"},
2904 {PTP_OPC_BufferSize,"BufferSize"},
2905 {PTP_OPC_EncodingQuality,"EncodingQuality"},
2906};
2907
2908int
2909ptp_render_mtp_propname(uint16_t propid, int spaceleft, char *txt) {
2910 int i;
2911 for (i=0;i<sizeof(ptp_opc_trans)/sizeof(ptp_opc_trans[0]);i++)
2912 if (propid == ptp_opc_trans[i].id)
2913 return snprintf(txt, spaceleft,ptp_opc_trans[i].name);
2914 return snprintf (txt, spaceleft,"unknown(%04x)", propid);
2915}