blob: 536160dc0cc4844bdee1df3784975629613e1e49 [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>
Marcus Meissner56f937f2017-04-01 21:47:44 +02004 * Copyright (C) 2003-2017 Marcus Meissner <marcus@jet.franken.de>
Linus Walleij7e3b3072009-01-19 22:51:17 +00005 * Copyright (C) 2006-2008 Linus Walleij <triad@df.lth.se>
Linus Walleija6d0d482007-10-31 08:54:56 +00006 * Copyright (C) 2007 Tero Saarni <tero.saarni@gmail.com>
Linus Walleije29ca682010-01-30 08:15:25 +00007 * Copyright (C) 2009 Axel Waggershauser <awagger@web.de>
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00008 *
Linus Walleijb02a0662006-04-25 08:05:09 +00009 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
Linus Walleijeb8c6fe2006-02-03 09:46:22 +000013 *
Linus Walleijb02a0662006-04-25 08:05:09 +000014 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
Linus Walleijeb8c6fe2006-02-03 09:46:22 +000018 *
Linus Walleijb02a0662006-04-25 08:05:09 +000019 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the
Linus Walleij9783ce32014-06-02 21:44:29 +020021 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 * Boston, MA 02110-1301 USA
Linus Walleijeb8c6fe2006-02-03 09:46:22 +000023 */
24
Marcus Meissner3d692dc2016-02-21 12:34:06 +010025#define _DEFAULT_SOURCE
Linus Walleijd4637502009-06-14 23:03:33 +000026#include "config.h"
Linus Walleijeb8c6fe2006-02-03 09:46:22 +000027#include "ptp.h"
Linus Walleijeb8c6fe2006-02-03 09:46:22 +000028
Linus Walleijd9ee8cd2013-11-04 01:54:35 +010029#ifdef HAVE_LIBXML2
30# include <libxml/parser.h>
31#endif
32
Linus Walleijeb8c6fe2006-02-03 09:46:22 +000033#include <stdlib.h>
34#include <stdarg.h>
35#include <stdio.h>
36#include <string.h>
Marcus Meissner3d692dc2016-02-21 12:34:06 +010037#ifdef HAVE_UNISTD_H
38# include <unistd.h>
39#endif
Linus Walleijeb8c6fe2006-02-03 09:46:22 +000040
41#ifdef ENABLE_NLS
42# include <libintl.h>
43# undef _
44# define _(String) dgettext (PACKAGE, String)
45# ifdef gettext_noop
46# define N_(String) gettext_noop (String)
47# else
48# define N_(String) (String)
49# endif
50#else
51# define textdomain(String) (String)
52# define gettext(String) (String)
53# define dgettext(Domain,Message) (Message)
54# define dcgettext(Domain,Message,Type) (Message)
55# define bindtextdomain(Domain,Directory) (Domain)
56# define _(String) (String)
57# define N_(String) (String)
58#endif
59
Marcus Meissner3d692dc2016-02-21 12:34:06 +010060#define CHECK_PTP_RC(RESULT) do { uint16_t r = (RESULT); if (r != PTP_RC_OK) return r; } while(0)
Linus Walleijb02a0662006-04-25 08:05:09 +000061
Marcus Meissner3d692dc2016-02-21 12:34:06 +010062static inline void
63ptp_init_container(PTPContainer* ptp, uint16_t code, int n_param, ...)
64{
65 va_list args;
66 int i;
67
68 memset(ptp, 0, sizeof(*ptp));
69 ptp->Code = code;
70 ptp->Nparam = n_param;
71
72 va_start(args, n_param);
73 for (i=0; i<n_param; ++i)
74 (&ptp->Param1)[i] = va_arg(args, uint32_t);
75 va_end(args);
76}
77
78#define NARGS_SEQ(_1,_2,_3,_4,_5,_6,_7,_8,N,...) N
79#define NARGS(...) NARGS_SEQ(-1, ##__VA_ARGS__, 7, 6, 5, 4, 3, 2, 1, 0)
80
81#define PTP_CNT_INIT(PTP, CODE, ...) \
82 ptp_init_container(&PTP, CODE, NARGS(__VA_ARGS__), ##__VA_ARGS__)
Linus Walleijeb8c6fe2006-02-03 09:46:22 +000083
Linus Walleij784ac3f2006-12-29 10:36:51 +000084static uint16_t ptp_exit_recv_memory_handler (PTPDataHandler*,unsigned char**,unsigned long*);
85static uint16_t ptp_init_recv_memory_handler(PTPDataHandler*);
86static uint16_t ptp_init_send_memory_handler(PTPDataHandler*,unsigned char*,unsigned long len);
87static uint16_t ptp_exit_send_memory_handler (PTPDataHandler *handler);
88
Linus Walleij9e09ad02011-02-10 13:14:01 +010089void
Linus Walleijeb8c6fe2006-02-03 09:46:22 +000090ptp_debug (PTPParams *params, const char *format, ...)
91{
92 va_list args;
93
94 va_start (args, format);
95 if (params->debug_func!=NULL)
96 params->debug_func (params->data, format, args);
97 else
98 {
99 vfprintf (stderr, format, args);
100 fprintf (stderr,"\n");
101 fflush (stderr);
102 }
103 va_end (args);
104}
105
Linus Walleij9e09ad02011-02-10 13:14:01 +0100106void
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000107ptp_error (PTPParams *params, const char *format, ...)
108{
109 va_list args;
110
111 va_start (args, format);
112 if (params->error_func!=NULL)
113 params->error_func (params->data, format, args);
114 else
115 {
116 vfprintf (stderr, format, args);
117 fprintf (stderr,"\n");
118 fflush (stderr);
119 }
120 va_end (args);
121}
122
Linus Walleijb02a0662006-04-25 08:05:09 +0000123/* Pack / unpack functions */
124
125#include "ptp-pack.c"
126
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000127/* major PTP functions */
128
129/**
130 * ptp_transaction:
131 * params: PTPParams*
132 * PTPContainer* ptp - general ptp container
133 * uint16_t flags - lower 8 bits - data phase description
134 * unsigned int sendlen - senddata phase data length
135 * char** data - send or receive data buffer pointer
Linus Walleijb02a0662006-04-25 08:05:09 +0000136 * int* recvlen - receive data length
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000137 *
138 * Performs PTP transaction. ptp is a PTPContainer with appropriate fields
139 * filled in (i.e. operation code and parameters). It's up to caller to do
140 * so.
141 * The flags decide thether the transaction has a data phase and what is its
142 * direction (send or receive).
143 * If transaction is sending data the sendlen should contain its length in
144 * bytes, otherwise it's ignored.
145 * The data should contain an address of a pointer to data going to be sent
146 * or is filled with such a pointer address if data are received depending
147 * od dataphase direction (send or received) or is beeing ignored (no
148 * dataphase).
149 * The memory for a pointer should be preserved by the caller, if data are
150 * beeing retreived the appropriate amount of memory is beeing allocated
151 * (the caller should handle that!).
152 *
153 * Return values: Some PTP_RC_* code.
154 * Upon success PTPContainer* ptp contains PTP Response Phase container with
155 * all fields filled in.
156 **/
Linus Walleijb7c1a672013-03-05 09:08:44 +0100157uint16_t
Linus Walleij784ac3f2006-12-29 10:36:51 +0000158ptp_transaction_new (PTPParams* params, PTPContainer* ptp,
Linus Walleija381e8a2013-03-05 21:00:06 +0100159 uint16_t flags, uint64_t sendlen,
160 PTPDataHandler *handler
Linus Walleij784ac3f2006-12-29 10:36:51 +0000161) {
Linus Walleije29ca682010-01-30 08:15:25 +0000162 int tries;
163 uint16_t cmd;
Linus Walleij7e756532009-05-06 21:25:09 +0000164
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000165 if ((params==NULL) || (ptp==NULL))
166 return PTP_ERROR_BADPARAM;
Linus Walleije7f44be2006-08-25 19:32:29 +0000167
Linus Walleije29ca682010-01-30 08:15:25 +0000168 cmd = ptp->Code;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000169 ptp->Transaction_ID=params->transaction_id++;
170 ptp->SessionID=params->session_id;
171 /* send request */
Marcus Meissner3d692dc2016-02-21 12:34:06 +0100172 CHECK_PTP_RC(params->sendreq_func (params, ptp, flags));
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000173 /* is there a dataphase? */
174 switch (flags&PTP_DP_DATA_MASK) {
Linus Walleijb02a0662006-04-25 08:05:09 +0000175 case PTP_DP_SENDDATA:
Linus Walleijff01cb12007-09-16 19:49:48 +0000176 {
Marcus Meissner3d692dc2016-02-21 12:34:06 +0100177 uint16_t ret = params->senddata_func(params, ptp, sendlen, handler);
178 if (ret == PTP_ERROR_CANCEL)
179 CHECK_PTP_RC(params->cancelreq_func(params, params->transaction_id-1));
180 CHECK_PTP_RC(ret);
Linus Walleijff01cb12007-09-16 19:49:48 +0000181 }
Linus Walleijb02a0662006-04-25 08:05:09 +0000182 break;
183 case PTP_DP_GETDATA:
Linus Walleijff01cb12007-09-16 19:49:48 +0000184 {
Marcus Meissner3d692dc2016-02-21 12:34:06 +0100185 uint16_t ret = params->getdata_func(params, ptp, handler);
186 if (ret == PTP_ERROR_CANCEL)
187 CHECK_PTP_RC(params->cancelreq_func(params, params->transaction_id-1));
188 CHECK_PTP_RC(ret);
Linus Walleijff01cb12007-09-16 19:49:48 +0000189 }
Linus Walleijb02a0662006-04-25 08:05:09 +0000190 break;
191 case PTP_DP_NODATA:
192 break;
193 default:
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000194 return PTP_ERROR_BADPARAM;
195 }
Linus Walleij7e756532009-05-06 21:25:09 +0000196 tries = 3;
Linus Walleije29ca682010-01-30 08:15:25 +0000197 while (tries--) {
198 uint16_t ret;
Linus Walleij7e756532009-05-06 21:25:09 +0000199 /* get response */
Linus Walleije29ca682010-01-30 08:15:25 +0000200 ret = params->getresp_func(params, ptp);
201 if (ret == PTP_ERROR_RESP_EXPECTED) {
202 ptp_debug (params,"PTP: response expected but not got, retrying.");
203 tries++;
204 continue;
205 }
Marcus Meissner3d692dc2016-02-21 12:34:06 +0100206 CHECK_PTP_RC(ret);
207
Linus Walleije29ca682010-01-30 08:15:25 +0000208 if (ptp->Transaction_ID < params->transaction_id-1) {
Marcus Meissner3d692dc2016-02-21 12:34:06 +0100209 /* The Leica uses Transaction ID 0 on result from CloseSession. */
210 if (cmd == PTP_OC_CloseSession)
211 break;
Linus Walleije29ca682010-01-30 08:15:25 +0000212 tries++;
213 ptp_debug (params,
214 "PTP: Sequence number mismatch %d vs expected %d, suspecting old reply.",
215 ptp->Transaction_ID, params->transaction_id-1
216 );
217 continue;
218 }
Linus Walleij7e756532009-05-06 21:25:09 +0000219 if (ptp->Transaction_ID != params->transaction_id-1) {
220 /* try to clean up potential left overs from previous session */
Linus Walleije29ca682010-01-30 08:15:25 +0000221 if ((cmd == PTP_OC_OpenSession) && tries)
Linus Walleij7e756532009-05-06 21:25:09 +0000222 continue;
223 ptp_error (params,
224 "PTP: Sequence number mismatch %d vs expected %d.",
225 ptp->Transaction_ID, params->transaction_id-1
226 );
Marcus Meissneraa7d91a2017-03-16 15:59:48 +0100227#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
Linus Walleij7e756532009-05-06 21:25:09 +0000228 return PTP_ERROR_BADPARAM;
Marcus Meissneraa7d91a2017-03-16 15:59:48 +0100229#endif
Linus Walleij7e756532009-05-06 21:25:09 +0000230 }
231 break;
Linus Walleij7347d0f2006-10-23 07:23:39 +0000232 }
Linus Walleijb02a0662006-04-25 08:05:09 +0000233 return ptp->Code;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000234}
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000235
Linus Walleij784ac3f2006-12-29 10:36:51 +0000236/* memory data get/put handler */
237typedef struct {
238 unsigned char *data;
239 unsigned long size, curoff;
240} PTPMemHandlerPrivate;
241
242static uint16_t
243memory_getfunc(PTPParams* params, void* private,
244 unsigned long wantlen, unsigned char *data,
245 unsigned long *gotlen
246) {
247 PTPMemHandlerPrivate* priv = (PTPMemHandlerPrivate*)private;
248 unsigned long tocopy = wantlen;
249
250 if (priv->curoff + tocopy > priv->size)
251 tocopy = priv->size - priv->curoff;
252 memcpy (data, priv->data + priv->curoff, tocopy);
253 priv->curoff += tocopy;
254 *gotlen = tocopy;
255 return PTP_RC_OK;
256}
257
258static uint16_t
259memory_putfunc(PTPParams* params, void* private,
Marcus Meissner3d692dc2016-02-21 12:34:06 +0100260 unsigned long sendlen, unsigned char *data
Linus Walleij784ac3f2006-12-29 10:36:51 +0000261) {
262 PTPMemHandlerPrivate* priv = (PTPMemHandlerPrivate*)private;
263
264 if (priv->curoff + sendlen > priv->size) {
265 priv->data = realloc (priv->data, priv->curoff+sendlen);
Linus Walleije29ca682010-01-30 08:15:25 +0000266 if (!priv->data)
267 return PTP_RC_GeneralError;
Linus Walleij784ac3f2006-12-29 10:36:51 +0000268 priv->size = priv->curoff + sendlen;
269 }
270 memcpy (priv->data + priv->curoff, data, sendlen);
271 priv->curoff += sendlen;
Linus Walleij784ac3f2006-12-29 10:36:51 +0000272 return PTP_RC_OK;
273}
274
275/* init private struct for receiving data. */
276static uint16_t
Marcus Meissner3d692dc2016-02-21 12:34:06 +0100277ptp_init_recv_memory_handler(PTPDataHandler *handler)
278{
Linus Walleij784ac3f2006-12-29 10:36:51 +0000279 PTPMemHandlerPrivate* priv;
280 priv = malloc (sizeof(PTPMemHandlerPrivate));
Linus Walleij936b27b2009-09-21 12:12:10 +0000281 if (!priv)
Richard Lowce0cef62009-09-13 17:41:15 +0000282 return PTP_RC_GeneralError;
Linus Walleijd866d242009-08-23 21:50:39 +0000283 handler->priv = priv;
Linus Walleij784ac3f2006-12-29 10:36:51 +0000284 handler->getfunc = memory_getfunc;
285 handler->putfunc = memory_putfunc;
286 priv->data = NULL;
287 priv->size = 0;
288 priv->curoff = 0;
289 return PTP_RC_OK;
290}
291
292/* init private struct and put data in for sending data.
293 * data is still owned by caller.
294 */
295static uint16_t
296ptp_init_send_memory_handler(PTPDataHandler *handler,
297 unsigned char *data, unsigned long len
298) {
299 PTPMemHandlerPrivate* priv;
300 priv = malloc (sizeof(PTPMemHandlerPrivate));
301 if (!priv)
302 return PTP_RC_GeneralError;
Linus Walleijd866d242009-08-23 21:50:39 +0000303 handler->priv = priv;
Linus Walleij784ac3f2006-12-29 10:36:51 +0000304 handler->getfunc = memory_getfunc;
305 handler->putfunc = memory_putfunc;
306 priv->data = data;
307 priv->size = len;
308 priv->curoff = 0;
309 return PTP_RC_OK;
310}
311
312/* free private struct + data */
313static uint16_t
Marcus Meissner3d692dc2016-02-21 12:34:06 +0100314ptp_exit_send_memory_handler (PTPDataHandler *handler)
315{
Linus Walleijd866d242009-08-23 21:50:39 +0000316 PTPMemHandlerPrivate* priv = (PTPMemHandlerPrivate*)handler->priv;
Linus Walleij784ac3f2006-12-29 10:36:51 +0000317 /* data is owned by caller */
318 free (priv);
319 return PTP_RC_OK;
320}
321
322/* hand over our internal data to caller */
323static uint16_t
324ptp_exit_recv_memory_handler (PTPDataHandler *handler,
325 unsigned char **data, unsigned long *size
326) {
Linus Walleijd866d242009-08-23 21:50:39 +0000327 PTPMemHandlerPrivate* priv = (PTPMemHandlerPrivate*)handler->priv;
Linus Walleij784ac3f2006-12-29 10:36:51 +0000328 *data = priv->data;
329 *size = priv->size;
330 free (priv);
331 return PTP_RC_OK;
332}
333
334/* fd data get/put handler */
335typedef struct {
336 int fd;
337} PTPFDHandlerPrivate;
338
339static uint16_t
340fd_getfunc(PTPParams* params, void* private,
341 unsigned long wantlen, unsigned char *data,
342 unsigned long *gotlen
343) {
344 PTPFDHandlerPrivate* priv = (PTPFDHandlerPrivate*)private;
345 int got;
346
347 got = read (priv->fd, data, wantlen);
348 if (got != -1)
349 *gotlen = got;
350 else
351 return PTP_RC_GeneralError;
352 return PTP_RC_OK;
353}
354
355static uint16_t
356fd_putfunc(PTPParams* params, void* private,
Marcus Meissner3d692dc2016-02-21 12:34:06 +0100357 unsigned long sendlen, unsigned char *data
Linus Walleij784ac3f2006-12-29 10:36:51 +0000358) {
Marcus Meissner3d692dc2016-02-21 12:34:06 +0100359 ssize_t written;
Linus Walleij784ac3f2006-12-29 10:36:51 +0000360 PTPFDHandlerPrivate* priv = (PTPFDHandlerPrivate*)private;
361
362 written = write (priv->fd, data, sendlen);
Marcus Meissner3d692dc2016-02-21 12:34:06 +0100363 if (written != sendlen)
364 return PTP_ERROR_IO;
Linus Walleij784ac3f2006-12-29 10:36:51 +0000365 return PTP_RC_OK;
366}
367
368static uint16_t
Marcus Meissner3d692dc2016-02-21 12:34:06 +0100369ptp_init_fd_handler(PTPDataHandler *handler, int fd)
370{
Linus Walleij784ac3f2006-12-29 10:36:51 +0000371 PTPFDHandlerPrivate* priv;
372 priv = malloc (sizeof(PTPFDHandlerPrivate));
Linus Walleije29ca682010-01-30 08:15:25 +0000373 if (!priv)
374 return PTP_RC_GeneralError;
Linus Walleijd866d242009-08-23 21:50:39 +0000375 handler->priv = priv;
Linus Walleij784ac3f2006-12-29 10:36:51 +0000376 handler->getfunc = fd_getfunc;
377 handler->putfunc = fd_putfunc;
378 priv->fd = fd;
379 return PTP_RC_OK;
380}
381
382static uint16_t
Marcus Meissner3d692dc2016-02-21 12:34:06 +0100383ptp_exit_fd_handler (PTPDataHandler *handler)
384{
Linus Walleijd866d242009-08-23 21:50:39 +0000385 PTPFDHandlerPrivate* priv = (PTPFDHandlerPrivate*)handler->priv;
Linus Walleij784ac3f2006-12-29 10:36:51 +0000386 free (priv);
387 return PTP_RC_OK;
388}
389
390/* Old style transaction, based on memory */
Marcus Meissner3d692dc2016-02-21 12:34:06 +0100391/* A note on memory management:
392 * If called with the flag PTP_DP_GETDATA, this function will internally
393 * allocate memory as much as necessary. The caller has to free the memory
394 * returned in *data. If the function returns an error, it will free any
395 * memory it might have allocated. The recvlen may be NULL. After the
396 * function returns, *data will be initialized (valid memory pointer or NULL),
397 * i.e. it is not necessary to initialize *data or *recvlen beforehand.
398 */
Linus Walleijb7c1a672013-03-05 09:08:44 +0100399uint16_t
Linus Walleij784ac3f2006-12-29 10:36:51 +0000400ptp_transaction (PTPParams* params, PTPContainer* ptp,
Linus Walleija381e8a2013-03-05 21:00:06 +0100401 uint16_t flags, uint64_t sendlen,
Linus Walleij784ac3f2006-12-29 10:36:51 +0000402 unsigned char **data, unsigned int *recvlen
403) {
404 PTPDataHandler handler;
405 uint16_t ret;
406
407 switch (flags & PTP_DP_DATA_MASK) {
408 case PTP_DP_SENDDATA:
Marcus Meissner3d692dc2016-02-21 12:34:06 +0100409 if (!data)
410 return PTP_ERROR_BADPARAM;
411 CHECK_PTP_RC(ptp_init_send_memory_handler (&handler, *data, sendlen));
Linus Walleij784ac3f2006-12-29 10:36:51 +0000412 break;
413 case PTP_DP_GETDATA:
Marcus Meissner3d692dc2016-02-21 12:34:06 +0100414 if (!data)
415 return PTP_ERROR_BADPARAM;
416 *data = NULL;
417 if (recvlen)
418 *recvlen = 0;
419 CHECK_PTP_RC(ptp_init_recv_memory_handler (&handler));
Linus Walleij784ac3f2006-12-29 10:36:51 +0000420 break;
421 default:break;
422 }
423 ret = ptp_transaction_new (params, ptp, flags, sendlen, &handler);
424 switch (flags & PTP_DP_DATA_MASK) {
425 case PTP_DP_SENDDATA:
426 ptp_exit_send_memory_handler (&handler);
427 break;
428 case PTP_DP_GETDATA: {
429 unsigned long len;
430 ptp_exit_recv_memory_handler (&handler, data, &len);
Marcus Meissner3d692dc2016-02-21 12:34:06 +0100431 if (ret != PTP_RC_OK) {
432 len = 0;
433 free(*data);
434 *data = NULL;
435 }
Linus Walleij784ac3f2006-12-29 10:36:51 +0000436 if (recvlen)
437 *recvlen = len;
438 break;
439 }
440 default:break;
441 }
442 return ret;
443}
444
445
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000446/**
447 * PTP operation functions
448 *
449 * all ptp_ functions should take integer parameters
450 * in host byte order!
451 **/
452
453
454/**
455 * ptp_getdeviceinfo:
456 * params: PTPParams*
457 *
458 * Gets device info dataset and fills deviceinfo structure.
459 *
460 * Return values: Some PTP_RC_* code.
461 **/
462uint16_t
463ptp_getdeviceinfo (PTPParams* params, PTPDeviceInfo* deviceinfo)
464{
Linus Walleij784ac3f2006-12-29 10:36:51 +0000465 PTPContainer ptp;
Marcus Meissner3d692dc2016-02-21 12:34:06 +0100466 unsigned char *data;
467 unsigned int size;
Marcus Meissneraa7d91a2017-03-16 15:59:48 +0100468 int ret;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000469
Marcus Meissner3d692dc2016-02-21 12:34:06 +0100470 PTP_CNT_INIT(ptp, PTP_OC_GetDeviceInfo);
471 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size));
Marcus Meissneraa7d91a2017-03-16 15:59:48 +0100472 ret = ptp_unpack_DI(params, data, deviceinfo, size);
Marcus Meissner3d692dc2016-02-21 12:34:06 +0100473 free(data);
Marcus Meissneraa7d91a2017-03-16 15:59:48 +0100474 if (ret)
475 return PTP_RC_OK;
476 else
477 return PTP_ERROR_IO;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000478}
479
Linus Walleij7e3b3072009-01-19 22:51:17 +0000480uint16_t
Linus Walleij7e756532009-05-06 21:25:09 +0000481ptp_canon_eos_getdeviceinfo (PTPParams* params, PTPCanonEOSDeviceInfo*di)
Linus Walleij7e3b3072009-01-19 22:51:17 +0000482{
Linus Walleij7e3b3072009-01-19 22:51:17 +0000483 PTPContainer ptp;
Linus Walleij7e756532009-05-06 21:25:09 +0000484 unsigned char *data;
Marcus Meissner3d692dc2016-02-21 12:34:06 +0100485 unsigned int size;
Marcus Meissneraa7d91a2017-03-16 15:59:48 +0100486 int ret;
Linus Walleij7e3b3072009-01-19 22:51:17 +0000487
Marcus Meissner3d692dc2016-02-21 12:34:06 +0100488 PTP_CNT_INIT(ptp, PTP_OC_CANON_EOS_GetDeviceInfoEx);
489 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size));
Marcus Meissneraa7d91a2017-03-16 15:59:48 +0100490 ret = ptp_unpack_EOS_DI(params, data, di, size);
Linus Walleij7e756532009-05-06 21:25:09 +0000491 free (data);
Marcus Meissneraa7d91a2017-03-16 15:59:48 +0100492 if (ret)
493 return PTP_RC_OK;
494 else
495 return PTP_ERROR_IO;
Linus Walleij7e3b3072009-01-19 22:51:17 +0000496}
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000497
Linus Walleijd9ee8cd2013-11-04 01:54:35 +0100498#ifdef HAVE_LIBXML2
499static int
Marcus Meissner3d692dc2016-02-21 12:34:06 +0100500traverse_tree (PTPParams *params, int depth, xmlNodePtr node)
501{
Linus Walleijd9ee8cd2013-11-04 01:54:35 +0100502 xmlNodePtr next;
503 xmlChar *xchar;
Marcus Meissner3d692dc2016-02-21 12:34:06 +0100504 int n;
Linus Walleijd9ee8cd2013-11-04 01:54:35 +0100505 char *xx;
506
507
508 if (!node) return 0;
Linus Walleij9783ce32014-06-02 21:44:29 +0200509 xx = malloc (depth * 4 + 1);
Linus Walleijd9ee8cd2013-11-04 01:54:35 +0100510 memset (xx, ' ', depth*4);
511 xx[depth*4] = 0;
512
513 n = xmlChildElementCount (node);
514
515 next = node;
516 do {
517 fprintf(stderr,"%snode %s\n", xx,next->name);
518 fprintf(stderr,"%selements %d\n", xx,n);
519 xchar = xmlNodeGetContent (next);
520 fprintf(stderr,"%scontent %s\n", xx,xchar);
521 traverse_tree (params, depth+1,xmlFirstElementChild (next));
522 } while ((next = xmlNextElementSibling (next)));
Linus Walleij9783ce32014-06-02 21:44:29 +0200523 free (xx);
Linus Walleijd9ee8cd2013-11-04 01:54:35 +0100524 return PTP_RC_OK;
525}
526
527static int
Marcus Meissner3d692dc2016-02-21 12:34:06 +0100528parse_9301_cmd_tree (PTPParams *params, xmlNodePtr node, PTPDeviceInfo *di)
529{
530 xmlNodePtr next;
531 int cnt;
Linus Walleijd9ee8cd2013-11-04 01:54:35 +0100532
533 cnt = 0;
534 next = xmlFirstElementChild (node);
535 while (next) {
536 cnt++;
537 next = xmlNextElementSibling (next);
538 }
539 di->OperationsSupported_len = cnt;
540 di->OperationsSupported = malloc (cnt*sizeof(di->OperationsSupported[0]));
541 cnt = 0;
542 next = xmlFirstElementChild (node);
543 while (next) {
544 unsigned int p;
545
546 sscanf((char*)next->name, "c%04x", &p);
547 ptp_debug( params, "cmd %s / 0x%04x", next->name, p);
548 di->OperationsSupported[cnt++] = p;
549 next = xmlNextElementSibling (next);
550 }
551 return PTP_RC_OK;
552}
553
554static int
Marcus Meissner3d692dc2016-02-21 12:34:06 +0100555parse_9301_value (PTPParams *params, const char *str, uint16_t type, PTPPropertyValue *propval)
556{
Linus Walleijd9ee8cd2013-11-04 01:54:35 +0100557 switch (type) {
558 case 6: { /*UINT32*/
559 unsigned int x;
560 if (!sscanf(str,"%08x", &x)) {
561 ptp_debug( params, "could not parse uint32 %s", str);
562 return PTP_RC_GeneralError;
563 }
564 ptp_debug( params, "\t%d", x);
565 propval->u32 = x;
566 break;
567 }
568 case 5: { /*INT32*/
569 int x;
570 if (!sscanf(str,"%08x", &x)) {
571 ptp_debug( params, "could not parse int32 %s", str);
572 return PTP_RC_GeneralError;
573 }
574 ptp_debug( params, "\t%d", x);
575 propval->i32 = x;
576 break;
577 }
578 case 4: { /*UINT16*/
579 unsigned int x;
580 if (!sscanf(str,"%04x", &x)) {
581 ptp_debug( params, "could not parse uint16 %s", str);
582 return PTP_RC_GeneralError;
583 }
584 ptp_debug( params, "\t%d", x);
585 propval->u16 = x;
586 break;
587 }
588 case 3: { /*INT16*/
589 int x;
590 if (!sscanf(str,"%04x", &x)) {
591 ptp_debug( params, "could not parse int16 %s", str);
592 return PTP_RC_GeneralError;
593 }
594 ptp_debug( params, "\t%d", x);
595 propval->i16 = x;
596 break;
597 }
598 case 2: { /*UINT8*/
599 unsigned int x;
600 if (!sscanf(str,"%02x", &x)) {
601 ptp_debug( params, "could not parse uint8 %s", str);
602 return PTP_RC_GeneralError;
603 }
604 ptp_debug( params, "\t%d", x);
605 propval->u8 = x;
606 break;
607 }
608 case 1: { /*INT8*/
609 int x;
610 if (!sscanf(str,"%02x", &x)) {
611 ptp_debug( params, "could not parse int8 %s", str);
612 return PTP_RC_GeneralError;
613 }
614 ptp_debug( params, "\t%d", x);
615 propval->i8 = x;
616 break;
617 }
618 case 65535: { /* string */
619 int len;
620
621 /* ascii ptp string, 1 byte length, little endian 16 bit chars */
622 if (sscanf(str,"%02x", &len)) {
623 int i;
624 char *xstr = malloc(len+1);
625 for (i=0;i<len;i++) {
626 int xc;
627 if (sscanf(str+2+i*4,"%04x", &xc)) {
628 int cx;
629
630 cx = ((xc>>8) & 0xff) | ((xc & 0xff) << 8);
631 xstr[i] = cx;
632 }
633 xstr[len] = 0;
634 }
635 ptp_debug( params, "\t%s", xstr);
636 propval->str = xstr;
637 break;
638 }
639 ptp_debug( params, "string %s not parseable!", str);
640 return PTP_RC_GeneralError;
641 }
642 case 7: /*INT64*/
643 case 8: /*UINT64*/
644 case 9: /*INT128*/
645 case 10: /*UINT128*/
646 default:
647 ptp_debug( params, "unhandled data type %d!", type);
648 return PTP_RC_GeneralError;
649 }
650 return PTP_RC_OK;
651}
652
653static int
Marcus Meissner3d692dc2016-02-21 12:34:06 +0100654parse_9301_propdesc (PTPParams *params, xmlNodePtr next, PTPDevicePropDesc *dpd)
655{
Linus Walleijd9ee8cd2013-11-04 01:54:35 +0100656 int type = -1;
657
658 if (!next)
659 return PTP_RC_GeneralError;
660
661 ptp_debug (params, "parse_9301_propdesc");
662 dpd->FormFlag = PTP_DPFF_None;
663 dpd->GetSet = PTP_DPGS_Get;
664 do {
665 if (!strcmp((char*)next->name,"type")) { /* propdesc.DataType */
666 if (!sscanf((char*)xmlNodeGetContent (next), "%04x", &type)) {
667 ptp_debug( params, "\ttype %s not parseable?",xmlNodeGetContent (next));
668 return 0;
669 }
670 ptp_debug( params, "type 0x%x", type);
671 dpd->DataType = type;
672 continue;
673 }
674 if (!strcmp((char*)next->name,"attribute")) { /* propdesc.GetSet */
675 int attr;
676
677 if (!sscanf((char*)xmlNodeGetContent (next), "%02x", &attr)) {
678 ptp_debug( params, "\tattr %s not parseable",xmlNodeGetContent (next));
679 return 0;
680 }
681 ptp_debug( params, "attribute 0x%x", attr);
682 dpd->GetSet = attr;
683 continue;
684 }
685 if (!strcmp((char*)next->name,"default")) { /* propdesc.FactoryDefaultValue */
686 ptp_debug( params, "default value");
687 parse_9301_value (params, (char*)xmlNodeGetContent (next), type, &dpd->FactoryDefaultValue);
688 continue;
689 }
690 if (!strcmp((char*)next->name,"value")) { /* propdesc.CurrentValue */
691 ptp_debug( params, "current value");
692 parse_9301_value (params, (char*)xmlNodeGetContent (next), type, &dpd->CurrentValue);
693 continue;
694 }
695 if (!strcmp((char*)next->name,"enum")) { /* propdesc.FORM.Enum */
696 int n,i;
697 char *s;
698
699 ptp_debug( params, "enum");
700 dpd->FormFlag = PTP_DPFF_Enumeration;
701 s = (char*)xmlNodeGetContent (next);
702 n = 0;
703 do {
704 s = strchr(s,' ');
705 if (s) s++;
706 n++;
707 } while (s);
708 dpd->FORM.Enum.NumberOfValues = n;
709 dpd->FORM.Enum.SupportedValue = malloc (n * sizeof(PTPPropertyValue));
710 s = (char*)xmlNodeGetContent (next);
711 i = 0;
712 do {
713 parse_9301_value (params, s, type, &dpd->FORM.Enum.SupportedValue[i]); /* should turn ' ' into \0? */
714 i++;
715 s = strchr(s,' ');
716 if (s) s++;
717 } while (s && (i<n));
718 continue;
719 }
720 if (!strcmp((char*)next->name,"range")) { /* propdesc.FORM.Enum */
721 char *s = (char*)xmlNodeGetContent (next);
722 dpd->FormFlag = PTP_DPFF_Range;
723 ptp_debug( params, "range");
724 parse_9301_value (params, s, type, &dpd->FORM.Range.MinimumValue); /* should turn ' ' into \0? */
725 s = strchr(s,' ');
726 if (!s) continue;
727 s++;
728 parse_9301_value (params, s, type, &dpd->FORM.Range.MaximumValue); /* should turn ' ' into \0? */
729 s = strchr(s,' ');
730 if (!s) continue;
731 s++;
732 parse_9301_value (params, s, type, &dpd->FORM.Range.StepSize); /* should turn ' ' into \0? */
733
734 continue;
735 }
736 ptp_debug (params, "\tpropdescvar: %s", next->name);
737 traverse_tree (params, 3, next);
738 } while ((next = xmlNextElementSibling (next)));
739 return PTP_RC_OK;
740}
741
742static int
Marcus Meissner3d692dc2016-02-21 12:34:06 +0100743parse_9301_prop_tree (PTPParams *params, xmlNodePtr node, PTPDeviceInfo *di)
744{
Linus Walleij9783ce32014-06-02 21:44:29 +0200745 xmlNodePtr next;
746 int cnt;
747 unsigned int i;
Linus Walleijd9ee8cd2013-11-04 01:54:35 +0100748
749 cnt = 0;
750 next = xmlFirstElementChild (node);
751 while (next) {
752 cnt++;
753 next = xmlNextElementSibling (next);
754 }
755
756 di->DevicePropertiesSupported_len = cnt;
757 di->DevicePropertiesSupported = malloc (cnt*sizeof(di->DevicePropertiesSupported[0]));
758 cnt = 0;
759 next = xmlFirstElementChild (node);
760 while (next) {
761 unsigned int p;
762 PTPDevicePropDesc dpd;
763
764 sscanf((char*)next->name, "p%04x", &p);
765 ptp_debug( params, "prop %s / 0x%04x", next->name, p);
766 parse_9301_propdesc (params, xmlFirstElementChild (next), &dpd);
Linus Walleij9783ce32014-06-02 21:44:29 +0200767 dpd.DevicePropertyCode = p;
Linus Walleijd9ee8cd2013-11-04 01:54:35 +0100768 di->DevicePropertiesSupported[cnt++] = p;
Linus Walleij9783ce32014-06-02 21:44:29 +0200769
770 /* add to cache of device propdesc */
771 for (i=0;i<params->nrofdeviceproperties;i++)
772 if (params->deviceproperties[i].desc.DevicePropertyCode == p)
773 break;
774 if (i == params->nrofdeviceproperties) {
Marcus Meissner3d692dc2016-02-21 12:34:06 +0100775 params->deviceproperties = realloc(params->deviceproperties,(i+1)*sizeof(params->deviceproperties[0]));
Linus Walleij9783ce32014-06-02 21:44:29 +0200776 memset(&params->deviceproperties[i],0,sizeof(params->deviceproperties[0]));
777 params->nrofdeviceproperties++;
778 } else {
779 ptp_free_devicepropdesc (&params->deviceproperties[i].desc);
780 }
781 /* FIXME: free old entry */
782 /* we are not using dpd, so copy it directly to the cache */
783 time( &params->deviceproperties[i].timestamp);
784 params->deviceproperties[i].desc = dpd;
785
Linus Walleijd9ee8cd2013-11-04 01:54:35 +0100786 next = xmlNextElementSibling (next);
787 }
788 return PTP_RC_OK;
789}
790
791static int
Marcus Meissner3d692dc2016-02-21 12:34:06 +0100792parse_9301_event_tree (PTPParams *params, xmlNodePtr node, PTPDeviceInfo *di)
793{
794 xmlNodePtr next;
795 int cnt;
Linus Walleijd9ee8cd2013-11-04 01:54:35 +0100796
797 cnt = 0;
798 next = xmlFirstElementChild (node);
799 while (next) {
800 cnt++;
801 next = xmlNextElementSibling (next);
802 }
803 di->EventsSupported_len = cnt;
804 di->EventsSupported = malloc (cnt*sizeof(di->EventsSupported[0]));
805 cnt = 0;
806 next = xmlFirstElementChild (node);
807 while (next) {
808 unsigned int p;
809
810 sscanf((char*)next->name, "e%04x", &p);
811 ptp_debug( params, "event %s / 0x%04x", next->name, p);
812 di->EventsSupported[cnt++] = p;
813 next = xmlNextElementSibling (next);
814 }
815 return PTP_RC_OK;
816}
817
818static int
Marcus Meissner3d692dc2016-02-21 12:34:06 +0100819parse_9301_tree (PTPParams *params, xmlNodePtr node, PTPDeviceInfo *di)
820{
Linus Walleijd9ee8cd2013-11-04 01:54:35 +0100821 xmlNodePtr next;
822
823 next = xmlFirstElementChild (node);
824 while (next) {
825 if (!strcmp ((char*)next->name, "cmd")) {
826 parse_9301_cmd_tree (params, next, di);
827 next = xmlNextElementSibling (next);
828 continue;
829 }
830 if (!strcmp ((char*)next->name, "prop")) {
831 parse_9301_prop_tree (params, next, di);
832 next = xmlNextElementSibling (next);
833 continue;
834 }
835 if (!strcmp ((char*)next->name, "event")) {
836 parse_9301_event_tree (params, next, di);
837 next = xmlNextElementSibling (next);
838 continue;
839 }
840 fprintf (stderr,"9301: unhandled type %s\n", next->name);
841 next = xmlNextElementSibling (next);
842 }
843 /*traverse_tree (0, node);*/
844 return PTP_RC_OK;
845}
846
847static uint16_t
Marcus Meissner3d692dc2016-02-21 12:34:06 +0100848ptp_olympus_parse_output_xml(PTPParams* params, char*data, int len, xmlNodePtr *code)
849{
Linus Walleijd9ee8cd2013-11-04 01:54:35 +0100850 xmlDocPtr docin;
851 xmlNodePtr docroot, output, next;
852 int result, xcode;
853
854 *code = NULL;
855
856 docin = xmlReadMemory ((char*)data, len, "http://gphoto.org/", "utf-8", 0);
857 if (!docin) return PTP_RC_GeneralError;
858 docroot = xmlDocGetRootElement (docin);
859 if (!docroot) {
860 xmlFreeDoc (docin);
861 return PTP_RC_GeneralError;
862 }
863
864 if (strcmp((char*)docroot->name,"x3c")) {
865 ptp_debug (params, "olympus: docroot is not x3c, but %s", docroot->name);
866 xmlFreeDoc (docin);
867 return PTP_RC_GeneralError;
868 }
869 if (xmlChildElementCount(docroot) != 1) {
870 ptp_debug (params, "olympus: x3c: expected 1 child, got %ld", xmlChildElementCount(docroot));
871 xmlFreeDoc (docin);
872 return PTP_RC_GeneralError;
873 }
874 output = xmlFirstElementChild (docroot);
875 if (strcmp((char*)output->name, "output") != 0) {
876 ptp_debug (params, "olympus: x3c node: expected child 'output', but got %s", (char*)output->name);
877 xmlFreeDoc (docin);
878 return PTP_RC_GeneralError;
879 }
880 next = xmlFirstElementChild (output);
881
882 result = PTP_RC_GeneralError;
883
884 while (next) {
885 if (!strcmp((char*)next->name,"result")) {
886 xmlChar *xchar;
887
888 xchar = xmlNodeGetContent (next);
889 if (!sscanf((char*)xchar,"%04x",&result))
890 ptp_debug (params, "failed scanning result from %s", xchar);
891 ptp_debug (params, "ptp result is 0x%04x", result);
892 next = xmlNextElementSibling (next);
893 continue;
894 }
895 if (sscanf((char*)next->name,"c%x", &xcode)) {
896 ptp_debug (params, "ptp code node found %s", (char*)next->name);
897 *code = next;
898 next = xmlNextElementSibling (next);
899 continue;
900 }
901 ptp_debug (params, "unhandled node %s", (char*)next->name);
902 next = xmlNextElementSibling (next);
903 }
904
905 if (result != PTP_RC_OK) {
906 *code = NULL;
907 xmlFreeDoc (docin);
908 }
909 return result;
910}
911#endif
912
913uint16_t
914ptp_olympus_getdeviceinfo (PTPParams* params, PTPDeviceInfo *di)
915{
916#ifdef HAVE_LIBXML2
Linus Walleijd9ee8cd2013-11-04 01:54:35 +0100917 PTPContainer ptp;
Marcus Meissner3d692dc2016-02-21 12:34:06 +0100918 uint16_t ret;
Linus Walleijd9ee8cd2013-11-04 01:54:35 +0100919 unsigned char *data;
Marcus Meissner3d692dc2016-02-21 12:34:06 +0100920 unsigned int size;
Linus Walleijd9ee8cd2013-11-04 01:54:35 +0100921 xmlNodePtr code;
922
923 memset (di, 0, sizeof(PTPDeviceInfo));
Linus Walleijd9ee8cd2013-11-04 01:54:35 +0100924
Marcus Meissner3d692dc2016-02-21 12:34:06 +0100925 PTP_CNT_INIT(ptp, PTP_OC_OLYMPUS_GetDeviceInfo);
926 ret=ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size);
927 /* TODO: check for error, only parse_output_xml if ret == PTP_RC_OK?
928 * where is 'data' going to be deallocated? */
929 ret = ptp_olympus_parse_output_xml(params,(char*)data,size,&code);
Linus Walleijd9ee8cd2013-11-04 01:54:35 +0100930 if (ret != PTP_RC_OK)
931 return ret;
932
933 ret = parse_9301_tree (params, code, di);
934
935 xmlFreeDoc(code->doc);
936 return ret;
937#else
938 return PTP_RC_GeneralError;
939#endif
940}
941
942uint16_t
Marcus Meissner3d692dc2016-02-21 12:34:06 +0100943ptp_olympus_opensession (PTPParams* params, unsigned char**data, unsigned int *len)
Linus Walleijd9ee8cd2013-11-04 01:54:35 +0100944{
Linus Walleijd9ee8cd2013-11-04 01:54:35 +0100945 PTPContainer ptp;
Linus Walleijd9ee8cd2013-11-04 01:54:35 +0100946
Marcus Meissner3d692dc2016-02-21 12:34:06 +0100947 PTP_CNT_INIT(ptp, PTP_OC_OLYMPUS_OpenSession);
948 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, data, len);
Linus Walleijd9ee8cd2013-11-04 01:54:35 +0100949}
950
951uint16_t
Marcus Meissner3d692dc2016-02-21 12:34:06 +0100952ptp_olympus_getcameraid (PTPParams* params, unsigned char**data, unsigned int *len)
Linus Walleijd9ee8cd2013-11-04 01:54:35 +0100953{
Linus Walleijd9ee8cd2013-11-04 01:54:35 +0100954 PTPContainer ptp;
Linus Walleijd9ee8cd2013-11-04 01:54:35 +0100955
Marcus Meissner3d692dc2016-02-21 12:34:06 +0100956 PTP_CNT_INIT(ptp, PTP_OC_OLYMPUS_GetCameraID);
957 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, data, len);
Linus Walleijd9ee8cd2013-11-04 01:54:35 +0100958}
959
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000960/**
Linus Walleij1a0c3012009-07-23 23:06:58 +0000961 * ptp_generic_no_data:
962 * params: PTPParams*
963 * code PTP OP Code
964 * n_param count of parameters
965 * ... variable argument list ...
966 *
967 * Emits a generic PTP command without any data transfer.
968 *
969 * Return values: Some PTP_RC_* code.
970 **/
971uint16_t
972ptp_generic_no_data (PTPParams* params, uint16_t code, unsigned int n_param, ...)
973{
Marcus Meissner3d692dc2016-02-21 12:34:06 +0100974 PTPContainer ptp;
975 va_list args;
976 unsigned int i;
Linus Walleij1a0c3012009-07-23 23:06:58 +0000977
978 if( n_param > 5 )
Marcus Meissner3d692dc2016-02-21 12:34:06 +0100979 return PTP_ERROR_BADPARAM;
Linus Walleij1a0c3012009-07-23 23:06:58 +0000980
Marcus Meissner3d692dc2016-02-21 12:34:06 +0100981 memset(&ptp, 0, sizeof(ptp));
Linus Walleij1a0c3012009-07-23 23:06:58 +0000982 ptp.Code=code;
983 ptp.Nparam=n_param;
984
985 va_start(args, n_param);
986 for( i=0; i<n_param; ++i )
987 (&ptp.Param1)[i] = va_arg(args, uint32_t);
988 va_end(args);
989
990 return ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL);
991}
992
993/**
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000994 * ptp_opensession:
995 * params: PTPParams*
996 * session - session number
997 *
998 * Establishes a new session.
999 *
1000 * Return values: Some PTP_RC_* code.
1001 **/
1002uint16_t
1003ptp_opensession (PTPParams* params, uint32_t session)
1004{
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001005 PTPContainer ptp;
1006 uint16_t ret;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001007
1008 ptp_debug(params,"PTP: Opening session");
1009
1010 /* SessonID field of the operation dataset should always
1011 be set to 0 for OpenSession request! */
1012 params->session_id=0x00000000;
1013 /* TransactionID should be set to 0 also! */
1014 params->transaction_id=0x0000000;
Linus Walleijc3e8a432006-12-01 22:17:40 +00001015 /* zero out response packet buffer */
1016 params->response_packet = NULL;
1017 params->response_packet_size = 0;
Linus Walleijc70a6df2007-01-01 22:19:08 +00001018 /* no split headers */
1019 params->split_header_data = 0;
Linus Walleij0fa47022007-01-03 08:21:23 +00001020
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001021 PTP_CNT_INIT(ptp, PTP_OC_OpenSession, session);
Linus Walleij784ac3f2006-12-29 10:36:51 +00001022 ret=ptp_transaction_new(params, &ptp, PTP_DP_NODATA, 0, NULL);
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001023 /* TODO: check for error */
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001024 /* now set the global session id to current session number */
1025 params->session_id=session;
1026 return ret;
1027}
1028
Linus Walleijd9ee8cd2013-11-04 01:54:35 +01001029void
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001030ptp_free_devicepropvalue(uint16_t dt, PTPPropertyValue* dpd)
1031{
Linus Walleijd9ee8cd2013-11-04 01:54:35 +01001032 switch (dt) {
1033 case PTP_DTC_INT8: case PTP_DTC_UINT8:
1034 case PTP_DTC_UINT16: case PTP_DTC_INT16:
1035 case PTP_DTC_UINT32: case PTP_DTC_INT32:
1036 case PTP_DTC_UINT64: case PTP_DTC_INT64:
1037 case PTP_DTC_UINT128: case PTP_DTC_INT128:
1038 /* Nothing to free */
1039 break;
1040 case PTP_DTC_AINT8: case PTP_DTC_AUINT8:
1041 case PTP_DTC_AUINT16: case PTP_DTC_AINT16:
1042 case PTP_DTC_AUINT32: case PTP_DTC_AINT32:
1043 case PTP_DTC_AUINT64: case PTP_DTC_AINT64:
1044 case PTP_DTC_AUINT128: case PTP_DTC_AINT128:
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001045 free(dpd->a.v);
Linus Walleijd9ee8cd2013-11-04 01:54:35 +01001046 break;
1047 case PTP_DTC_STR:
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001048 free(dpd->str);
Linus Walleijd9ee8cd2013-11-04 01:54:35 +01001049 break;
1050 }
1051}
1052
1053void
1054ptp_free_devicepropdesc(PTPDevicePropDesc* dpd)
1055{
1056 uint16_t i;
1057
1058 ptp_free_devicepropvalue (dpd->DataType, &dpd->FactoryDefaultValue);
1059 ptp_free_devicepropvalue (dpd->DataType, &dpd->CurrentValue);
1060 switch (dpd->FormFlag) {
1061 case PTP_DPFF_Range:
1062 ptp_free_devicepropvalue (dpd->DataType, &dpd->FORM.Range.MinimumValue);
1063 ptp_free_devicepropvalue (dpd->DataType, &dpd->FORM.Range.MaximumValue);
1064 ptp_free_devicepropvalue (dpd->DataType, &dpd->FORM.Range.StepSize);
1065 break;
1066 case PTP_DPFF_Enumeration:
1067 if (dpd->FORM.Enum.SupportedValue) {
1068 for (i=0;i<dpd->FORM.Enum.NumberOfValues;i++)
1069 ptp_free_devicepropvalue (dpd->DataType, dpd->FORM.Enum.SupportedValue+i);
1070 free (dpd->FORM.Enum.SupportedValue);
1071 }
1072 }
Linus Walleij9783ce32014-06-02 21:44:29 +02001073 dpd->DataType = PTP_DTC_UNDEF;
1074 dpd->FormFlag = PTP_DPFF_None;
Linus Walleijd9ee8cd2013-11-04 01:54:35 +01001075}
1076
1077
1078void
1079ptp_free_objectpropdesc(PTPObjectPropDesc* opd)
1080{
1081 uint16_t i;
1082
1083 ptp_free_devicepropvalue (opd->DataType, &opd->FactoryDefaultValue);
1084 switch (opd->FormFlag) {
1085 case PTP_OPFF_None:
1086 break;
1087 case PTP_OPFF_Range:
1088 ptp_free_devicepropvalue (opd->DataType, &opd->FORM.Range.MinimumValue);
1089 ptp_free_devicepropvalue (opd->DataType, &opd->FORM.Range.MaximumValue);
1090 ptp_free_devicepropvalue (opd->DataType, &opd->FORM.Range.StepSize);
1091 break;
1092 case PTP_OPFF_Enumeration:
1093 if (opd->FORM.Enum.SupportedValue) {
1094 for (i=0;i<opd->FORM.Enum.NumberOfValues;i++)
1095 ptp_free_devicepropvalue (opd->DataType, opd->FORM.Enum.SupportedValue+i);
1096 free (opd->FORM.Enum.SupportedValue);
1097 }
1098 break;
1099 case PTP_OPFF_DateTime:
1100 case PTP_OPFF_FixedLengthArray:
1101 case PTP_OPFF_RegularExpression:
1102 case PTP_OPFF_ByteArray:
1103 case PTP_OPFF_LongString:
1104 /* Ignore these presently, we cannot unpack them, so there is nothing to be freed. */
1105 break;
1106 default:
1107 fprintf (stderr, "Unknown OPFF type %d\n", opd->FormFlag);
1108 break;
1109 }
1110}
1111
1112
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001113/**
Linus Walleija8a19cc2007-02-02 22:13:17 +00001114 * ptp_free_params:
1115 * params: PTPParams*
1116 *
1117 * Frees all data within the PTPParams struct.
1118 *
1119 * Return values: Some PTP_RC_* code.
1120 **/
1121void
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001122ptp_free_params (PTPParams *params)
1123{
Linus Walleij2ad5b722013-11-04 02:07:44 +01001124 unsigned int i;
Linus Walleijf0bf4372007-07-01 21:47:38 +00001125
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001126 free (params->cameraname);
1127 free (params->wifi_profiles);
Linus Walleijd4637502009-06-14 23:03:33 +00001128 for (i=0;i<params->nrofobjects;i++)
1129 ptp_free_object (&params->objects[i]);
1130 free (params->objects);
Marcus Meissneraa7d91a2017-03-16 15:59:48 +01001131 free (params->storageids.Storage);
Linus Walleij0d762cc2010-04-04 23:34:27 +00001132 free (params->events);
1133 for (i=0;i<params->nrofcanon_props;i++) {
1134 free (params->canon_props[i].data);
1135 ptp_free_devicepropdesc (&params->canon_props[i].dpd);
1136 }
1137 free (params->canon_props);
1138 free (params->backlogentries);
Linus Walleij9783ce32014-06-02 21:44:29 +02001139
1140 for (i=0;i<params->nrofdeviceproperties;i++)
1141 ptp_free_devicepropdesc (&params->deviceproperties[i].desc);
1142 free (params->deviceproperties);
1143
Linus Walleija8a19cc2007-02-02 22:13:17 +00001144 ptp_free_DI (&params->deviceinfo);
1145}
1146
Linus Walleij5d533bb2007-07-17 21:48:57 +00001147/**
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001148 * ptp_getststorageids:
1149 * params: PTPParams*
1150 *
Linus Walleijb02a0662006-04-25 08:05:09 +00001151 * Gets array of StorageIDs and fills the storageids structure.
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001152 *
1153 * Return values: Some PTP_RC_* code.
1154 **/
1155uint16_t
1156ptp_getstorageids (PTPParams* params, PTPStorageIDs* storageids)
1157{
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001158 PTPContainer ptp;
1159 unsigned char *data;
1160 unsigned int size;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001161
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001162 PTP_CNT_INIT(ptp, PTP_OC_GetStorageIDs);
1163 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size));
1164 ptp_unpack_SIDs(params, data, storageids, size);
1165 free(data);
1166 return PTP_RC_OK;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001167}
1168
1169/**
1170 * ptp_getststorageinfo:
1171 * params: PTPParams*
1172 * storageid - StorageID
1173 *
1174 * Gets StorageInfo dataset of desired storage and fills storageinfo
1175 * structure.
1176 *
1177 * Return values: Some PTP_RC_* code.
1178 **/
1179uint16_t
1180ptp_getstorageinfo (PTPParams* params, uint32_t storageid,
1181 PTPStorageInfo* storageinfo)
1182{
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001183 PTPContainer ptp;
1184 unsigned char *data;
1185 unsigned int size;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001186
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001187 PTP_CNT_INIT(ptp, PTP_OC_GetStorageInfo, storageid);
1188 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size));
Marcus Meissneraa7d91a2017-03-16 15:59:48 +01001189 if (!data || !size)
1190 return PTP_RC_GeneralError;
1191 memset(storageinfo, 0, sizeof(*storageinfo));
1192 if (!ptp_unpack_SI(params, data, storageinfo, size)) {
1193 free(data);
1194 return PTP_RC_GeneralError;
1195 }
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001196 free(data);
1197 return PTP_RC_OK;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001198}
1199
1200/**
1201 * ptp_getobjecthandles:
1202 * params: PTPParams*
1203 * storage - StorageID
1204 * objectformatcode - ObjectFormatCode (optional)
1205 * associationOH - ObjectHandle of Association for
1206 * wich a list of children is desired
1207 * (optional)
1208 * objecthandles - pointer to structute
1209 *
1210 * Fills objecthandles with structure returned by device.
1211 *
1212 * Return values: Some PTP_RC_* code.
1213 **/
1214uint16_t
1215ptp_getobjecthandles (PTPParams* params, uint32_t storage,
1216 uint32_t objectformatcode, uint32_t associationOH,
1217 PTPObjectHandles* objecthandles)
1218{
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001219 PTPContainer ptp;
1220 uint16_t ret;
1221 unsigned char *data;
1222 unsigned int size;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001223
Marcus Meissneraa7d91a2017-03-16 15:59:48 +01001224 objecthandles->Handler = NULL;
1225 objecthandles->n = 0;
1226
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001227 PTP_CNT_INIT(ptp, PTP_OC_GetObjectHandles, storage, objectformatcode, associationOH);
1228 ret=ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size);
Linus Walleijf0bf4372007-07-01 21:47:38 +00001229 if (ret == PTP_RC_OK) {
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001230 ptp_unpack_OH(params, data, objecthandles, size);
Linus Walleijf0bf4372007-07-01 21:47:38 +00001231 } else {
1232 if ( (storage == 0xffffffff) &&
1233 (objectformatcode == 0) &&
1234 (associationOH == 0)
1235 ) {
1236 /* When we query all object handles on all stores and
1237 * get an error -> just handle it as "0 handles".
1238 */
1239 objecthandles->Handler = NULL;
1240 objecthandles->n = 0;
1241 ret = PTP_RC_OK;
1242 }
1243 }
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001244 free(data);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001245 return ret;
1246}
1247
Linus Walleij3a1a82c2012-07-03 19:36:28 +02001248uint16_t
1249ptp_getfilesystemmanifest (PTPParams* params, uint32_t storage,
1250 uint32_t objectformatcode, uint32_t associationOH,
1251 unsigned char** data)
1252{
Linus Walleij3a1a82c2012-07-03 19:36:28 +02001253 PTPContainer ptp;
Linus Walleij3a1a82c2012-07-03 19:36:28 +02001254
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001255 PTP_CNT_INIT(ptp, PTP_OC_GetFilesystemManifest, storage, objectformatcode, associationOH);
1256 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, data, NULL);
Linus Walleij3a1a82c2012-07-03 19:36:28 +02001257}
1258
Linus Walleijb02a0662006-04-25 08:05:09 +00001259/**
1260 * ptp_getnumobjects:
1261 * params: PTPParams*
1262 * storage - StorageID
1263 * objectformatcode - ObjectFormatCode (optional)
1264 * associationOH - ObjectHandle of Association for
1265 * wich a list of children is desired
1266 * (optional)
1267 * numobs - pointer to uint32_t that takes number of objects
1268 *
1269 * Fills numobs with number of objects on device.
1270 *
1271 * Return values: Some PTP_RC_* code.
1272 **/
1273uint16_t
1274ptp_getnumobjects (PTPParams* params, uint32_t storage,
1275 uint32_t objectformatcode, uint32_t associationOH,
1276 uint32_t* numobs)
1277{
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001278 PTPContainer ptp;
Linus Walleijb02a0662006-04-25 08:05:09 +00001279
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001280 PTP_CNT_INIT(ptp, PTP_OC_GetNumObjects, storage, objectformatcode, associationOH);
1281 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL));
1282 if (ptp.Nparam >= 1)
1283 *numobs = ptp.Param1;
1284 else
1285 return PTP_RC_GeneralError;
1286 return PTP_RC_OK;
Linus Walleijb02a0662006-04-25 08:05:09 +00001287}
1288
1289/**
Linus Walleij0d762cc2010-04-04 23:34:27 +00001290 * ptp_eos_bulbstart:
1291 * params: PTPParams*
1292 *
1293 * Starts EOS Bulb capture.
1294 *
1295 * Return values: Some PTP_RC_* code.
1296 **/
1297uint16_t
1298ptp_canon_eos_bulbstart (PTPParams* params)
1299{
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001300 PTPContainer ptp;
Linus Walleij0d762cc2010-04-04 23:34:27 +00001301
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001302 PTP_CNT_INIT(ptp, PTP_OC_CANON_EOS_BulbStart);
1303 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL));
1304 if ((ptp.Nparam >= 1) && ((ptp.Param1 & 0x7000) == 0x2000))
1305 return ptp.Param1;
1306 return PTP_RC_OK;
Linus Walleij0d762cc2010-04-04 23:34:27 +00001307}
1308
1309/**
Linus Walleijd7072c32010-12-07 20:43:00 +00001310 * ptp_eos_capture:
1311 * params: PTPParams*
1312 * uint32_t* result
1313 *
1314 * This starts a EOS400D style capture. You have to use the
1315 * get_eos_events to find out what resulted.
1316 * The return value is "0" for all OK, and "1" for capture failed. (not fully confirmed)
1317 *
1318 * Return values: Some PTP_RC_* code.
1319 **/
1320uint16_t
1321ptp_canon_eos_capture (PTPParams* params, uint32_t *result)
1322{
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001323 PTPContainer ptp;
Linus Walleijd7072c32010-12-07 20:43:00 +00001324
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001325 PTP_CNT_INIT(ptp, PTP_OC_CANON_EOS_RemoteRelease);
Linus Walleijd7072c32010-12-07 20:43:00 +00001326 *result = 0;
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001327 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL));
1328 if (ptp.Nparam >= 1)
Linus Walleijd7072c32010-12-07 20:43:00 +00001329 *result = ptp.Param1;
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001330 return PTP_RC_OK;
Linus Walleijd7072c32010-12-07 20:43:00 +00001331}
1332
1333/**
Linus Walleij0d762cc2010-04-04 23:34:27 +00001334 * ptp_canon_eos_bulbend:
1335 * params: PTPParams*
1336 *
1337 * Starts EOS Bulb capture.
1338 *
1339 * Return values: Some PTP_RC_* code.
1340 **/
1341uint16_t
1342ptp_canon_eos_bulbend (PTPParams* params)
1343{
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001344 PTPContainer ptp;
Linus Walleij0d762cc2010-04-04 23:34:27 +00001345
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001346 PTP_CNT_INIT(ptp, PTP_OC_CANON_EOS_BulbEnd);
1347 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL));
1348 if ((ptp.Nparam >= 1) && ((ptp.Param1 & 0x7000) == 0x2000))
1349 return ptp.Param1;
1350 return PTP_RC_OK;
Linus Walleij0d762cc2010-04-04 23:34:27 +00001351}
1352
1353/**
Linus Walleijb02a0662006-04-25 08:05:09 +00001354 * ptp_getobjectinfo:
1355 * params: PTPParams*
1356 * handle - Object handle
1357 * objectinfo - pointer to objectinfo that is returned
1358 *
1359 * Get objectinfo structure for handle from device.
1360 *
1361 * Return values: Some PTP_RC_* code.
1362 **/
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001363uint16_t
1364ptp_getobjectinfo (PTPParams* params, uint32_t handle,
1365 PTPObjectInfo* objectinfo)
1366{
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001367 PTPContainer ptp;
1368 unsigned char *data;
1369 unsigned int size;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001370
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001371 PTP_CNT_INIT(ptp, PTP_OC_GetObjectInfo, handle);
1372 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size));
1373 ptp_unpack_OI(params, data, objectinfo, size);
1374 free(data);
1375 return PTP_RC_OK;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001376}
1377
Linus Walleijb02a0662006-04-25 08:05:09 +00001378/**
1379 * ptp_getobject:
1380 * params: PTPParams*
1381 * handle - Object handle
1382 * object - pointer to data area
1383 *
1384 * Get object 'handle' from device and store the data in newly
1385 * allocated 'object'.
1386 *
1387 * Return values: Some PTP_RC_* code.
1388 **/
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001389uint16_t
Linus Walleijb02a0662006-04-25 08:05:09 +00001390ptp_getobject (PTPParams* params, uint32_t handle, unsigned char** object)
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001391{
1392 PTPContainer ptp;
1393
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001394 PTP_CNT_INIT(ptp, PTP_OC_GetObject, handle);
1395 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, object, NULL);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001396}
1397
Linus Walleijb02a0662006-04-25 08:05:09 +00001398/**
Marcus Meissneraa7d91a2017-03-16 15:59:48 +01001399 * ptp_getobject_with_size:
1400 * params: PTPParams*
1401 * handle - Object handle
1402 * object - pointer to data area
1403 * size - pointer to uint, returns size of object
1404 *
1405 * Get object 'handle' from device and store the data in newly
1406 * allocated 'object'.
1407 *
1408 * Return values: Some PTP_RC_* code.
1409 **/
1410uint16_t
1411ptp_getobject_with_size (PTPParams* params, uint32_t handle, unsigned char** object, unsigned int *size)
1412{
1413 PTPContainer ptp;
1414
1415 PTP_CNT_INIT(ptp, PTP_OC_GetObject, handle);
1416 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, object, size);
1417}
1418
1419/**
Linus Walleij784ac3f2006-12-29 10:36:51 +00001420 * ptp_getobject_to_handler:
1421 * params: PTPParams*
1422 * handle - Object handle
1423 * PTPDataHandler* - pointer datahandler
1424 *
1425 * Get object 'handle' from device and store the data in newly
1426 * allocated 'object'.
1427 *
1428 * Return values: Some PTP_RC_* code.
1429 **/
1430uint16_t
1431ptp_getobject_to_handler (PTPParams* params, uint32_t handle, PTPDataHandler *handler)
1432{
1433 PTPContainer ptp;
1434
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001435 PTP_CNT_INIT(ptp, PTP_OC_GetObject, handle);
Linus Walleij784ac3f2006-12-29 10:36:51 +00001436 return ptp_transaction_new(params, &ptp, PTP_DP_GETDATA, 0, handler);
1437}
1438
1439/**
Linus Walleij96c62432006-08-21 10:04:02 +00001440 * ptp_getobject_tofd:
1441 * params: PTPParams*
1442 * handle - Object handle
1443 * fd - File descriptor to write() to
1444 *
1445 * Get object 'handle' from device and write the data to the
1446 * given file descriptor.
1447 *
1448 * Return values: Some PTP_RC_* code.
1449 **/
1450uint16_t
1451ptp_getobject_tofd (PTPParams* params, uint32_t handle, int fd)
1452{
Linus Walleij784ac3f2006-12-29 10:36:51 +00001453 PTPContainer ptp;
1454 PTPDataHandler handler;
1455 uint16_t ret;
Linus Walleij96c62432006-08-21 10:04:02 +00001456
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001457 PTP_CNT_INIT(ptp, PTP_OC_GetObject, handle);
Linus Walleij784ac3f2006-12-29 10:36:51 +00001458 ptp_init_fd_handler (&handler, fd);
Linus Walleij784ac3f2006-12-29 10:36:51 +00001459 ret = ptp_transaction_new(params, &ptp, PTP_DP_GETDATA, 0, &handler);
1460 ptp_exit_fd_handler (&handler);
1461 return ret;
Linus Walleij96c62432006-08-21 10:04:02 +00001462}
1463
1464/**
Linus Walleijb02a0662006-04-25 08:05:09 +00001465 * ptp_getpartialobject:
1466 * params: PTPParams*
1467 * handle - Object handle
1468 * offset - Offset into object
1469 * maxbytes - Maximum of bytes to read
1470 * object - pointer to data area
Linus Walleij0d762cc2010-04-04 23:34:27 +00001471 * len - pointer to returned length
Linus Walleijb02a0662006-04-25 08:05:09 +00001472 *
1473 * Get object 'handle' from device and store the data in newly
1474 * allocated 'object'. Start from offset and read at most maxbytes.
1475 *
1476 * Return values: Some PTP_RC_* code.
1477 **/
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001478uint16_t
Linus Walleijb02a0662006-04-25 08:05:09 +00001479ptp_getpartialobject (PTPParams* params, uint32_t handle, uint32_t offset,
Linus Walleij0d762cc2010-04-04 23:34:27 +00001480 uint32_t maxbytes, unsigned char** object,
1481 uint32_t *len)
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001482{
1483 PTPContainer ptp;
Linus Walleijb02a0662006-04-25 08:05:09 +00001484
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001485 PTP_CNT_INIT(ptp, PTP_OC_GetPartialObject, handle, offset, maxbytes);
Linus Walleij0d762cc2010-04-04 23:34:27 +00001486 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, object, len);
Linus Walleijb02a0662006-04-25 08:05:09 +00001487}
1488
1489/**
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001490 * ptp_getpartialobject_to_handler:
1491 * params: PTPParams*
1492 * handle - Object handle
1493 * offset - Offset into object
1494 * maxbytes - Maximum of bytes to read
1495 * handler - a ptp data handler
1496 *
1497 * Get object 'handle' from device and send the data to the
1498 * data handler. Start from offset and read at most maxbytes.
1499 *
1500 * Return values: Some PTP_RC_* code.
1501 **/
1502uint16_t
1503ptp_getpartialobject_to_handler (PTPParams* params, uint32_t handle, uint32_t offset,
1504 uint32_t maxbytes, PTPDataHandler *handler)
1505{
1506 PTPContainer ptp;
1507
1508 PTP_CNT_INIT(ptp, PTP_OC_GetPartialObject, handle, offset, maxbytes);
1509 return ptp_transaction_new(params, &ptp, PTP_DP_GETDATA, 0, handler);
1510}
1511
1512/**
Linus Walleijb02a0662006-04-25 08:05:09 +00001513 * ptp_getthumb:
1514 * params: PTPParams*
1515 * handle - Object handle
1516 * object - pointer to data area
1517 *
1518 * Get thumb for object 'handle' from device and store the data in newly
1519 * allocated 'object'.
1520 *
1521 * Return values: Some PTP_RC_* code.
1522 **/
1523uint16_t
Linus Walleij3a1a82c2012-07-03 19:36:28 +02001524ptp_getthumb (PTPParams* params, uint32_t handle, unsigned char** object, unsigned int *len)
Linus Walleijb02a0662006-04-25 08:05:09 +00001525{
1526 PTPContainer ptp;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001527
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001528 PTP_CNT_INIT(ptp, PTP_OC_GetThumb, handle);
Linus Walleij3a1a82c2012-07-03 19:36:28 +02001529 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, object, len);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001530}
1531
1532/**
1533 * ptp_deleteobject:
1534 * params: PTPParams*
1535 * handle - object handle
1536 * ofc - object format code (optional)
1537 *
1538 * Deletes desired objects.
1539 *
1540 * Return values: Some PTP_RC_* code.
1541 **/
1542uint16_t
Linus Walleijb02a0662006-04-25 08:05:09 +00001543ptp_deleteobject (PTPParams* params, uint32_t handle, uint32_t ofc)
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001544{
1545 PTPContainer ptp;
1546
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001547 PTP_CNT_INIT(ptp, PTP_OC_DeleteObject, handle, ofc);
1548 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL));
Linus Walleija6d0d482007-10-31 08:54:56 +00001549 /* If the object is cached and could be removed, cleanse cache. */
1550 ptp_remove_object_from_cache(params, handle);
1551 return PTP_RC_OK;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001552}
1553
1554/**
1555 * ptp_sendobjectinfo:
1556 * params: PTPParams*
1557 * uint32_t* store - destination StorageID on Responder
1558 * uint32_t* parenthandle - Parent ObjectHandle on responder
1559 * uint32_t* handle - see Return values
1560 * PTPObjectInfo* objectinfo- ObjectInfo that is to be sent
1561 *
1562 * Sends ObjectInfo of file that is to be sent via SendFileObject.
1563 *
1564 * Return values: Some PTP_RC_* code.
1565 * Upon success : uint32_t* store - Responder StorageID in which
1566 * object will be stored
1567 * uint32_t* parenthandle- Responder Parent ObjectHandle
1568 * in which the object will be stored
1569 * uint32_t* handle - Responder's reserved ObjectHandle
1570 * for the incoming object
1571 **/
1572uint16_t
1573ptp_sendobjectinfo (PTPParams* params, uint32_t* store,
1574 uint32_t* parenthandle, uint32_t* handle,
1575 PTPObjectInfo* objectinfo)
1576{
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001577 PTPContainer ptp;
1578 uint16_t ret;
1579 unsigned char *data = NULL;
1580 uint32_t size;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001581
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001582 PTP_CNT_INIT(ptp, PTP_OC_SendObjectInfo, *store, *parenthandle);
1583 size = ptp_pack_OI(params, objectinfo, &data);
1584 ret = ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, &data, NULL);
1585 free(data);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001586 *store=ptp.Param1;
1587 *parenthandle=ptp.Param2;
1588 *handle=ptp.Param3;
1589 return ret;
1590}
1591
1592/**
1593 * ptp_sendobject:
1594 * params: PTPParams*
1595 * char* object - contains the object that is to be sent
Linus Walleija381e8a2013-03-05 21:00:06 +01001596 * uint64_t size - object size
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001597 *
1598 * Sends object to Responder.
1599 *
1600 * Return values: Some PTP_RC_* code.
1601 *
1602 */
1603uint16_t
Linus Walleija381e8a2013-03-05 21:00:06 +01001604ptp_sendobject (PTPParams* params, unsigned char* object, uint64_t size)
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001605{
1606 PTPContainer ptp;
1607
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001608 PTP_CNT_INIT(ptp, PTP_OC_SendObject);
Linus Walleijb02a0662006-04-25 08:05:09 +00001609 return ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, &object, NULL);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001610}
1611
Linus Walleije7f44be2006-08-25 19:32:29 +00001612/**
Linus Walleij784ac3f2006-12-29 10:36:51 +00001613 * ptp_sendobject_from_handler:
1614 * params: PTPParams*
1615 * PTPDataHandler* - File descriptor to read() object from
Linus Walleija381e8a2013-03-05 21:00:06 +01001616 * uint64_t size - File/object size
Linus Walleij784ac3f2006-12-29 10:36:51 +00001617 *
1618 * Sends object from file descriptor by consecutive reads from this
1619 * descriptor.
1620 *
1621 * Return values: Some PTP_RC_* code.
1622 **/
1623uint16_t
Linus Walleija381e8a2013-03-05 21:00:06 +01001624ptp_sendobject_from_handler (PTPParams* params, PTPDataHandler *handler, uint64_t size)
Linus Walleij784ac3f2006-12-29 10:36:51 +00001625{
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001626 PTPContainer ptp;
Linus Walleij784ac3f2006-12-29 10:36:51 +00001627
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001628 PTP_CNT_INIT(ptp, PTP_OC_SendObject);
Linus Walleij784ac3f2006-12-29 10:36:51 +00001629 return ptp_transaction_new(params, &ptp, PTP_DP_SENDDATA, size, handler);
1630}
1631
1632
1633/**
Linus Walleije7f44be2006-08-25 19:32:29 +00001634 * ptp_sendobject_fromfd:
1635 * params: PTPParams*
1636 * fd - File descriptor to read() object from
Linus Walleija381e8a2013-03-05 21:00:06 +01001637 * uint64_t size - File/object size
Linus Walleije7f44be2006-08-25 19:32:29 +00001638 *
1639 * Sends object from file descriptor by consecutive reads from this
1640 * descriptor.
1641 *
1642 * Return values: Some PTP_RC_* code.
1643 **/
1644uint16_t
Linus Walleija381e8a2013-03-05 21:00:06 +01001645ptp_sendobject_fromfd (PTPParams* params, int fd, uint64_t size)
Linus Walleije7f44be2006-08-25 19:32:29 +00001646{
Linus Walleij784ac3f2006-12-29 10:36:51 +00001647 PTPContainer ptp;
1648 PTPDataHandler handler;
1649 uint16_t ret;
Linus Walleije7f44be2006-08-25 19:32:29 +00001650
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001651 PTP_CNT_INIT(ptp, PTP_OC_SendObject);
Linus Walleij784ac3f2006-12-29 10:36:51 +00001652 ptp_init_fd_handler (&handler, fd);
Linus Walleij784ac3f2006-12-29 10:36:51 +00001653 ret = ptp_transaction_new(params, &ptp, PTP_DP_SENDDATA, size, &handler);
1654 ptp_exit_fd_handler (&handler);
1655 return ret;
Linus Walleije7f44be2006-08-25 19:32:29 +00001656}
1657
Linus Walleijd9ee8cd2013-11-04 01:54:35 +01001658#define PROPCACHE_TIMEOUT 5 /* seconds */
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001659
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001660uint16_t
1661ptp_getdevicepropdesc (PTPParams* params, uint16_t propcode,
1662 PTPDevicePropDesc* devicepropertydesc)
1663{
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001664 PTPContainer ptp;
1665 uint16_t ret = PTP_RC_OK;
1666 unsigned char *data;
1667 unsigned int size;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001668
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001669 PTP_CNT_INIT(ptp, PTP_OC_GetDevicePropDesc, propcode);
1670 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size));
Linus Walleijd9ee8cd2013-11-04 01:54:35 +01001671
Marcus Meissneraa7d91a2017-03-16 15:59:48 +01001672 if (!data) {
1673 ptp_debug (params, "no data received for getdevicepropdesc");
1674 return PTP_RC_InvalidDevicePropFormat;
1675 }
1676
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001677 if (params->device_flags & DEVICE_FLAG_OLYMPUS_XML_WRAPPED) {
Linus Walleijd9ee8cd2013-11-04 01:54:35 +01001678#ifdef HAVE_LIBXML2
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001679 xmlNodePtr code;
Linus Walleijd9ee8cd2013-11-04 01:54:35 +01001680
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001681 ret = ptp_olympus_parse_output_xml (params,(char*)data,size,&code);
1682 if (ret == PTP_RC_OK) {
1683 int x;
Linus Walleijd9ee8cd2013-11-04 01:54:35 +01001684
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001685 if ( (xmlChildElementCount(code) == 1) &&
Linus Walleijd9ee8cd2013-11-04 01:54:35 +01001686 (!strcmp((char*)code->name,"c1014"))
Linus Walleijd9ee8cd2013-11-04 01:54:35 +01001687 ) {
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001688 code = xmlFirstElementChild (code);
1689
1690 if ( (sscanf((char*)code->name,"p%x", &x)) &&
1691 (x == propcode)
1692 ) {
1693 ret = parse_9301_propdesc (params, xmlFirstElementChild (code), devicepropertydesc);
1694 xmlFreeDoc(code->doc);
Linus Walleijd9ee8cd2013-11-04 01:54:35 +01001695 }
Linus Walleijd9ee8cd2013-11-04 01:54:35 +01001696 }
Linus Walleijd9ee8cd2013-11-04 01:54:35 +01001697 } else {
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001698 ptp_debug(params,"failed to parse output xml, ret %x?", ret);
Linus Walleijd9ee8cd2013-11-04 01:54:35 +01001699 }
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001700#endif
1701 } else {
1702 ptp_unpack_DPD(params, data, devicepropertydesc, size);
Linus Walleijd9ee8cd2013-11-04 01:54:35 +01001703 }
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001704 free(data);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001705 return ret;
1706}
1707
Linus Walleijb02a0662006-04-25 08:05:09 +00001708
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001709uint16_t
1710ptp_getdevicepropvalue (PTPParams* params, uint16_t propcode,
Linus Walleijb02a0662006-04-25 08:05:09 +00001711 PTPPropertyValue* value, uint16_t datatype)
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001712{
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001713 PTPContainer ptp;
1714 unsigned char *data;
1715 unsigned int size, offset = 0;
1716 uint16_t ret;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001717
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001718 PTP_CNT_INIT(ptp, PTP_OC_GetDevicePropValue, propcode);
1719 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size));
1720 ret = ptp_unpack_DPV(params, data, &offset, size, value, datatype) ? PTP_RC_OK : PTP_RC_GeneralError;
1721 if (ret != PTP_RC_OK)
1722 ptp_debug (params, "ptp_getdevicepropvalue: unpacking DPV failed");
1723 free(data);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001724 return ret;
1725}
1726
1727uint16_t
1728ptp_setdevicepropvalue (PTPParams* params, uint16_t propcode,
Linus Walleijb02a0662006-04-25 08:05:09 +00001729 PTPPropertyValue *value, uint16_t datatype)
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001730{
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001731 PTPContainer ptp;
1732 uint16_t ret;
1733 unsigned char *data = NULL;
1734 uint32_t size;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001735
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001736 PTP_CNT_INIT(ptp, PTP_OC_SetDevicePropValue, propcode);
1737 size=ptp_pack_DPV(params, value, &data, datatype);
1738 ret=ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, &data, NULL);
1739 free(data);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001740 return ret;
1741}
1742
1743/**
1744 * ptp_ek_sendfileobjectinfo:
1745 * params: PTPParams*
1746 * uint32_t* store - destination StorageID on Responder
1747 * uint32_t* parenthandle - Parent ObjectHandle on responder
1748 * uint32_t* handle - see Return values
1749 * PTPObjectInfo* objectinfo- ObjectInfo that is to be sent
1750 *
1751 * Sends ObjectInfo of file that is to be sent via SendFileObject.
1752 *
1753 * Return values: Some PTP_RC_* code.
1754 * Upon success : uint32_t* store - Responder StorageID in which
1755 * object will be stored
1756 * uint32_t* parenthandle- Responder Parent ObjectHandle
1757 * in which the object will be stored
1758 * uint32_t* handle - Responder's reserved ObjectHandle
1759 * for the incoming object
1760 **/
1761uint16_t
1762ptp_ek_sendfileobjectinfo (PTPParams* params, uint32_t* store,
1763 uint32_t* parenthandle, uint32_t* handle,
1764 PTPObjectInfo* objectinfo)
1765{
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001766 PTPContainer ptp;
1767 uint16_t ret;
1768 unsigned char *data = NULL;
1769 uint32_t size;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001770
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001771 PTP_CNT_INIT(ptp, PTP_OC_EK_SendFileObjectInfo, *store, *parenthandle);
1772 size=ptp_pack_OI(params, objectinfo, &data);
1773 ret=ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, &data, NULL);
1774 free(data);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001775 *store=ptp.Param1;
1776 *parenthandle=ptp.Param2;
1777 *handle=ptp.Param3;
1778 return ret;
1779}
1780
1781/**
Linus Walleijb02a0662006-04-25 08:05:09 +00001782 * ptp_ek_getserial:
1783 * params: PTPParams*
1784 * char** serial - contains the serial number of the camera
1785 * uint32_t* size - contains the string length
1786 *
1787 * Gets the serial number from the device. (ptp serial)
1788 *
1789 * Return values: Some PTP_RC_* code.
1790 *
1791 */
1792uint16_t
1793ptp_ek_getserial (PTPParams* params, unsigned char **data, unsigned int *size)
1794{
1795 PTPContainer ptp;
1796
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001797 PTP_CNT_INIT(ptp, PTP_OC_EK_GetSerial);
Linus Walleijb02a0662006-04-25 08:05:09 +00001798 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, data, size);
1799}
1800
1801/**
1802 * ptp_ek_setserial:
1803 * params: PTPParams*
1804 * char* serial - contains the new serial number
1805 * uint32_t size - string length
1806 *
1807 * Sets the serial number of the device. (ptp serial)
1808 *
1809 * Return values: Some PTP_RC_* code.
1810 *
1811 */
1812uint16_t
1813ptp_ek_setserial (PTPParams* params, unsigned char *data, unsigned int size)
1814{
1815 PTPContainer ptp;
1816
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001817 PTP_CNT_INIT(ptp, PTP_OC_EK_SetSerial);
Linus Walleijb02a0662006-04-25 08:05:09 +00001818 return ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, &data, NULL);
1819}
1820
1821/* unclear what it does yet */
1822uint16_t
1823ptp_ek_9007 (PTPParams* params, unsigned char **data, unsigned int *size)
1824{
1825 PTPContainer ptp;
1826
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001827 PTP_CNT_INIT(ptp, 0x9007);
Linus Walleijb02a0662006-04-25 08:05:09 +00001828 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, data, size);
1829}
1830
1831/* unclear what it does yet */
1832uint16_t
1833ptp_ek_9009 (PTPParams* params, uint32_t *p1, uint32_t *p2)
1834{
1835 PTPContainer ptp;
Linus Walleijb02a0662006-04-25 08:05:09 +00001836
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001837 PTP_CNT_INIT(ptp, 0x9009);
1838 *p1 = *p2 = 0;
1839 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL));
Linus Walleijb02a0662006-04-25 08:05:09 +00001840 *p1 = ptp.Param1;
1841 *p2 = ptp.Param2;
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001842 return PTP_RC_OK;
Linus Walleijb02a0662006-04-25 08:05:09 +00001843}
1844
1845/* unclear yet, but I guess it returns the info from 9008 */
1846uint16_t
1847ptp_ek_900c (PTPParams* params, unsigned char **data, unsigned int *size)
1848{
1849 PTPContainer ptp;
1850
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001851 PTP_CNT_INIT(ptp, 0x900c);
Linus Walleijb02a0662006-04-25 08:05:09 +00001852 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, data, size);
1853 /* returned data is 16bit,16bit,32bit,32bit */
1854}
1855
1856/**
1857 * ptp_ek_settext:
1858 * params: PTPParams*
1859 * PTPEKTextParams* - contains the texts to display.
1860 *
1861 * Displays the specified texts on the TFT of the camera.
1862 *
1863 * Return values: Some PTP_RC_* code.
1864 *
1865 */
1866uint16_t
1867ptp_ek_settext (PTPParams* params, PTPEKTextParams *text)
1868{
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001869 PTPContainer ptp;
1870 uint16_t ret;
1871 unsigned char *data = 0;
1872 uint32_t size;
Linus Walleijb02a0662006-04-25 08:05:09 +00001873
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001874 PTP_CNT_INIT(ptp, PTP_OC_EK_SetText);
Linus Walleijb02a0662006-04-25 08:05:09 +00001875 if (0 == (size = ptp_pack_EK_text(params, text, &data)))
1876 return PTP_ERROR_BADPARAM;
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001877 ret = ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, &data, NULL);
Linus Walleijb02a0662006-04-25 08:05:09 +00001878 free(data);
1879 return ret;
1880}
1881
1882/**
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001883 * ptp_ek_sendfileobject:
1884 * params: PTPParams*
1885 * char* object - contains the object that is to be sent
1886 * uint32_t size - object size
1887 *
1888 * Sends object to Responder.
1889 *
1890 * Return values: Some PTP_RC_* code.
1891 *
1892 */
1893uint16_t
Linus Walleijb02a0662006-04-25 08:05:09 +00001894ptp_ek_sendfileobject (PTPParams* params, unsigned char* object, uint32_t size)
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001895{
1896 PTPContainer ptp;
1897
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001898 PTP_CNT_INIT(ptp, PTP_OC_EK_SendFileObject);
Linus Walleijb02a0662006-04-25 08:05:09 +00001899 return ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, &object, NULL);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001900}
1901
Linus Walleij784ac3f2006-12-29 10:36:51 +00001902/**
1903 * ptp_ek_sendfileobject_from_handler:
1904 * params: PTPParams*
1905 * PTPDataHandler* handler - contains the handler of the object that is to be sent
1906 * uint32_t size - object size
1907 *
1908 * Sends object to Responder.
1909 *
1910 * Return values: Some PTP_RC_* code.
1911 *
1912 */
1913uint16_t
1914ptp_ek_sendfileobject_from_handler (PTPParams* params, PTPDataHandler*handler, uint32_t size)
1915{
1916 PTPContainer ptp;
1917
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001918 PTP_CNT_INIT(ptp, PTP_OC_EK_SendFileObject);
Linus Walleij784ac3f2006-12-29 10:36:51 +00001919 return ptp_transaction_new(params, &ptp, PTP_DP_SENDDATA, size, handler);
1920}
1921
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001922/*************************************************************************
1923 *
1924 * Canon PTP extensions support
1925 *
1926 * (C) Nikolai Kopanygin 2003
1927 *
1928 *************************************************************************/
1929
1930
1931/**
Linus Walleij7347d0f2006-10-23 07:23:39 +00001932 * ptp_canon_getpartialobjectinfo:
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001933 * params: PTPParams*
1934 * uint32_t handle - ObjectHandle
Linus Walleij7347d0f2006-10-23 07:23:39 +00001935 * uint32_t p2 - Not fully understood parameter
1936 * 0 - returns full size
1937 * 1 - returns thumbnail size (or EXIF?)
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001938 *
1939 * Gets form the responder the size of the specified object.
1940 *
1941 * Return values: Some PTP_RC_* code.
1942 * Upon success : uint32_t* size - The object size
Linus Walleij7347d0f2006-10-23 07:23:39 +00001943 * uint32_t* rp2 - Still unknown return parameter
1944 * (perhaps upper 32bit of size)
1945 *
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001946 *
1947 **/
1948uint16_t
Linus Walleij7347d0f2006-10-23 07:23:39 +00001949ptp_canon_getpartialobjectinfo (PTPParams* params, uint32_t handle, uint32_t p2,
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001950 uint32_t* size, uint32_t* rp2)
1951{
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001952 PTPContainer ptp;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001953
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001954 PTP_CNT_INIT(ptp, PTP_OC_CANON_GetPartialObjectInfo, handle, p2);
1955 *size = *rp2 = 0;
1956 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL));
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001957 *size=ptp.Param1;
1958 *rp2=ptp.Param2;
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001959 return PTP_RC_OK;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001960}
1961
1962/**
Linus Walleij7347d0f2006-10-23 07:23:39 +00001963 * ptp_canon_get_mac_address:
1964 * params: PTPParams*
1965 * value 0 works.
1966 * Gets the MAC address of the wireless transmitter.
1967 *
1968 * Return values: Some PTP_RC_* code.
1969 * Upon success : unsigned char* mac - The MAC address
1970 *
1971 **/
1972uint16_t
1973ptp_canon_get_mac_address (PTPParams* params, unsigned char **mac)
1974{
1975 PTPContainer ptp;
Linus Walleij7347d0f2006-10-23 07:23:39 +00001976
Marcus Meissner3d692dc2016-02-21 12:34:06 +01001977 PTP_CNT_INIT(ptp, PTP_OC_CANON_GetMACAddress);
1978 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, mac, NULL);
Linus Walleij7347d0f2006-10-23 07:23:39 +00001979}
1980
1981/**
1982 * ptp_canon_get_directory:
1983 * params: PTPParams*
1984
1985 * Gets the full directory of the camera.
1986 *
1987 * Return values: Some PTP_RC_* code.
1988 * Upon success : PTPObjectHandles *handles - filled out with handles
1989 * PTPObjectInfo **oinfos - allocated array of PTP Object Infos
1990 * uint32_t **flags - allocated array of CANON Flags
1991 *
1992 **/
1993uint16_t
1994ptp_canon_get_directory (PTPParams* params,
1995 PTPObjectHandles *handles,
1996 PTPObjectInfo **oinfos, /* size(handles->n) */
1997 uint32_t **flags /* size(handles->n) */
1998) {
1999 PTPContainer ptp;
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002000 unsigned char *data;
Linus Walleij7347d0f2006-10-23 07:23:39 +00002001 uint16_t ret;
2002
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002003 PTP_CNT_INIT(ptp, PTP_OC_CANON_GetDirectory);
2004 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, NULL));
2005 ret = ptp_unpack_canon_directory(params, data, ptp.Param1, handles, oinfos, flags);
2006 free (data);
Linus Walleij7347d0f2006-10-23 07:23:39 +00002007 return ret;
2008}
2009
2010/**
Linus Walleijf0bf4372007-07-01 21:47:38 +00002011 * ptp_canon_gettreeinfo:
Linus Walleij7347d0f2006-10-23 07:23:39 +00002012 * params: PTPParams*
2013 * uint32_t *out
2014 *
2015 * Switches the camera display to on and lets the user
2016 * select what to transfer. Sends a 0xc011 event when started
2017 * and 0xc013 if direct transfer aborted.
2018 *
2019 * Return values: Some PTP_RC_* code.
2020 *
2021 **/
2022uint16_t
Linus Walleijf0bf4372007-07-01 21:47:38 +00002023ptp_canon_gettreeinfo (PTPParams* params, uint32_t *out)
Linus Walleij7347d0f2006-10-23 07:23:39 +00002024{
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002025 PTPContainer ptp;
Linus Walleij7347d0f2006-10-23 07:23:39 +00002026
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002027 PTP_CNT_INIT(ptp, PTP_OC_CANON_GetTreeInfo, 0xf);
2028 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL));
2029 if (ptp.Nparam > 0)
Linus Walleij7347d0f2006-10-23 07:23:39 +00002030 *out = ptp.Param1;
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002031 return PTP_RC_OK;
Linus Walleij7347d0f2006-10-23 07:23:39 +00002032}
2033
2034/**
Linus Walleij953504f2007-04-18 19:01:11 +00002035 * ptp_canon_getpairinginfo:
2036 * params: PTPParams*
2037 * int nr
2038 *
2039 * Get the pairing information.
2040 *
2041 * Return values: Some PTP_RC_* code.
2042 *
2043 **/
2044uint16_t
2045ptp_canon_getpairinginfo (PTPParams* params, uint32_t nr, unsigned char **data, unsigned int *size)
2046{
2047 PTPContainer ptp;
Linus Walleij953504f2007-04-18 19:01:11 +00002048
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002049 PTP_CNT_INIT(ptp, PTP_OC_CANON_GetPairingInfo, nr);
2050 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, data, size);
Linus Walleij953504f2007-04-18 19:01:11 +00002051}
2052
2053/**
Linus Walleij7347d0f2006-10-23 07:23:39 +00002054 * ptp_canon_get_target_handles:
2055 * params: PTPParams*
2056 * PTPCanon_directtransfer_entry **out
2057 * unsigned int *outsize
2058 *
2059 * Retrieves direct transfer entries specifying the images to transfer
2060 * from the camera (to be retrieved after 0xc011 event).
2061 *
2062 * Return values: Some PTP_RC_* code.
2063 *
2064 **/
2065uint16_t
Linus Walleijf0bf4372007-07-01 21:47:38 +00002066ptp_canon_gettreesize (PTPParams* params,
Linus Walleij7347d0f2006-10-23 07:23:39 +00002067 PTPCanon_directtransfer_entry **entries, unsigned int *cnt)
2068{
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002069 PTPContainer ptp;
2070 uint16_t ret = PTP_RC_OK;
2071 unsigned char *data, *cur;
2072 unsigned int size, i;
Linus Walleij2ad5b722013-11-04 02:07:44 +01002073
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002074 PTP_CNT_INIT(ptp, PTP_OC_CANON_GetTreeSize);
2075 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size));
2076 *cnt = dtoh32a(data);
Linus Walleij7347d0f2006-10-23 07:23:39 +00002077 *entries = malloc(sizeof(PTPCanon_directtransfer_entry)*(*cnt));
Linus Walleije29ca682010-01-30 08:15:25 +00002078 if (!*entries) {
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002079 ret = PTP_RC_GeneralError;
2080 goto exit;
Linus Walleije29ca682010-01-30 08:15:25 +00002081 }
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002082 cur = data+4;
Linus Walleij7347d0f2006-10-23 07:23:39 +00002083 for (i=0;i<*cnt;i++) {
2084 unsigned char len;
2085 (*entries)[i].oid = dtoh32a(cur);
Marcus Meissneraa7d91a2017-03-16 15:59:48 +01002086 (*entries)[i].str = ptp_unpack_string(params, cur, 4, size-(cur-data-4), &len);
Linus Walleij7347d0f2006-10-23 07:23:39 +00002087 cur += 4+(cur[4]*2+1);
2088 }
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002089exit:
2090 free (data);
2091 return ret;
Linus Walleij7347d0f2006-10-23 07:23:39 +00002092}
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002093
2094/**
2095 * ptp_canon_checkevent:
2096 * params: PTPParams*
2097 *
2098 * The camera has a FIFO stack, in which it accumulates events.
2099 * Partially these events are communicated also via the USB interrupt pipe
2100 * according to the PTP USB specification, partially not.
2101 * This operation returns from the device a block of data, empty,
2102 * if the event stack is empty, or filled with an event's data otherwise.
2103 * The event is removed from the stack in the latter case.
2104 * The Remote Capture app sends this command to the camera all the time
2105 * of connection, filling with it the gaps between other operations.
2106 *
2107 * Return values: Some PTP_RC_* code.
2108 * Upon success : PTPUSBEventContainer* event - is filled with the event data
2109 * if any
2110 * int *isevent - returns 1 in case of event
2111 * or 0 otherwise
2112 **/
2113uint16_t
Linus Walleij7e756532009-05-06 21:25:09 +00002114ptp_canon_checkevent (PTPParams* params, PTPContainer* event, int* isevent)
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002115{
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002116 PTPContainer ptp;
2117 unsigned char *data;
2118 unsigned int size;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002119
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002120 PTP_CNT_INIT(ptp, PTP_OC_CANON_CheckEvent);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002121 *isevent=0;
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002122 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size));
2123 if (data && size) { /* check if we had a successfull call with data */
2124 ptp_unpack_EC(params, data, event, size);
2125 *isevent=1;
2126 free(data);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002127 }
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002128 return PTP_RC_OK;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002129}
2130
Linus Walleij7e756532009-05-06 21:25:09 +00002131uint16_t
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002132ptp_add_event (PTPParams *params, PTPContainer *evt)
2133{
2134 params->events = realloc(params->events, sizeof(PTPContainer)*(params->nrofevents+1));
Linus Walleijd9ee8cd2013-11-04 01:54:35 +01002135 memcpy (&params->events[params->nrofevents],evt,1*sizeof(PTPContainer));
2136 params->nrofevents += 1;
2137 return PTP_RC_OK;
2138}
2139
Marcus Meissneraa7d91a2017-03-16 15:59:48 +01002140static void
2141handle_event_internal (PTPParams *params, PTPContainer *event)
2142{
2143 /* handle some PTP stack internal events */
2144 switch (event->Code) {
2145 case PTP_EC_DevicePropChanged: {
2146 unsigned int i;
2147
2148 /* mark the property for a forced refresh on the next query */
2149 for (i=0;i<params->nrofdeviceproperties;i++)
2150 if (params->deviceproperties[i].desc.DevicePropertyCode == event->Param1) {
2151 params->deviceproperties[i].timestamp = 0;
2152 break;
2153 }
2154 break;
2155 }
2156 case PTP_EC_StoreAdded:
2157 case PTP_EC_StoreRemoved: {
2158 int i;
2159
2160 /* refetch storage IDs and also invalidate whole object tree */
2161 free (params->storageids.Storage);
2162 params->storageids.Storage = NULL;
2163 params->storageids.n = 0;
2164 ptp_getstorageids (params, &params->storageids);
2165
2166 /* free object storage as it might be associated with the storage ids */
2167 /* FIXME: enhance and just delete the ones from the storage */
2168 for (i=0;i<params->nrofobjects;i++)
2169 ptp_free_object (&params->objects[i]);
2170 free (params->objects);
2171 params->objects = NULL;
2172 params->nrofobjects = 0;
2173
2174 params->storagechanged = 1;
2175 break;
2176 }
2177 default: /* check if we should handle it internally too */
2178 break;
2179 }
2180}
2181
2182uint16_t
2183ptp_check_event_queue (PTPParams *params)
2184{
2185 PTPContainer event;
2186 uint16_t ret;
2187
2188 /* We try to do a event check without I/O */
2189 /* Basically this means just looking at the meanwhile queued events */
2190
2191 ret = params->event_check_queue(params,&event);
2192
2193 if (ret == PTP_RC_OK) {
2194 ptp_debug (params, "event: nparams=0x%X, code=0x%X, trans_id=0x%X, p1=0x%X, p2=0x%X, p3=0x%X", event.Nparam,event.Code,event.Transaction_ID, event.Param1, event.Param2, event.Param3);
2195 ptp_add_event (params, &event);
2196 handle_event_internal (params, &event);
2197 }
2198 if (ret == PTP_ERROR_TIMEOUT) /* ok, just new events */
2199 ret = PTP_RC_OK;
2200 return ret;
2201}
2202
Linus Walleijd9ee8cd2013-11-04 01:54:35 +01002203uint16_t
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002204ptp_check_event (PTPParams *params)
2205{
2206 PTPContainer event;
2207 uint16_t ret;
Linus Walleij7e756532009-05-06 21:25:09 +00002208
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002209 /* Method offered by Nikon DSLR, Nikon 1, and some older Nikon Coolpix P*
2210 * The Nikon Coolpix P2 however does not return anything. So if we never get
2211 * events from here, use the ptp "interrupt" method */
Linus Walleij7e756532009-05-06 21:25:09 +00002212 if ( (params->deviceinfo.VendorExtensionID == PTP_VENDOR_NIKON) &&
2213 ptp_operation_issupported(params, PTP_OC_NIKON_CheckEvent)
2214 ) {
Marcus Meissneraa7d91a2017-03-16 15:59:48 +01002215 unsigned int evtcnt = 0, i;
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002216 PTPContainer *xevent = NULL;
Linus Walleij7e756532009-05-06 21:25:09 +00002217
2218 ret = ptp_nikon_check_event(params, &xevent, &evtcnt);
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002219 if (ret != PTP_RC_OperationNotSupported)
2220 CHECK_PTP_RC(ret);
Linus Walleij7e756532009-05-06 21:25:09 +00002221
2222 if (evtcnt) {
Marcus Meissneraa7d91a2017-03-16 15:59:48 +01002223 for (i = 0; i < evtcnt; i++)
2224 handle_event_internal (params, &xevent[i]);
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002225 params->events = realloc(params->events, sizeof(PTPContainer)*(evtcnt+params->nrofevents));
Linus Walleij7e756532009-05-06 21:25:09 +00002226 memcpy (&params->events[params->nrofevents],xevent,evtcnt*sizeof(PTPContainer));
2227 params->nrofevents += evtcnt;
2228 free (xevent);
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002229 params->event90c7works = 1;
Linus Walleij7e756532009-05-06 21:25:09 +00002230 }
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002231 if (params->event90c7works)
2232 return PTP_RC_OK;
2233 /* fall through to generic event handling */
Linus Walleij7e756532009-05-06 21:25:09 +00002234 }
Linus Walleij51856e52012-04-13 19:18:35 +02002235 /* should not get here ... EOS has no normal PTP events and another queue handling. */
2236 if ( (params->deviceinfo.VendorExtensionID == PTP_VENDOR_CANON) &&
2237 ptp_operation_issupported(params, PTP_OC_CANON_EOS_GetEvent)
2238 ) {
2239 return PTP_RC_OK;
2240 }
2241
Linus Walleij7e756532009-05-06 21:25:09 +00002242 if ( (params->deviceinfo.VendorExtensionID == PTP_VENDOR_CANON) &&
2243 ptp_operation_issupported(params, PTP_OC_CANON_CheckEvent)
2244 ) {
2245 int isevent;
2246
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002247 CHECK_PTP_RC(ptp_canon_checkevent (params,&event,&isevent));
2248
2249 if (isevent) {
2250 ret = PTP_RC_OK;
Linus Walleij7e756532009-05-06 21:25:09 +00002251 goto store_event;
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002252 }
Linus Walleij51770e22011-12-13 00:55:25 +01002253 /* Event Emulate Mode 0 (unset) and 1-5 get interrupt events. 6-7 does not. */
2254 if (params->canon_event_mode > 5)
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002255 return PTP_RC_OK;
Linus Walleij51770e22011-12-13 00:55:25 +01002256
Linus Walleij7e756532009-05-06 21:25:09 +00002257 /* FIXME: fallthrough or return? */
Linus Walleij9dd61b12011-06-08 00:45:17 +02002258#ifdef __APPLE__
2259 /* the libusb 1 on darwin currently does not like polling
2260 * for interrupts, they have no timeout for it. 2010/08/23
2261 * Check back in 2011 or so. -Marcus
2262 */
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002263 return PTP_RC_OK;
Linus Walleij9dd61b12011-06-08 00:45:17 +02002264#endif
Linus Walleij7e756532009-05-06 21:25:09 +00002265 }
2266 ret = params->event_check(params,&event);
2267
2268store_event:
2269 if (ret == PTP_RC_OK) {
2270 ptp_debug (params, "event: nparams=0x%X, code=0x%X, trans_id=0x%X, p1=0x%X, p2=0x%X, p3=0x%X", event.Nparam,event.Code,event.Transaction_ID, event.Param1, event.Param2, event.Param3);
Linus Walleijd9ee8cd2013-11-04 01:54:35 +01002271 ptp_add_event (params, &event);
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002272
Marcus Meissneraa7d91a2017-03-16 15:59:48 +01002273 handle_event_internal (params, &event);
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002274
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002275
Linus Walleij7e756532009-05-06 21:25:09 +00002276 }
Linus Walleij749282b2009-08-12 22:56:59 +00002277 if (ret == PTP_ERROR_TIMEOUT) /* ok, just new events */
2278 ret = PTP_RC_OK;
Linus Walleij7e756532009-05-06 21:25:09 +00002279 return ret;
2280}
2281
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002282uint16_t
2283ptp_wait_event (PTPParams *params)
2284{
2285 PTPContainer event;
2286 uint16_t ret;
2287
2288 ret = params->event_wait(params,&event);
2289 if (ret == PTP_RC_OK) {
2290 ptp_debug (params, "event: nparams=0x%X, code=0x%X, trans_id=0x%X, p1=0x%X, p2=0x%X, p3=0x%X", event.Nparam,event.Code,event.Transaction_ID, event.Param1, event.Param2, event.Param3);
2291 ptp_add_event (params, &event);
2292
Marcus Meissneraa7d91a2017-03-16 15:59:48 +01002293 handle_event_internal (params, &event);
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002294 }
2295 if (ret == PTP_ERROR_TIMEOUT) /* ok, just new events */
2296 ret = PTP_RC_OK;
2297 return ret;
2298}
2299
2300
Linus Walleij7e756532009-05-06 21:25:09 +00002301int
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002302ptp_get_one_event(PTPParams *params, PTPContainer *event)
2303{
Linus Walleij7e756532009-05-06 21:25:09 +00002304 if (!params->nrofevents)
2305 return 0;
2306 memcpy (event, params->events, sizeof(PTPContainer));
2307 memmove (params->events, params->events+1, sizeof(PTPContainer)*(params->nrofevents-1));
2308 /* do not realloc on shrink. */
2309 params->nrofevents--;
Linus Walleij0d762cc2010-04-04 23:34:27 +00002310 if (!params->nrofevents) {
2311 free (params->events);
2312 params->events = NULL;
2313 }
Linus Walleij7e756532009-05-06 21:25:09 +00002314 return 1;
2315}
2316
Linus Walleijf0bf4372007-07-01 21:47:38 +00002317/**
2318 * ptp_canon_eos_getevent:
2319 *
2320 * This retrieves configuration status/updates/changes
2321 * on EOS cameras. It reads a datablock which has a list of variable
2322 * sized structures.
2323 *
2324 * params: PTPParams*
2325 *
2326 * Return values: Some PTP_RC_* code.
2327 *
2328 **/
2329uint16_t
2330ptp_canon_eos_getevent (PTPParams* params, PTPCanon_changes_entry **entries, int *nrofentries)
2331{
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002332 PTPContainer ptp;
2333 unsigned char *data;
2334 unsigned int size;
Linus Walleijf0bf4372007-07-01 21:47:38 +00002335
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002336 PTP_CNT_INIT(ptp, PTP_OC_CANON_EOS_GetEvent);
Linus Walleij9d22ce02008-05-28 20:39:29 +00002337 *nrofentries = 0;
2338 *entries = NULL;
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002339 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size));
2340 *nrofentries = ptp_unpack_CANON_changes(params,data,size,entries);
Linus Walleij0d762cc2010-04-04 23:34:27 +00002341 free (data);
Linus Walleijf0bf4372007-07-01 21:47:38 +00002342 return PTP_RC_OK;
2343}
2344
2345uint16_t
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002346ptp_check_eos_events (PTPParams *params)
2347{
Linus Walleij7f275362010-04-25 04:14:26 +00002348 PTPCanon_changes_entry *entries = NULL, *nentries;
2349 int nrofentries = 0;
2350
Linus Walleijd7072c32010-12-07 20:43:00 +00002351 while (1) { /* call it repeatedly until the camera does not report any */
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002352 CHECK_PTP_RC(ptp_canon_eos_getevent (params, &entries, &nrofentries));
Linus Walleijd7072c32010-12-07 20:43:00 +00002353 if (!nrofentries)
2354 return PTP_RC_OK;
Linus Walleij7f275362010-04-25 04:14:26 +00002355
Linus Walleijd7072c32010-12-07 20:43:00 +00002356 if (params->nrofbacklogentries) {
2357 nentries = realloc(params->backlogentries,sizeof(entries[0])*(params->nrofbacklogentries+nrofentries));
2358 if (!nentries)
2359 return PTP_RC_GeneralError;
2360 params->backlogentries = nentries;
2361 memcpy (nentries+params->nrofbacklogentries, entries, nrofentries*sizeof(entries[0]));
2362 params->nrofbacklogentries += nrofentries;
2363 free (entries);
2364 } else {
2365 params->backlogentries = entries;
2366 params->nrofbacklogentries = nrofentries;
2367 }
Linus Walleij7f275362010-04-25 04:14:26 +00002368 }
2369 return PTP_RC_OK;
2370}
2371
2372int
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002373ptp_get_one_eos_event (PTPParams *params, PTPCanon_changes_entry *entry)
2374{
Linus Walleij7f275362010-04-25 04:14:26 +00002375 if (!params->nrofbacklogentries)
2376 return 0;
2377 memcpy (entry, params->backlogentries, sizeof(*entry));
2378 if (params->nrofbacklogentries > 1) {
2379 memmove (params->backlogentries,params->backlogentries+1,sizeof(*entry)*(params->nrofbacklogentries-1));
2380 params->nrofbacklogentries--;
2381 } else {
2382 free (params->backlogentries);
2383 params->backlogentries = NULL;
2384 params->nrofbacklogentries = 0;
2385 }
2386 return 1;
2387}
2388
2389
Linus Walleij7f275362010-04-25 04:14:26 +00002390uint16_t
Linus Walleijf0bf4372007-07-01 21:47:38 +00002391ptp_canon_eos_getdevicepropdesc (PTPParams* params, uint16_t propcode,
2392 PTPDevicePropDesc *dpd)
2393{
Linus Walleij2ad5b722013-11-04 02:07:44 +01002394 unsigned int i;
Linus Walleijf0bf4372007-07-01 21:47:38 +00002395
2396 for (i=0;i<params->nrofcanon_props;i++)
2397 if (params->canon_props[i].proptype == propcode)
2398 break;
2399 if (params->nrofcanon_props == i)
2400 return PTP_RC_Undefined;
2401 memcpy (dpd, &params->canon_props[i].dpd, sizeof (*dpd));
2402 if (dpd->FormFlag == PTP_DPFF_Enumeration) {
2403 /* need to duplicate the Enumeration alloc */
2404 dpd->FORM.Enum.SupportedValue = malloc (sizeof (PTPPropertyValue)*dpd->FORM.Enum.NumberOfValues);
2405 memcpy (dpd->FORM.Enum.SupportedValue,
2406 params->canon_props[i].dpd.FORM.Enum.SupportedValue,
2407 sizeof (PTPPropertyValue)*dpd->FORM.Enum.NumberOfValues
2408 );
Linus Walleijf0bf4372007-07-01 21:47:38 +00002409 }
Linus Walleij1a0c3012009-07-23 23:06:58 +00002410 if (dpd->DataType == PTP_DTC_STR) {
2411 dpd->FactoryDefaultValue.str = strdup( params->canon_props[i].dpd.FactoryDefaultValue.str );
2412 dpd->CurrentValue.str = strdup( params->canon_props[i].dpd.CurrentValue.str );
2413 }
2414
Linus Walleijf0bf4372007-07-01 21:47:38 +00002415 return PTP_RC_OK;
2416}
2417
2418
2419uint16_t
Linus Walleij9d22ce02008-05-28 20:39:29 +00002420ptp_canon_eos_getstorageids (PTPParams* params, PTPStorageIDs* storageids)
Linus Walleijf0bf4372007-07-01 21:47:38 +00002421{
Linus Walleij9d22ce02008-05-28 20:39:29 +00002422 PTPContainer ptp;
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002423 unsigned char *data;
2424 unsigned int size;
2425
2426 PTP_CNT_INIT(ptp, PTP_OC_CANON_EOS_GetStorageIDs);
2427 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size));
2428 ptp_unpack_SIDs(params, data, storageids, size);
2429 free(data);
2430 return PTP_RC_OK;
Linus Walleijf0bf4372007-07-01 21:47:38 +00002431}
2432
2433uint16_t
Linus Walleij0d762cc2010-04-04 23:34:27 +00002434ptp_canon_eos_getstorageinfo (PTPParams* params, uint32_t p1, unsigned char **data, unsigned int *size)
Linus Walleijf0bf4372007-07-01 21:47:38 +00002435{
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002436 PTPContainer ptp;
Linus Walleijf0bf4372007-07-01 21:47:38 +00002437
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002438 PTP_CNT_INIT(ptp, PTP_OC_CANON_EOS_GetStorageInfo, p1);
2439 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, data, size);
Linus Walleijf0bf4372007-07-01 21:47:38 +00002440 /* FIXME: do stuff with data */
Linus Walleijf0bf4372007-07-01 21:47:38 +00002441}
2442
Linus Walleij96aa0e32012-03-25 12:25:25 +02002443uint16_t
2444ptp_canon_eos_getobjectinfoex (
2445 PTPParams* params, uint32_t storageid, uint32_t oid, uint32_t unk,
2446 PTPCANONFolderEntry **entries, unsigned int *nrofentries
2447) {
2448 PTPContainer ptp;
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002449 uint16_t ret = PTP_RC_OK;
Linus Walleij96aa0e32012-03-25 12:25:25 +02002450 unsigned char *data, *xdata;
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002451 unsigned int size, i;
Linus Walleij96aa0e32012-03-25 12:25:25 +02002452
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002453 PTP_CNT_INIT(ptp, PTP_OC_CANON_EOS_GetObjectInfoEx, storageid, oid, unk);
2454 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size));
Linus Walleijd9ee8cd2013-11-04 01:54:35 +01002455 if (!data) {
2456 *nrofentries = 0;
2457 return PTP_RC_OK;
2458 }
2459
Marcus Meissneraa7d91a2017-03-16 15:59:48 +01002460 if (size < 4) {
2461 ret = PTP_RC_GeneralError;
2462 goto exit;
2463 }
2464 /* check for integer overflow */
2465 if (dtoh32a(data) >= INT_MAX/sizeof(PTPCANONFolderEntry)) {
2466 ret = PTP_RC_GeneralError;
2467 goto exit;
2468 }
2469
Linus Walleij96aa0e32012-03-25 12:25:25 +02002470 *nrofentries = dtoh32a(data);
2471 *entries = malloc(*nrofentries * sizeof(PTPCANONFolderEntry));
Linus Walleij9783ce32014-06-02 21:44:29 +02002472 if (!*entries) {
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002473 ret = PTP_RC_GeneralError;
2474 goto exit;
Linus Walleij9783ce32014-06-02 21:44:29 +02002475 }
Linus Walleij96aa0e32012-03-25 12:25:25 +02002476
2477 xdata = data+sizeof(uint32_t);
2478 for (i=0;i<*nrofentries;i++) {
Marcus Meissneraa7d91a2017-03-16 15:59:48 +01002479 if ((dtoh32a(xdata) + (xdata-data)) > size) {
2480 ptp_debug (params, "reading canon FEs run over read data size?\n");
2481 free (*entries);
2482 *entries = NULL;
2483 *nrofentries = 0;
2484 ret = PTP_RC_GeneralError;
2485 goto exit;
2486 }
Linus Walleij96aa0e32012-03-25 12:25:25 +02002487 ptp_unpack_Canon_EOS_FE (params, &xdata[4], &((*entries)[i]));
2488 xdata += dtoh32a(xdata);
2489 }
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002490exit:
Linus Walleij9783ce32014-06-02 21:44:29 +02002491 free (data);
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002492 return ret;
Linus Walleij96aa0e32012-03-25 12:25:25 +02002493}
2494
Linus Walleijf0bf4372007-07-01 21:47:38 +00002495/**
2496 * ptp_canon_eos_getpartialobject:
2497 *
2498 * This retrieves a part of an PTP object which you specify as object id.
2499 * The id originates from 0x9116 call.
2500 * After finishing it, we seem to need to call ptp_canon_eos_enddirecttransfer.
2501 *
2502 * params: PTPParams*
2503 * oid Object ID
2504 * offset The offset where to start the data transfer
2505 * xsize Size in bytes of the transfer to do
2506 * data Pointer that receives the malloc()ed memory of the transfer.
2507 *
2508 * Return values: Some PTP_RC_* code.
2509 *
2510 */
2511uint16_t
2512ptp_canon_eos_getpartialobject (PTPParams* params, uint32_t oid, uint32_t offset, uint32_t xsize, unsigned char**data)
2513{
2514 PTPContainer ptp;
Linus Walleijf0bf4372007-07-01 21:47:38 +00002515
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002516 PTP_CNT_INIT(ptp, PTP_OC_CANON_EOS_GetPartialObject, oid, offset, xsize);
2517 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, data, NULL);
Linus Walleijf0bf4372007-07-01 21:47:38 +00002518}
2519
Linus Walleijf0bf4372007-07-01 21:47:38 +00002520uint16_t
2521ptp_canon_eos_setdevicepropvalueex (PTPParams* params, unsigned char* data, unsigned int size)
2522{
2523 PTPContainer ptp;
2524
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002525 PTP_CNT_INIT(ptp, PTP_OC_CANON_EOS_SetDevicePropValueEx);
Linus Walleijf0bf4372007-07-01 21:47:38 +00002526 return ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, &data, NULL);
2527}
2528
2529uint16_t
Linus Walleij5d533bb2007-07-17 21:48:57 +00002530ptp_canon_eos_setdevicepropvalue (PTPParams* params,
2531 uint16_t propcode, PTPPropertyValue *value, uint16_t datatype
2532) {
2533 PTPContainer ptp;
2534 uint16_t ret;
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002535 unsigned char *data = NULL;
Linus Walleij2ad5b722013-11-04 02:07:44 +01002536 unsigned int i, size;
Linus Walleij5d533bb2007-07-17 21:48:57 +00002537
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002538 PTP_CNT_INIT(ptp, PTP_OC_CANON_EOS_SetDevicePropValueEx);
2539
Linus Walleij5d533bb2007-07-17 21:48:57 +00002540 for (i=0;i<params->nrofcanon_props;i++)
2541 if (params->canon_props[i].proptype == propcode)
2542 break;
2543 if (params->nrofcanon_props == i)
2544 return PTP_RC_Undefined;
Linus Walleij1a0c3012009-07-23 23:06:58 +00002545
2546 switch (propcode) {
2547 case PTP_DPC_CANON_EOS_ImageFormat:
2548 case PTP_DPC_CANON_EOS_ImageFormatCF:
2549 case PTP_DPC_CANON_EOS_ImageFormatSD:
2550 case PTP_DPC_CANON_EOS_ImageFormatExtHD:
2551 /* special handling of ImageFormat properties */
2552 size = 8 + ptp_pack_EOS_ImageFormat( params, NULL, value->u16 );
2553 data = malloc( size );
Linus Walleije29ca682010-01-30 08:15:25 +00002554 if (!data) return PTP_RC_GeneralError;
Linus Walleij1a0c3012009-07-23 23:06:58 +00002555 params->canon_props[i].dpd.CurrentValue.u16 = value->u16;
2556 ptp_pack_EOS_ImageFormat( params, data + 8, value->u16 );
2557 break;
Marcus Meissner0546a762012-04-10 18:49:10 +02002558 case PTP_DPC_CANON_EOS_CustomFuncEx:
2559 /* special handling of CustomFuncEx properties */
2560 ptp_debug (params, "ptp2/ptp_canon_eos_setdevicepropvalue: setting EOS prop %x to %s",propcode,value->str);
2561 size = 8 + ptp_pack_EOS_CustomFuncEx( params, NULL, value->str );
2562 data = malloc( size );
2563 if (!data) return PTP_RC_GeneralError;
2564 params->canon_props[i].dpd.CurrentValue.str = strdup( value->str );
2565 ptp_pack_EOS_CustomFuncEx( params, data + 8, value->str );
2566 break;
Linus Walleij1a0c3012009-07-23 23:06:58 +00002567 default:
2568 if (datatype != PTP_DTC_STR) {
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002569 data = calloc(3,sizeof(uint32_t));
Linus Walleije29ca682010-01-30 08:15:25 +00002570 if (!data) return PTP_RC_GeneralError;
Linus Walleij1a0c3012009-07-23 23:06:58 +00002571 size = sizeof(uint32_t)*3;
2572 } else {
2573 size = strlen(value->str) + 1 + 8;
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002574 data = calloc(size,sizeof(char));
Linus Walleije29ca682010-01-30 08:15:25 +00002575 if (!data) return PTP_RC_GeneralError;
Linus Walleij1a0c3012009-07-23 23:06:58 +00002576 }
2577 switch (datatype) {
Linus Walleije29ca682010-01-30 08:15:25 +00002578 case PTP_DTC_INT8:
Linus Walleij1a0c3012009-07-23 23:06:58 +00002579 case PTP_DTC_UINT8:
2580 /*fprintf (stderr, "%x -> %d\n", propcode, value->u8);*/
2581 htod8a(&data[8], value->u8);
2582 params->canon_props[i].dpd.CurrentValue.u8 = value->u8;
2583 break;
2584 case PTP_DTC_UINT16:
Linus Walleije29ca682010-01-30 08:15:25 +00002585 case PTP_DTC_INT16:
Linus Walleij1a0c3012009-07-23 23:06:58 +00002586 /*fprintf (stderr, "%x -> %d\n", propcode, value->u16);*/
2587 htod16a(&data[8], value->u16);
2588 params->canon_props[i].dpd.CurrentValue.u16 = value->u16;
2589 break;
Linus Walleije29ca682010-01-30 08:15:25 +00002590 case PTP_DTC_INT32:
Linus Walleij1a0c3012009-07-23 23:06:58 +00002591 case PTP_DTC_UINT32:
2592 /*fprintf (stderr, "%x -> %d\n", propcode, value->u32);*/
2593 htod32a(&data[8], value->u32);
2594 params->canon_props[i].dpd.CurrentValue.u32 = value->u32;
2595 break;
2596 case PTP_DTC_STR:
2597 strcpy((char*)data + 8, value->str);
2598 free (params->canon_props[i].dpd.CurrentValue.str);
2599 params->canon_props[i].dpd.CurrentValue.str = strdup(value->str);
2600 break;
2601 }
Linus Walleij5d533bb2007-07-17 21:48:57 +00002602 }
Linus Walleij1a0c3012009-07-23 23:06:58 +00002603
Linus Walleij5d533bb2007-07-17 21:48:57 +00002604 htod32a(&data[0], size);
2605 htod32a(&data[4], propcode);
Linus Walleij1a0c3012009-07-23 23:06:58 +00002606
Linus Walleij5d533bb2007-07-17 21:48:57 +00002607 ret = ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, &data, NULL);
2608 free (data);
2609 return ret;
2610}
2611
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002612/**
2613 * ptp_canon_getpartialobject:
2614 *
2615 * This operation is used to read from the device a data
2616 * block of an object from a specified offset.
2617 *
2618 * params: PTPParams*
2619 * uint32_t handle - the handle of the requested object
2620 * uint32_t offset - the offset in bytes from the beginning of the object
2621 * uint32_t size - the requested size of data block to read
2622 * uint32_t pos - 1 for the first block, 2 - for a block in the middle,
2623 * 3 - for the last block
2624 *
2625 * Return values: Some PTP_RC_* code.
2626 * char **block - the pointer to the block of data read
2627 * uint32_t* readnum - the number of bytes read
2628 *
2629 **/
2630uint16_t
2631ptp_canon_getpartialobject (PTPParams* params, uint32_t handle,
2632 uint32_t offset, uint32_t size,
Linus Walleijb02a0662006-04-25 08:05:09 +00002633 uint32_t pos, unsigned char** block,
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002634 uint32_t* readnum)
2635{
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002636 PTPContainer ptp;
2637 uint16_t ret;
2638 unsigned char *data;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002639
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002640 PTP_CNT_INIT(ptp, PTP_OC_CANON_GetPartialObjectEx, handle, offset, size, pos);
2641 ret=ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, NULL);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002642 if (ret==PTP_RC_OK) {
2643 *block=data;
2644 *readnum=ptp.Param1;
2645 }
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002646 free (data);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002647 return ret;
2648}
2649
2650/**
2651 * ptp_canon_getviewfinderimage:
2652 *
2653 * This operation can be used to read the image which is currently
2654 * in the camera's viewfinder. The image size is 320x240, format is JPEG.
2655 * Of course, prior to calling this operation, one must turn the viewfinder
2656 * on with the CANON_ViewfinderOn command.
2657 * Invoking this operation many times, one can get live video from the camera!
2658 *
2659 * params: PTPParams*
2660 *
2661 * Return values: Some PTP_RC_* code.
2662 * char **image - the pointer to the read image
2663 * unit32_t *size - the size of the image in bytes
2664 *
2665 **/
2666uint16_t
Linus Walleijb02a0662006-04-25 08:05:09 +00002667ptp_canon_getviewfinderimage (PTPParams* params, unsigned char** image, uint32_t* size)
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002668{
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002669 PTPContainer ptp;
2670 uint16_t ret;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002671
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002672 PTP_CNT_INIT(ptp, PTP_OC_CANON_GetViewfinderImage);
2673 ret=ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, image, NULL);
2674 if (ret==PTP_RC_OK)
2675 *size=ptp.Param1;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002676 return ret;
2677}
2678
2679/**
2680 * ptp_canon_getchanges:
2681 *
2682 * This is an interesting operation, about the effect of which I am not sure.
2683 * This command is called every time when a device property has been changed
2684 * with the SetDevicePropValue operation, and after some other operations.
2685 * This operation reads the array of Device Properties which have been changed
2686 * by the previous operation.
2687 * Probably, this operation is even required to make those changes work.
2688 *
2689 * params: PTPParams*
2690 *
2691 * Return values: Some PTP_RC_* code.
2692 * uint16_t** props - the pointer to the array of changed properties
2693 * uint32_t* propnum - the number of elements in the *props array
2694 *
2695 **/
2696uint16_t
2697ptp_canon_getchanges (PTPParams* params, uint16_t** props, uint32_t* propnum)
2698{
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002699 PTPContainer ptp;
2700 unsigned char *data;
2701 unsigned int size;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002702
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002703 PTP_CNT_INIT(ptp, PTP_OC_CANON_GetChanges);
2704 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size));
2705 *propnum=ptp_unpack_uint16_t_array(params,data,0,size,props);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002706 free(data);
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002707 return PTP_RC_OK;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002708}
2709
2710/**
Linus Walleij7347d0f2006-10-23 07:23:39 +00002711 * ptp_canon_getobjectinfo:
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002712 *
2713 * This command reads a specified object's record in a device's filesystem,
2714 * or the records of all objects belonging to a specified folder (association).
2715 *
2716 * params: PTPParams*
2717 * uint32_t store - StorageID,
2718 * uint32_t p2 - Yet unknown (0 value works OK)
2719 * uint32_t parent - Parent Object Handle
2720 * # If Parent Object Handle is 0xffffffff,
2721 * # the Parent Object is the top level folder.
2722 * uint32_t handle - Object Handle
2723 * # If Object Handle is 0, the records of all objects
2724 * # belonging to the Parent Object are read.
2725 * # If Object Handle is not 0, only the record of this
2726 * # Object is read.
2727 *
2728 * Return values: Some PTP_RC_* code.
2729 * PTPCANONFolderEntry** entries - the pointer to the folder entry array
2730 * uint32_t* entnum - the number of elements of the array
2731 *
2732 **/
2733uint16_t
Linus Walleij7347d0f2006-10-23 07:23:39 +00002734ptp_canon_getobjectinfo (PTPParams* params, uint32_t store, uint32_t p2,
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002735 uint32_t parent, uint32_t handle,
2736 PTPCANONFolderEntry** entries, uint32_t* entnum)
2737{
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002738 PTPContainer ptp;
2739 uint16_t ret;
2740 unsigned char *data;
Marcus Meissneraa7d91a2017-03-16 15:59:48 +01002741 unsigned int i, size;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002742
Marcus Meissneraa7d91a2017-03-16 15:59:48 +01002743 *entnum = 0;
2744 *entries = NULL;
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002745 PTP_CNT_INIT(ptp, PTP_OC_CANON_GetObjectInfoEx, store, p2, parent, handle);
Marcus Meissneraa7d91a2017-03-16 15:59:48 +01002746 data = NULL;
2747 size = 0;
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002748 ret=ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, NULL);
2749 if (ret != PTP_RC_OK)
2750 goto exit;
Marcus Meissneraa7d91a2017-03-16 15:59:48 +01002751 if (!data)
2752 return ret;
2753 if (ptp.Param1 > size/PTP_CANON_FolderEntryLen) {
2754 ptp_debug (params, "param1 is %d, size is only %d", ptp.Param1, size);
2755 ret = PTP_RC_GeneralError;
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002756 goto exit;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002757 }
Marcus Meissneraa7d91a2017-03-16 15:59:48 +01002758
2759 *entnum = ptp.Param1;
2760 *entries= calloc(*entnum, sizeof(PTPCANONFolderEntry));
2761 if (*entries == NULL) {
2762 ret = PTP_RC_GeneralError;
2763 goto exit;
2764 }
2765 for(i=0; i<(*entnum); i++) {
2766 if (size < i*PTP_CANON_FolderEntryLen) break;
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002767 ptp_unpack_Canon_FE(params,
2768 data+i*PTP_CANON_FolderEntryLen,
2769 &((*entries)[i]) );
Marcus Meissneraa7d91a2017-03-16 15:59:48 +01002770 }
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002771
2772exit:
2773 free (data);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002774 return ret;
2775}
2776
Linus Walleijb02a0662006-04-25 08:05:09 +00002777/**
Linus Walleij7347d0f2006-10-23 07:23:39 +00002778 * ptp_canon_get_objecthandle_by_name:
Linus Walleij0468fe72006-09-13 11:49:52 +00002779 *
2780 * This command looks up the specified object on the camera.
2781 *
2782 * Format is "A:\\PATH".
2783 *
2784 * The 'A' is the VolumeLabel from GetStorageInfo,
2785 * my IXUS has "A" for the card and "V" for internal memory.
2786 *
2787 * params: PTPParams*
2788 * char* name - path name
2789 *
2790 * Return values: Some PTP_RC_* code.
2791 * uint32_t *oid - PTP object id.
2792 *
2793 **/
2794uint16_t
Linus Walleij7347d0f2006-10-23 07:23:39 +00002795ptp_canon_get_objecthandle_by_name (PTPParams* params, char* name, uint32_t* objectid)
Linus Walleij0468fe72006-09-13 11:49:52 +00002796{
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002797 PTPContainer ptp;
2798 uint16_t ret;
2799 unsigned char *data;
2800 uint8_t len = 0;
Linus Walleij0468fe72006-09-13 11:49:52 +00002801
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002802 PTP_CNT_INIT(ptp, PTP_OC_CANON_GetObjectHandleByName);
Linus Walleij0468fe72006-09-13 11:49:52 +00002803 data = malloc (2*(strlen(name)+1)+2);
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002804 if (!data) return PTP_RC_GeneralError;
Linus Walleij0468fe72006-09-13 11:49:52 +00002805 memset (data, 0, 2*(strlen(name)+1)+2);
2806 ptp_pack_string (params, name, data, 0, &len);
2807 ret=ptp_transaction (params, &ptp, PTP_DP_SENDDATA, (len+1)*2+1, &data, NULL);
2808 free (data);
2809 *objectid = ptp.Param1;
2810 return ret;
2811}
2812
2813/**
Linus Walleij7347d0f2006-10-23 07:23:39 +00002814 * ptp_canon_get_customize_data:
Linus Walleijb02a0662006-04-25 08:05:09 +00002815 *
2816 * This command downloads the specified theme slot, including jpegs
2817 * and wav files.
2818 *
2819 * params: PTPParams*
2820 * uint32_t themenr - nr of theme
2821 *
2822 * Return values: Some PTP_RC_* code.
2823 * unsigned char **data - pointer to data pointer
2824 * unsigned int *size - size of data returned
2825 *
2826 **/
2827uint16_t
Linus Walleij7347d0f2006-10-23 07:23:39 +00002828ptp_canon_get_customize_data (PTPParams* params, uint32_t themenr,
Linus Walleijb02a0662006-04-25 08:05:09 +00002829 unsigned char **data, unsigned int *size)
2830{
2831 PTPContainer ptp;
2832
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002833 PTP_CNT_INIT(ptp, PTP_OC_CANON_GetCustomizeData, themenr);
Linus Walleijb02a0662006-04-25 08:05:09 +00002834 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, data, size);
2835}
2836
2837
Linus Walleijb02a0662006-04-25 08:05:09 +00002838uint16_t
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002839ptp_nikon_curve_download (PTPParams* params, unsigned char **data, unsigned int *size)
2840{
Linus Walleijb02a0662006-04-25 08:05:09 +00002841 PTPContainer ptp;
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002842
2843 PTP_CNT_INIT(ptp, PTP_OC_NIKON_CurveDownload);
Linus Walleijb02a0662006-04-25 08:05:09 +00002844 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, data, size);
2845}
2846
Linus Walleij7e756532009-05-06 21:25:09 +00002847/**
Linus Walleij9783ce32014-06-02 21:44:29 +02002848 * ptp_sony_sdioconnect:
2849 *
2850 * This changes modes of the camera
2851 *
2852 * params: PTPParams*
2853 *
2854 * Return values: Some PTP_RC_* code.
2855 *
2856 **/
2857uint16_t
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002858ptp_sony_sdioconnect (PTPParams* params, uint32_t p1, uint32_t p2, uint32_t p3)
2859{
Linus Walleij9783ce32014-06-02 21:44:29 +02002860 PTPContainer ptp;
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002861 unsigned char *data;
Linus Walleij9783ce32014-06-02 21:44:29 +02002862
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002863 PTP_CNT_INIT(ptp, PTP_OC_SONY_SDIOConnect, p1, p2, p3);
2864 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, NULL));
2865 free (data);
2866 return PTP_RC_OK;
Linus Walleij9783ce32014-06-02 21:44:29 +02002867}
2868/**
2869 * ptp_sony_get_vendorpropcodes:
2870 *
2871 * This command downloads the vendor specific property codes.
2872 *
2873 * params: PTPParams*
2874 *
2875 * Return values: Some PTP_RC_* code.
2876 * unsigned char **data - pointer to data pointer
2877 * unsigned int *size - size of data returned
2878 *
2879 **/
2880uint16_t
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002881ptp_sony_get_vendorpropcodes (PTPParams* params, uint16_t **props, unsigned int *size)
2882{
Linus Walleij9783ce32014-06-02 21:44:29 +02002883 PTPContainer ptp;
Marcus Meissneraa7d91a2017-03-16 15:59:48 +01002884 unsigned char *xdata = NULL;
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002885 unsigned int xsize, psize1 = 0, psize2 = 0;
2886 uint16_t *props1 = NULL,*props2 = NULL;
Linus Walleij9783ce32014-06-02 21:44:29 +02002887
2888 *props = NULL;
2889 *size = 0;
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002890 PTP_CNT_INIT(ptp, PTP_OC_SONY_GetSDIOGetExtDeviceInfo, 0xc8 /* unclear */);
2891 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &xdata, &xsize));
2892 if (xsize == 0) {
2893 ptp_debug (params, "No special operations sent?");
2894 return PTP_RC_OK;
2895 }
2896
2897 psize1 = ptp_unpack_uint16_t_array (params, xdata+2, 0, xsize, &props1);
2898 ptp_debug (params, "xsize %d, got size %d\n", xsize, psize1*2 + 2 + 4);
2899 if (psize1*2 + 2 + 4 < xsize) {
2900 psize2 = ptp_unpack_uint16_t_array(params,xdata+2+psize1*2+4, 0, xsize, &props2);
2901 }
Marcus Meissneraa7d91a2017-03-16 15:59:48 +01002902 *props = calloc(psize1+psize2, sizeof(uint16_t));
2903 if (!*props) {
2904 ptp_debug (params, "oom during malloc?");
2905 free (props1);
2906 free (props2);
2907 free (xdata);
2908 return PTP_RC_OK;
2909 }
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002910 *size = psize1+psize2;
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002911 memcpy (*props, props1, psize1*sizeof(uint16_t));
2912 memcpy ((*props)+psize1, props2, psize2*sizeof(uint16_t));
2913 free (props1);
2914 free (props2);
Linus Walleij9783ce32014-06-02 21:44:29 +02002915 free (xdata);
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002916 return PTP_RC_OK;
Linus Walleij9783ce32014-06-02 21:44:29 +02002917}
2918
2919uint16_t
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002920ptp_sony_getdevicepropdesc (PTPParams* params, uint16_t propcode, PTPDevicePropDesc *dpd)
2921{
Linus Walleij9783ce32014-06-02 21:44:29 +02002922 PTPContainer ptp;
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002923 unsigned char *data;
2924 unsigned int size, len = 0;
Linus Walleij9783ce32014-06-02 21:44:29 +02002925 uint16_t ret;
Linus Walleij9783ce32014-06-02 21:44:29 +02002926
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002927 PTP_CNT_INIT(ptp, PTP_OC_SONY_GetDevicePropdesc, propcode);
2928 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size));
Marcus Meissneraa7d91a2017-03-16 15:59:48 +01002929 if (!data) return PTP_RC_GeneralError;
Linus Walleij9783ce32014-06-02 21:44:29 +02002930 /* first 16 bit is 0xc8 0x00, then an array of 16 bit PTP ids */
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002931 ret = ptp_unpack_Sony_DPD(params,data,dpd,size,&len) ? PTP_RC_OK : PTP_RC_GeneralError;
2932 free (data);
Linus Walleij9783ce32014-06-02 21:44:29 +02002933 return ret;
2934}
2935
2936uint16_t
2937ptp_sony_getalldevicepropdesc (PTPParams* params)
2938{
2939 PTPContainer ptp;
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002940 unsigned char *data, *dpddata;
2941 unsigned int size, readlen;
Linus Walleij9783ce32014-06-02 21:44:29 +02002942 PTPDevicePropDesc dpd;
2943
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002944 PTP_CNT_INIT(ptp, PTP_OC_SONY_GetAllDevicePropData);
2945 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size));
Marcus Meissneraa7d91a2017-03-16 15:59:48 +01002946 if (!data)
2947 return PTP_RC_GeneralError;
2948 if (size <= 8) {
2949 free (data);
2950 return PTP_RC_GeneralError;
2951 }
Linus Walleij9783ce32014-06-02 21:44:29 +02002952 dpddata = data+8; /* nr of entries 32bit, 0 32bit */
2953 size -= 8;
2954 while (size>0) {
2955 unsigned int i;
2956 uint16_t propcode;
2957
2958 if (!ptp_unpack_Sony_DPD (params, dpddata, &dpd, size, &readlen))
2959 break;
2960
2961 propcode = dpd.DevicePropertyCode;
2962
2963 for (i=0;i<params->nrofdeviceproperties;i++)
2964 if (params->deviceproperties[i].desc.DevicePropertyCode == propcode)
2965 break;
2966
Marcus Meissneraa7d91a2017-03-16 15:59:48 +01002967 /* debug output to see what changes */
2968 if (i != params->nrofdeviceproperties) {
2969 switch (dpd.DataType) {
2970 case PTP_DTC_INT8:
2971#define CHECK_CHANGED(type) \
2972 if (params->deviceproperties[i].desc.CurrentValue.type != dpd.CurrentValue.type) \
2973 ptp_debug (params, "ptp_sony_getalldevicepropdesc: %04x: value %d -> %d", propcode, params->deviceproperties[i].desc.CurrentValue.type, dpd.CurrentValue.type);
2974 CHECK_CHANGED(i8);
2975 break;
2976 case PTP_DTC_UINT8:
2977 CHECK_CHANGED(u8);
2978 break;
2979 case PTP_DTC_UINT16:
2980 CHECK_CHANGED(u16);
2981 break;
2982 case PTP_DTC_INT16:
2983 CHECK_CHANGED(i16);
2984 break;
2985 case PTP_DTC_INT32:
2986 CHECK_CHANGED(i32);
2987 break;
2988 case PTP_DTC_UINT32:
2989 CHECK_CHANGED(u32);
2990 break;
2991 default:
2992 break;
2993 }
2994 }
2995
Linus Walleij9783ce32014-06-02 21:44:29 +02002996 if (i == params->nrofdeviceproperties) {
Marcus Meissner3d692dc2016-02-21 12:34:06 +01002997 params->deviceproperties = realloc(params->deviceproperties,(i+1)*sizeof(params->deviceproperties[0]));
Linus Walleij9783ce32014-06-02 21:44:29 +02002998 memset(&params->deviceproperties[i],0,sizeof(params->deviceproperties[0]));
2999 params->nrofdeviceproperties++;
3000 } else {
3001 ptp_free_devicepropdesc (&params->deviceproperties[i].desc);
3002 }
3003 params->deviceproperties[i].desc = dpd;
3004#if 0
3005 ptp_debug (params, "dpd.DevicePropertyCode %04x, readlen %d, getset %d", dpd.DevicePropertyCode, readlen, dpd.GetSet);
3006 switch (dpd.DataType) {
3007 case PTP_DTC_INT8:
3008 ptp_debug (params, "value %d/%x", dpd.CurrentValue.i8, dpd.CurrentValue.i8);
3009 break;
3010 case PTP_DTC_UINT8:
3011 ptp_debug (params, "value %d/%x", dpd.CurrentValue.u8, dpd.CurrentValue.u8);
3012 break;
3013 case PTP_DTC_UINT16:
3014 ptp_debug (params, "value %d/%x", dpd.CurrentValue.u16, dpd.CurrentValue.u16);
3015 break;
3016 case PTP_DTC_INT16:
3017 ptp_debug (params, "value %d/%x", dpd.CurrentValue.i16, dpd.CurrentValue.i16);
3018 break;
3019 case PTP_DTC_INT32:
3020 ptp_debug (params, "value %d/%x", dpd.CurrentValue.i32, dpd.CurrentValue.i32);
3021 break;
3022 case PTP_DTC_UINT32:
3023 ptp_debug (params, "value %d/%x", dpd.CurrentValue.u32, dpd.CurrentValue.u32);
3024 break;
3025 default:
3026 ptp_debug (params, "unknown type %x", dpd.DataType);
3027 break;
3028 }
3029#endif
3030 dpddata += readlen;
3031 size -= readlen;
3032 }
3033 free(data);
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003034 return PTP_RC_OK;
Linus Walleij9783ce32014-06-02 21:44:29 +02003035}
3036
3037uint16_t
3038ptp_sony_setdevicecontrolvaluea (PTPParams* params, uint16_t propcode,
3039 PTPPropertyValue *value, uint16_t datatype)
3040{
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003041 PTPContainer ptp;
3042 uint16_t ret;
3043 unsigned char *data;
3044 uint32_t size;
Linus Walleij9783ce32014-06-02 21:44:29 +02003045
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003046 PTP_CNT_INIT(ptp, PTP_OC_SONY_SetControlDeviceA, propcode);
3047 size = ptp_pack_DPV(params, value, &data, datatype);
3048 ret = ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, &data, NULL);
3049 free(data);
Linus Walleij9783ce32014-06-02 21:44:29 +02003050 return ret;
3051}
3052
3053uint16_t
3054ptp_sony_setdevicecontrolvalueb (PTPParams* params, uint16_t propcode,
3055 PTPPropertyValue *value, uint16_t datatype)
3056{
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003057 PTPContainer ptp;
3058 uint16_t ret;
3059 unsigned char *data;
3060 uint32_t size;
Linus Walleij9783ce32014-06-02 21:44:29 +02003061
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003062 PTP_CNT_INIT(ptp, PTP_OC_SONY_SetControlDeviceB, propcode);
3063 size = ptp_pack_DPV(params, value, &data , datatype);
3064 ret = ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, &data, NULL);
3065 free(data);
3066 return ret;
3067}
3068
3069uint16_t
3070ptp_sony_9280 (PTPParams* params, uint32_t param1,
3071 uint32_t additional, uint32_t data2, uint32_t data3, uint32_t data4, uint8_t x, uint8_t y)
3072{
3073 PTPContainer ptp;
3074 unsigned char buf[18];
3075 unsigned char *buffer;
3076
3077 PTP_CNT_INIT(ptp, 0x9280, param1);
3078
3079 if ((additional != 0) && (additional != 2))
3080 return PTP_RC_GeneralError;
3081
3082 htod32a(&buf[0], additional);
3083 htod32a(&buf[4], data2);
3084 htod32a(&buf[8], data3);
3085 htod32a(&buf[12], data4);
3086
3087 /* only sent in the case where additional is 2 */
3088 buf[16]= x; buf[17]= y;
3089
3090 buffer=buf;
3091 return ptp_transaction(params, &ptp, PTP_DP_SENDDATA, 16+additional, &buffer, NULL);
3092}
3093
3094uint16_t
3095ptp_sony_9281 (PTPParams* params, uint32_t param1) {
3096 PTPContainer ptp;
3097 unsigned int size = 0;
3098 unsigned char *buffer = NULL;
3099 uint16_t ret;
3100
3101 PTP_CNT_INIT(ptp, 0x9281, param1);
3102 ret = ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &buffer, &size);
3103 free (buffer);
Linus Walleij9783ce32014-06-02 21:44:29 +02003104 return ret;
3105}
3106
3107/**
3108 * ptp_generic_getdevicepropdesc:
3109 *
3110 * This command gets a propertydesc.
3111 * If a vendor specific property desc query is available, it uses that.
3112 * If not, it falls back to the generic PTP getdevicepropdesc.
3113 *
3114 * params: PTPParams*
3115 * uint16_t propcode
3116 * PTPDevicePropDesc *dpd
3117 *
3118 * Return values: Some PTP_RC_* code.
3119 *
3120 **/
3121/* Cache time in seconds. Should perhaps be more granular... */
Linus Walleij9783ce32014-06-02 21:44:29 +02003122
3123uint16_t
3124ptp_generic_getdevicepropdesc (PTPParams *params, uint16_t propcode, PTPDevicePropDesc *dpd)
3125{
3126 unsigned int i;
Linus Walleij9783ce32014-06-02 21:44:29 +02003127 time_t now;
3128
3129 for (i=0;i<params->nrofdeviceproperties;i++)
3130 if (params->deviceproperties[i].desc.DevicePropertyCode == propcode)
3131 break;
3132 if (i == params->nrofdeviceproperties) {
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003133 params->deviceproperties = realloc(params->deviceproperties,(i+1)*sizeof(params->deviceproperties[0]));
Linus Walleij9783ce32014-06-02 21:44:29 +02003134 memset(&params->deviceproperties[i],0,sizeof(params->deviceproperties[0]));
3135 params->nrofdeviceproperties++;
3136 }
3137
3138 if (params->deviceproperties[i].desc.DataType != PTP_DTC_UNDEF) {
3139 time(&now);
Marcus Meissneraa7d91a2017-03-16 15:59:48 +01003140 if (params->deviceproperties[i].timestamp + params->cachetime > now) {
Linus Walleij9783ce32014-06-02 21:44:29 +02003141 duplicate_DevicePropDesc(&params->deviceproperties[i].desc, dpd);
3142 return PTP_RC_OK;
3143 }
3144 /* free cached entry as we will refetch it. */
3145 ptp_free_devicepropdesc (&params->deviceproperties[i].desc);
3146 }
3147
3148 if ( (params->deviceinfo.VendorExtensionID == PTP_VENDOR_SONY) &&
3149 ptp_operation_issupported(params, PTP_OC_SONY_GetAllDevicePropData)
3150 ) {
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003151 CHECK_PTP_RC(ptp_sony_getalldevicepropdesc (params));
Linus Walleij9783ce32014-06-02 21:44:29 +02003152
3153 for (i=0;i<params->nrofdeviceproperties;i++)
3154 if (params->deviceproperties[i].desc.DevicePropertyCode == propcode)
3155 break;
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003156 if (i == params->nrofdeviceproperties) {
3157 ptp_debug (params, "property 0x%04x not found?\n", propcode);
3158 return PTP_RC_GeneralError;
3159 }
Linus Walleij9783ce32014-06-02 21:44:29 +02003160 time(&now);
3161 params->deviceproperties[i].timestamp = now;
3162 duplicate_DevicePropDesc(&params->deviceproperties[i].desc, dpd);
3163 return PTP_RC_OK;
3164 }
3165 if ( (params->deviceinfo.VendorExtensionID == PTP_VENDOR_SONY) &&
3166 ptp_operation_issupported(params, PTP_OC_SONY_GetDevicePropdesc)
3167 ) {
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003168 CHECK_PTP_RC(ptp_sony_getdevicepropdesc (params, propcode, &params->deviceproperties[i].desc));
Linus Walleij9783ce32014-06-02 21:44:29 +02003169
3170 time(&now);
3171 params->deviceproperties[i].timestamp = now;
3172 duplicate_DevicePropDesc(&params->deviceproperties[i].desc, dpd);
3173 return PTP_RC_OK;
3174 }
3175
3176
3177 if (ptp_operation_issupported(params, PTP_OC_GetDevicePropDesc)) {
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003178 CHECK_PTP_RC(ptp_getdevicepropdesc (params, propcode, &params->deviceproperties[i].desc));
Linus Walleij9783ce32014-06-02 21:44:29 +02003179
3180 time(&now);
3181 params->deviceproperties[i].timestamp = now;
3182 duplicate_DevicePropDesc(&params->deviceproperties[i].desc, dpd);
3183 return PTP_RC_OK;
3184 }
3185
3186 return PTP_RC_OK;
3187}
3188
3189/**
3190 * ptp_generic_setdevicepropvalue:
3191 *
3192 * This command sets a property value, device specific.
3193 *
3194 * params: PTPParams*
3195 * uint16_t propcode
3196 * PTPDevicePropertyValue *value
3197 * uint16_t datatype
3198 *
3199 * Return values: Some PTP_RC_* code.
3200 *
3201 **/
3202uint16_t
3203ptp_generic_setdevicepropvalue (PTPParams* params, uint16_t propcode,
3204 PTPPropertyValue *value, uint16_t datatype)
3205{
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003206 unsigned int i;
3207
3208 /* reset the cache entry */
3209 for (i=0;i<params->nrofdeviceproperties;i++)
3210 if (params->deviceproperties[i].desc.DevicePropertyCode == propcode)
3211 break;
3212 if (i != params->nrofdeviceproperties)
3213 params->deviceproperties[i].timestamp = 0;
3214
Linus Walleij9783ce32014-06-02 21:44:29 +02003215 /* FIXME: change the cache? hmm */
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003216 /* this works for some methods, but not for all */
Linus Walleij9783ce32014-06-02 21:44:29 +02003217 if ( (params->deviceinfo.VendorExtensionID == PTP_VENDOR_SONY) &&
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003218 ptp_operation_issupported(params, PTP_OC_SONY_SetControlDeviceA)
Linus Walleij9783ce32014-06-02 21:44:29 +02003219 )
3220 return ptp_sony_setdevicecontrolvaluea (params, propcode, value, datatype);
3221 return ptp_setdevicepropvalue (params, propcode, value, datatype);
3222}
3223
3224/**
3225 * ptp_nikon_get_vendorpropcodes:
Linus Walleij7e756532009-05-06 21:25:09 +00003226 *
3227 * This command downloads the vendor specific property codes.
3228 *
3229 * params: PTPParams*
3230 *
3231 * Return values: Some PTP_RC_* code.
3232 * unsigned char **data - pointer to data pointer
3233 * unsigned int *size - size of data returned
3234 *
3235 **/
3236uint16_t
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003237ptp_nikon_get_vendorpropcodes (PTPParams* params, uint16_t **props, unsigned int *size)
3238{
Linus Walleij7e756532009-05-06 21:25:09 +00003239 PTPContainer ptp;
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003240 unsigned char *data = NULL;
3241 unsigned int xsize = 0;
Linus Walleij7e756532009-05-06 21:25:09 +00003242
3243 *props = NULL;
3244 *size = 0;
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003245 PTP_CNT_INIT(ptp, PTP_OC_NIKON_GetVendorPropCodes);
3246 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &xsize));
3247 *size = ptp_unpack_uint16_t_array(params,data,0,xsize,props);
3248 free (data);
3249 return PTP_RC_OK;
Linus Walleij7e756532009-05-06 21:25:09 +00003250}
3251
Linus Walleijb02a0662006-04-25 08:05:09 +00003252uint16_t
3253ptp_nikon_getfileinfoinblock ( PTPParams* params,
3254 uint32_t p1, uint32_t p2, uint32_t p3,
3255 unsigned char **data, unsigned int *size
3256) {
3257 PTPContainer ptp;
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003258
3259 PTP_CNT_INIT(ptp, PTP_OC_NIKON_GetFileInfoInBlock, p1, p2, p3);
Linus Walleijb02a0662006-04-25 08:05:09 +00003260 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, data, size);
3261}
3262
3263/**
Linus Walleij7e756532009-05-06 21:25:09 +00003264 * ptp_nikon_get_liveview_image:
3265 *
3266 * This command gets a LiveView image from newer Nikons DSLRs.
3267 *
3268 * params: PTPParams*
3269 *
3270 * Return values: Some PTP_RC_* code.
3271 *
3272 **/
3273uint16_t
3274ptp_nikon_get_liveview_image (PTPParams* params, unsigned char **data, unsigned int *size)
3275{
3276 PTPContainer ptp;
3277
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003278 PTP_CNT_INIT(ptp, PTP_OC_NIKON_GetLiveViewImg);
Linus Walleij7e756532009-05-06 21:25:09 +00003279 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, data, size);
3280}
3281
3282/**
3283 * ptp_nikon_get_preview_image:
3284 *
3285 * This command gets a Preview image from newer Nikons DSLRs.
3286 *
3287 * params: PTPParams*
3288 *
3289 * Return values: Some PTP_RC_* code.
3290 *
3291 **/
3292uint16_t
3293ptp_nikon_get_preview_image (PTPParams* params, unsigned char **xdata, unsigned int *xsize,
3294 uint32_t *handle)
3295{
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003296 PTPContainer ptp;
3297
3298 PTP_CNT_INIT(ptp, PTP_OC_NIKON_GetPreviewImg);
3299
Linus Walleijd9ee8cd2013-11-04 01:54:35 +01003300 /* FIXME:
3301 * pdslrdashboard passes 3 parameters:
3302 * objectid, minimum size, maximum size
3303 */
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003304 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, xdata, xsize));
3305 if (ptp.Nparam > 0)
3306 *handle = ptp.Param1;
3307 return PTP_RC_OK;
Linus Walleij7e756532009-05-06 21:25:09 +00003308}
3309
3310/**
Linus Walleij7e756532009-05-06 21:25:09 +00003311 * ptp_canon_eos_get_viewfinder_image:
3312 *
3313 * This command gets a Viewfinder image from newer Nikons DSLRs.
3314 *
3315 * params: PTPParams*
3316 *
3317 * Return values: Some PTP_RC_* code.
3318 *
3319 **/
3320uint16_t
3321ptp_canon_eos_get_viewfinder_image (PTPParams* params, unsigned char **data, unsigned int *size)
3322{
3323 PTPContainer ptp;
3324
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003325 PTP_CNT_INIT(ptp, PTP_OC_CANON_EOS_GetViewFinderData, 0x00100000 /* from trace */);
Linus Walleij7e756532009-05-06 21:25:09 +00003326 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, data, size);
3327}
3328
Linus Walleijd6f25ba2011-11-14 23:00:52 +01003329uint16_t
3330ptp_canon_eos_get_viewfinder_image_handler (PTPParams* params, PTPDataHandler*handler)
3331{
3332 PTPContainer ptp;
3333
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003334 PTP_CNT_INIT(ptp, PTP_OC_CANON_EOS_GetViewFinderData, 0x00100000 /* from trace */);
Linus Walleijd6f25ba2011-11-14 23:00:52 +01003335 return ptp_transaction_new(params, &ptp, PTP_DP_GETDATA, 0, handler);
3336}
3337
Linus Walleij7e756532009-05-06 21:25:09 +00003338/**
Linus Walleijb02a0662006-04-25 08:05:09 +00003339 * ptp_nikon_check_event:
3340 *
3341 * This command checks the event queue on the Nikon.
3342 *
3343 * params: PTPParams*
3344 * PTPUSBEventContainer **event - list of usb events.
3345 * int *evtcnt - number of usb events in event structure.
3346 *
3347 * Return values: Some PTP_RC_* code.
3348 *
3349 **/
3350uint16_t
Linus Walleij2ad5b722013-11-04 02:07:44 +01003351ptp_nikon_check_event (PTPParams* params, PTPContainer** event, unsigned int* evtcnt)
Linus Walleijb02a0662006-04-25 08:05:09 +00003352{
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003353 PTPContainer ptp;
3354 unsigned char *data;
3355 unsigned int size;
Linus Walleijb02a0662006-04-25 08:05:09 +00003356
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003357 PTP_CNT_INIT(ptp, PTP_OC_NIKON_CheckEvent);
Linus Walleijb02a0662006-04-25 08:05:09 +00003358 *evtcnt = 0;
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003359 CHECK_PTP_RC(ptp_transaction (params, &ptp, PTP_DP_GETDATA, 0, &data, &size));
3360 ptp_unpack_Nikon_EC (params, data, size, event, evtcnt);
3361 free (data);
3362 return PTP_RC_OK;
Linus Walleijb02a0662006-04-25 08:05:09 +00003363}
3364
3365/**
Linus Walleijb02a0662006-04-25 08:05:09 +00003366 * ptp_nikon_getptpipinfo:
3367 *
3368 * This command gets the ptpip info data.
3369 *
3370 * params: PTPParams*
3371 * unsigned char *data - data
3372 * unsigned int size - size of returned data
3373 *
3374 * Return values: Some PTP_RC_* code.
3375 *
3376 **/
3377uint16_t
3378ptp_nikon_getptpipinfo (PTPParams* params, unsigned char **data, unsigned int *size)
3379{
3380 PTPContainer ptp;
3381
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003382 PTP_CNT_INIT(ptp, PTP_OC_NIKON_GetDevicePTPIPInfo);
Linus Walleijb02a0662006-04-25 08:05:09 +00003383 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, data, size);
3384}
3385
3386/**
Linus Walleijaa4b0752006-07-26 22:21:04 +00003387 * ptp_nikon_getwifiprofilelist:
Linus Walleijb02a0662006-04-25 08:05:09 +00003388 *
Linus Walleijaa4b0752006-07-26 22:21:04 +00003389 * This command gets the wifi profile list.
Linus Walleijb02a0662006-04-25 08:05:09 +00003390 *
3391 * params: PTPParams*
Linus Walleijb02a0662006-04-25 08:05:09 +00003392 *
3393 * Return values: Some PTP_RC_* code.
3394 *
3395 **/
3396uint16_t
Linus Walleijaa4b0752006-07-26 22:21:04 +00003397ptp_nikon_getwifiprofilelist (PTPParams* params)
Linus Walleijb02a0662006-04-25 08:05:09 +00003398{
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003399 PTPContainer ptp;
3400 uint16_t ret;
3401 unsigned char *data;
3402 unsigned int size, pos, profn, n;
3403 char *buffer;
3404 uint8_t len;
3405
3406 PTP_CNT_INIT(ptp, PTP_OC_NIKON_GetProfileAllData);
Linus Walleijaa4b0752006-07-26 22:21:04 +00003407 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size));
3408
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003409 ret = PTP_RC_Undefined; /* FIXME: Add more precise error code */
3410
3411 if (size < 2)
3412 goto exit;
Linus Walleijaa4b0752006-07-26 22:21:04 +00003413
3414 params->wifi_profiles_version = data[0];
3415 params->wifi_profiles_number = data[1];
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003416 free(params->wifi_profiles);
Linus Walleijaa4b0752006-07-26 22:21:04 +00003417
3418 params->wifi_profiles = malloc(params->wifi_profiles_number*sizeof(PTPNIKONWifiProfile));
3419 memset(params->wifi_profiles, 0, params->wifi_profiles_number*sizeof(PTPNIKONWifiProfile));
3420
3421 pos = 2;
3422 profn = 0;
3423 while (profn < params->wifi_profiles_number && pos < size) {
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003424 if (pos+6 >= size)
3425 goto exit;
Linus Walleijaa4b0752006-07-26 22:21:04 +00003426 params->wifi_profiles[profn].id = data[pos++];
3427 params->wifi_profiles[profn].valid = data[pos++];
3428
3429 n = dtoh32a(&data[pos]);
3430 pos += 4;
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003431 if (pos+n+4 >= size)
3432 goto exit;
Linus Walleijaa4b0752006-07-26 22:21:04 +00003433 strncpy(params->wifi_profiles[profn].profile_name, (char*)&data[pos], n);
3434 params->wifi_profiles[profn].profile_name[16] = '\0';
3435 pos += n;
3436
3437 params->wifi_profiles[profn].display_order = data[pos++];
3438 params->wifi_profiles[profn].device_type = data[pos++];
3439 params->wifi_profiles[profn].icon_type = data[pos++];
3440
Marcus Meissneraa7d91a2017-03-16 15:59:48 +01003441 buffer = ptp_unpack_string(params, data, pos, size, &len);
Linus Walleijaa4b0752006-07-26 22:21:04 +00003442 strncpy(params->wifi_profiles[profn].creation_date, buffer, sizeof(params->wifi_profiles[profn].creation_date));
Linus Walleijf0bf4372007-07-01 21:47:38 +00003443 free (buffer);
Linus Walleijaa4b0752006-07-26 22:21:04 +00003444 pos += (len*2+1);
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003445 if (pos+1 >= size)
3446 goto exit;
Linus Walleijaa4b0752006-07-26 22:21:04 +00003447 /* FIXME: check if it is really last usage date */
Marcus Meissneraa7d91a2017-03-16 15:59:48 +01003448 buffer = ptp_unpack_string(params, data, pos, size, &len);
Linus Walleijaa4b0752006-07-26 22:21:04 +00003449 strncpy(params->wifi_profiles[profn].lastusage_date, buffer, sizeof(params->wifi_profiles[profn].lastusage_date));
Linus Walleijf0bf4372007-07-01 21:47:38 +00003450 free (buffer);
Linus Walleijaa4b0752006-07-26 22:21:04 +00003451 pos += (len*2+1);
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003452 if (pos+5 >= size)
3453 goto exit;
Linus Walleijaa4b0752006-07-26 22:21:04 +00003454
3455 n = dtoh32a(&data[pos]);
3456 pos += 4;
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003457 if (pos+n >= size)
3458 goto exit;
Linus Walleijaa4b0752006-07-26 22:21:04 +00003459 strncpy(params->wifi_profiles[profn].essid, (char*)&data[pos], n);
3460 params->wifi_profiles[profn].essid[32] = '\0';
3461 pos += n;
3462 pos += 1;
3463 profn++;
3464 }
3465
3466#if 0
3467 PTPNIKONWifiProfile test;
3468 memset(&test, 0, sizeof(PTPNIKONWifiProfile));
3469 strcpy(test.profile_name, "MyTest");
3470 test.icon_type = 1;
3471 strcpy(test.essid, "nikon");
3472 test.ip_address = 10 + 11 << 16 + 11 << 24;
3473 test.subnet_mask = 24;
3474 test.access_mode = 1;
3475 test.wifi_channel = 1;
3476 test.key_nr = 1;
3477
3478 ptp_nikon_writewifiprofile(params, &test);
3479#endif
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003480 /* everything went Ok */
3481 ret = PTP_RC_OK;
3482exit:
3483 free (data);
3484 return ret;
Linus Walleijb02a0662006-04-25 08:05:09 +00003485}
3486
3487/**
Linus Walleijaa4b0752006-07-26 22:21:04 +00003488 * ptp_nikon_writewifiprofile:
Linus Walleijb02a0662006-04-25 08:05:09 +00003489 *
3490 * This command gets the ptpip info data.
3491 *
3492 * params: PTPParams*
Linus Walleijaa4b0752006-07-26 22:21:04 +00003493 * unsigned int profilenr - profile number
Linus Walleijb02a0662006-04-25 08:05:09 +00003494 * unsigned char *data - data
3495 * unsigned int size - size of returned data
3496 *
3497 * Return values: Some PTP_RC_* code.
3498 *
3499 **/
3500uint16_t
Linus Walleijaa4b0752006-07-26 22:21:04 +00003501ptp_nikon_writewifiprofile (PTPParams* params, PTPNIKONWifiProfile* profile)
Linus Walleijb02a0662006-04-25 08:05:09 +00003502{
Linus Walleijaa4b0752006-07-26 22:21:04 +00003503 PTPContainer ptp;
3504 unsigned char buffer[1024];
3505 unsigned char* data = buffer;
3506 int size = 0;
3507 int i;
3508 uint8_t len;
3509 int profilenr = -1;
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003510 unsigned char guid[16];
3511
Linus Walleijaa4b0752006-07-26 22:21:04 +00003512 ptp_nikon_getptpipguid(guid);
3513
3514 if (!params->wifi_profiles)
3515 CHECK_PTP_RC(ptp_nikon_getwifiprofilelist(params));
3516
3517 for (i = 0; i < params->wifi_profiles_number; i++) {
3518 if (!params->wifi_profiles[i].valid) {
3519 profilenr = params->wifi_profiles[i].id;
3520 break;
3521 }
3522 }
3523
3524 if (profilenr == -1) {
3525 /* No free profile! */
3526 return PTP_RC_StoreFull;
3527 }
3528
3529 memset(buffer, 0, 1024);
3530
3531 buffer[0x00] = 0x64; /* Version */
3532
3533 /* Profile name */
3534 htod32a(&buffer[0x01], 17);
3535 /* 16 as third parameter, so there will always be a null-byte in the end */
3536 strncpy((char*)&buffer[0x05], profile->profile_name, 16);
3537
3538 buffer[0x16] = 0x00; /* Display order */
3539 buffer[0x17] = profile->device_type;
3540 buffer[0x18] = profile->icon_type;
3541
3542 /* FIXME: Creation date: put a real date here */
3543 ptp_pack_string(params, "19990909T090909", data, 0x19, &len);
3544
3545 /* IP parameters */
Linus Walleijd9ee8cd2013-11-04 01:54:35 +01003546 memcpy(&buffer[0x3A],&profile->ip_address,sizeof(profile->ip_address));
3547 /**((unsigned int*)&buffer[0x3A]) = profile->ip_address; *//* Do not reverse bytes */
Linus Walleijaa4b0752006-07-26 22:21:04 +00003548 buffer[0x3E] = profile->subnet_mask;
Linus Walleijd9ee8cd2013-11-04 01:54:35 +01003549 memcpy(&buffer[0x3F],&profile->gateway_address,sizeof(profile->gateway_address));
3550 /**((unsigned int*)&buffer[0x3F]) = profile->gateway_address; */ /* Do not reverse bytes */
Linus Walleijaa4b0752006-07-26 22:21:04 +00003551 buffer[0x43] = profile->address_mode;
3552
3553 /* Wifi parameters */
3554 buffer[0x44] = profile->access_mode;
3555 buffer[0x45] = profile->wifi_channel;
3556
3557 htod32a(&buffer[0x46], 33); /* essid */
3558 /* 32 as third parameter, so there will always be a null-byte in the end */
3559 strncpy((char*)&buffer[0x4A], profile->essid, 32);
3560
3561 buffer[0x6B] = profile->authentification;
3562 buffer[0x6C] = profile->encryption;
3563 htod32a(&buffer[0x6D], 64);
3564 for (i = 0; i < 64; i++) {
3565 buffer[0x71+i] = profile->key[i];
3566 }
3567 buffer[0xB1] = profile->key_nr;
3568 memcpy(&buffer[0xB2], guid, 16);
3569
3570 switch(profile->encryption) {
3571 case 1: /* WEP 64bit */
3572 htod16a(&buffer[0xC2], 5); /* (64-24)/8 = 5 */
3573 break;
3574 case 2: /* WEP 128bit */
3575 htod16a(&buffer[0xC2], 13); /* (128-24)/8 = 13 */
3576 break;
3577 default:
3578 htod16a(&buffer[0xC2], 0);
3579 }
3580 size = 0xC4;
3581
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003582 PTP_CNT_INIT(ptp, PTP_OC_NIKON_SendProfileData, profilenr);
Linus Walleijaa4b0752006-07-26 22:21:04 +00003583 return ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, &data, NULL);
Linus Walleijb02a0662006-04-25 08:05:09 +00003584}
3585
3586/**
3587 * ptp_mtp_getobjectpropssupported:
3588 *
3589 * This command gets the object properties possible from the device.
3590 *
3591 * params: PTPParams*
3592 * uint ofc - object format code
3593 * unsigned int *propnum - number of elements in returned array
3594 * uint16_t *props - array of supported properties
3595 *
3596 * Return values: Some PTP_RC_* code.
3597 *
3598 **/
3599uint16_t
3600ptp_mtp_getobjectpropssupported (PTPParams* params, uint16_t ofc,
3601 uint32_t *propnum, uint16_t **props
3602) {
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003603 PTPContainer ptp;
3604 unsigned char *data = NULL;
3605 unsigned int xsize = 0;
3606
3607 PTP_CNT_INIT(ptp, PTP_OC_MTP_GetObjectPropsSupported, ofc);
3608 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &xsize));
Marcus Meissneraa7d91a2017-03-16 15:59:48 +01003609 if (!data) return PTP_RC_GeneralError;
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003610 *propnum=ptp_unpack_uint16_t_array (params, data, 0, xsize, props);
Linus Walleijb02a0662006-04-25 08:05:09 +00003611 free(data);
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003612 return PTP_RC_OK;
Linus Walleijb02a0662006-04-25 08:05:09 +00003613}
3614
3615/**
3616 * ptp_mtp_getobjectpropdesc:
3617 *
3618 * This command gets the object property description.
3619 *
3620 * params: PTPParams*
3621 * uint16_t opc - object property code
3622 * uint16_t ofc - object format code
3623 *
3624 * Return values: Some PTP_RC_* code.
3625 *
3626 **/
3627uint16_t
3628ptp_mtp_getobjectpropdesc (
3629 PTPParams* params, uint16_t opc, uint16_t ofc, PTPObjectPropDesc *opd
3630) {
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003631 PTPContainer ptp;
3632 unsigned char *data;
3633 unsigned int size;
3634
3635 PTP_CNT_INIT(ptp, PTP_OC_MTP_GetObjectPropDesc, opc, ofc);
3636 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size));
3637 ptp_unpack_OPD (params, data, opd, size);
Linus Walleijb02a0662006-04-25 08:05:09 +00003638 free(data);
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003639 return PTP_RC_OK;
Linus Walleijb02a0662006-04-25 08:05:09 +00003640}
3641
3642/**
3643 * ptp_mtp_getobjectpropvalue:
3644 *
3645 * This command gets the object properties of an object handle.
3646 *
3647 * params: PTPParams*
3648 * uint32_t objectid - object format code
3649 * uint16_t opc - object prop code
3650 *
3651 * Return values: Some PTP_RC_* code.
3652 *
3653 **/
3654uint16_t
3655ptp_mtp_getobjectpropvalue (
3656 PTPParams* params, uint32_t oid, uint16_t opc,
3657 PTPPropertyValue *value, uint16_t datatype
3658) {
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003659 PTPContainer ptp;
3660 uint16_t ret = PTP_RC_OK;
3661 unsigned char *data;
3662 unsigned int size, offset = 0;
Linus Walleijb02a0662006-04-25 08:05:09 +00003663
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003664 PTP_CNT_INIT(ptp, PTP_OC_MTP_GetObjectPropValue, oid, opc);
3665 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size));
3666 if (!ptp_unpack_DPV(params, data, &offset, size, value, datatype)) {
3667 ptp_debug (params, "ptp_mtp_getobjectpropvalue: unpacking DPV failed");
3668 ret = PTP_RC_GeneralError;
3669 }
Linus Walleijb02a0662006-04-25 08:05:09 +00003670 free(data);
3671 return ret;
3672}
3673
3674/**
3675 * ptp_mtp_setobjectpropvalue:
3676 *
3677 * This command gets the object properties of an object handle.
3678 *
3679 * params: PTPParams*
3680 * uint32_t objectid - object format code
3681 * uint16_t opc - object prop code
3682 *
3683 * Return values: Some PTP_RC_* code.
3684 *
3685 **/
3686uint16_t
3687ptp_mtp_setobjectpropvalue (
3688 PTPParams* params, uint32_t oid, uint16_t opc,
3689 PTPPropertyValue *value, uint16_t datatype
3690) {
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003691 PTPContainer ptp;
3692 uint16_t ret;
3693 unsigned char *data = NULL;
3694 uint32_t size;
3695
3696 PTP_CNT_INIT(ptp, PTP_OC_MTP_SetObjectPropValue, oid, opc);
Linus Walleijb02a0662006-04-25 08:05:09 +00003697 size = ptp_pack_DPV(params, value, &data, datatype);
Linus Walleijf67bca92006-05-29 09:33:39 +00003698 ret = ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, &data, NULL);
Linus Walleijb02a0662006-04-25 08:05:09 +00003699 free(data);
3700 return ret;
3701}
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00003702
Linus Walleijf67bca92006-05-29 09:33:39 +00003703uint16_t
3704ptp_mtp_getobjectreferences (PTPParams* params, uint32_t handle, uint32_t** ohArray, uint32_t* arraylen)
3705{
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003706 PTPContainer ptp;
3707 unsigned char *data;
3708 unsigned int size;
Linus Walleijf67bca92006-05-29 09:33:39 +00003709
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003710 PTP_CNT_INIT(ptp, PTP_OC_MTP_GetObjectReferences, handle);
3711 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data , &size));
3712 /* Sandisk Sansa skips the DATA phase, but returns OK as response.
Linus Walleijb8f78c72008-03-02 20:22:56 +00003713 * this will gives us a NULL here. Handle it. -Marcus */
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003714 if ((data == NULL) || (size == 0)) {
3715 *arraylen = 0;
3716 *ohArray = NULL;
3717 } else {
3718 *arraylen = ptp_unpack_uint32_t_array(params, data , 0, size, ohArray);
Linus Walleijb8f78c72008-03-02 20:22:56 +00003719 }
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003720 free(data);
3721 return PTP_RC_OK;
Linus Walleijf67bca92006-05-29 09:33:39 +00003722}
3723
3724uint16_t
3725ptp_mtp_setobjectreferences (PTPParams* params, uint32_t handle, uint32_t* ohArray, uint32_t arraylen)
3726{
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003727 PTPContainer ptp;
3728 uint16_t ret;
3729 unsigned char *data = NULL;
3730 uint32_t size;
Linus Walleijf67bca92006-05-29 09:33:39 +00003731
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003732 PTP_CNT_INIT(ptp, PTP_OC_MTP_SetObjectReferences, handle);
3733 size = ptp_pack_uint32_t_array(params, ohArray, arraylen, &data);
3734 ret = ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, &data, NULL);
3735 free(data);
Linus Walleijf67bca92006-05-29 09:33:39 +00003736 return ret;
3737}
3738
Linus Walleij99310d42006-11-01 08:29:39 +00003739uint16_t
Linus Walleij1e9a0332007-09-12 19:35:56 +00003740ptp_mtp_getobjectproplist (PTPParams* params, uint32_t handle, MTPProperties **props, int *nrofprops)
Linus Walleij3fcfea52006-11-13 07:07:36 +00003741{
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003742 PTPContainer ptp;
3743 unsigned char *data;
3744 unsigned int size;
Linus Walleij3fcfea52006-11-13 07:07:36 +00003745
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003746 PTP_CNT_INIT(ptp, PTP_OC_MTP_GetObjPropList, handle,
3747 0x00000000U, /* 0x00000000U should be "all formats" */
3748 0xFFFFFFFFU, /* 0xFFFFFFFFU should be "all properties" */
3749 0x00000000U,
3750 0xFFFFFFFFU /* means - return full tree below the Param1 handle */
3751 );
3752 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size));
3753 *nrofprops = ptp_unpack_OPL(params, data, props, size);
3754 free(data);
3755 return PTP_RC_OK;
Linus Walleij3fcfea52006-11-13 07:07:36 +00003756}
3757
3758uint16_t
Linus Walleij58cf5d62012-04-26 00:19:38 +02003759ptp_mtp_getobjectproplist_single (PTPParams* params, uint32_t handle, MTPProperties **props, int *nrofprops)
3760{
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003761 PTPContainer ptp;
3762 unsigned char *data;
3763 unsigned int size;
Linus Walleij58cf5d62012-04-26 00:19:38 +02003764
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003765 PTP_CNT_INIT(ptp, PTP_OC_MTP_GetObjPropList, handle,
3766 0x00000000U, /* 0x00000000U should be "all formats" */
3767 0xFFFFFFFFU, /* 0xFFFFFFFFU should be "all properties" */
3768 0x00000000U,
3769 0x00000000U /* means - return single tree below the Param1 handle */
3770 );
3771 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size));
3772 *nrofprops = ptp_unpack_OPL(params, data, props, size);
3773 free(data);
3774 return PTP_RC_OK;
Linus Walleij58cf5d62012-04-26 00:19:38 +02003775}
3776
3777uint16_t
Linus Walleij99310d42006-11-01 08:29:39 +00003778ptp_mtp_sendobjectproplist (PTPParams* params, uint32_t* store, uint32_t* parenthandle, uint32_t* handle,
Linus Walleij1e9a0332007-09-12 19:35:56 +00003779 uint16_t objecttype, uint64_t objectsize, MTPProperties *props, int nrofprops)
Linus Walleij99310d42006-11-01 08:29:39 +00003780{
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003781 PTPContainer ptp;
3782 uint16_t ret;
3783 unsigned char *data = NULL;
3784 uint32_t size;
Linus Walleij99310d42006-11-01 08:29:39 +00003785
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003786 PTP_CNT_INIT(ptp, PTP_OC_MTP_SendObjectPropList, *store, *parenthandle, (uint32_t) objecttype,
3787 (uint32_t) (objectsize >> 32), (uint32_t) (objectsize & 0xffffffffU)
3788 );
Linus Walleij0fa47022007-01-03 08:21:23 +00003789
Linus Walleij99310d42006-11-01 08:29:39 +00003790 /* Set object handle to 0 for a new object */
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003791 size = ptp_pack_OPL(params,props,nrofprops,&data);
3792 ret = ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, &data, NULL);
3793 free(data);
Linus Walleij99310d42006-11-01 08:29:39 +00003794 *store = ptp.Param1;
3795 *parenthandle = ptp.Param2;
3796 *handle = ptp.Param3;
Linus Walleij0fa47022007-01-03 08:21:23 +00003797
Linus Walleij99310d42006-11-01 08:29:39 +00003798 return ret;
3799}
3800
Richard Low15731fe2007-03-22 20:27:20 +00003801uint16_t
Linus Walleij1e9a0332007-09-12 19:35:56 +00003802ptp_mtp_setobjectproplist (PTPParams* params, MTPProperties *props, int nrofprops)
Richard Low15731fe2007-03-22 20:27:20 +00003803{
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003804 PTPContainer ptp;
3805 unsigned char *data = NULL;
3806 uint32_t size;
Linus Walleij1e9a0332007-09-12 19:35:56 +00003807
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003808 PTP_CNT_INIT(ptp, PTP_OC_MTP_SetObjPropList);
3809 size = ptp_pack_OPL(params,props,nrofprops,&data);
3810 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, &data, NULL));
3811 free(data);
3812 return PTP_RC_OK;
Richard Low15731fe2007-03-22 20:27:20 +00003813}
3814
Linus Walleij96aa0e32012-03-25 12:25:25 +02003815uint16_t
3816ptp_mtpz_sendwmdrmpdapprequest (PTPParams* params, unsigned char *appcertmsg, uint32_t size)
3817{
3818 PTPContainer ptp;
3819
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003820 PTP_CNT_INIT(ptp, PTP_OC_MTP_WMDRMPD_SendWMDRMPDAppRequest);
Linus Walleij96aa0e32012-03-25 12:25:25 +02003821 return ptp_transaction (params, &ptp, PTP_DP_SENDDATA, size, &appcertmsg, NULL);
3822}
3823
3824uint16_t
3825ptp_mtpz_getwmdrmpdappresponse (PTPParams* params, unsigned char **response, uint32_t *size)
3826{
3827 PTPContainer ptp;
3828
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003829 PTP_CNT_INIT(ptp, PTP_OC_MTP_WMDRMPD_GetWMDRMPDAppResponse);
Linus Walleij96aa0e32012-03-25 12:25:25 +02003830 *size = 0;
3831 *response = NULL;
3832 return ptp_transaction (params, &ptp, PTP_DP_GETDATA, 0, response, size);
3833}
3834
Linus Walleije206af62011-04-19 01:51:39 +02003835/****** CHDK interface ******/
3836
3837uint16_t
Linus Walleij9783ce32014-06-02 21:44:29 +02003838ptp_chdk_get_memory(PTPParams* params, int start, int num, unsigned char **buf)
Linus Walleije206af62011-04-19 01:51:39 +02003839{
3840 PTPContainer ptp;
3841
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003842 PTP_CNT_INIT(ptp, PTP_OC_CHDK, PTP_CHDK_GetMemory, start, num);
Linus Walleije206af62011-04-19 01:51:39 +02003843 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, buf, NULL);
3844}
3845
Linus Walleije206af62011-04-19 01:51:39 +02003846uint16_t
Linus Walleij9783ce32014-06-02 21:44:29 +02003847ptp_chdk_set_memory_long(PTPParams* params, int addr, int val)
Linus Walleije206af62011-04-19 01:51:39 +02003848{
3849 PTPContainer ptp;
Linus Walleij9783ce32014-06-02 21:44:29 +02003850 unsigned char *buf = (unsigned char *) &val; /* FIXME ... endianness? */
Linus Walleije206af62011-04-19 01:51:39 +02003851
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003852 PTP_CNT_INIT(ptp, PTP_OC_CHDK, PTP_CHDK_SetMemory, addr, 4);
Linus Walleij9783ce32014-06-02 21:44:29 +02003853 return ptp_transaction(params, &ptp, PTP_DP_SENDDATA, 4, &buf, NULL);
Linus Walleije206af62011-04-19 01:51:39 +02003854}
3855
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003856uint16_t
3857ptp_chdk_download(PTPParams* params, char *remote_fn, PTPDataHandler *handler)
3858{
3859 PTPContainer ptp;
3860
3861 PTP_CNT_INIT(ptp, PTP_OC_CHDK, PTP_CHDK_TempData, 0);
3862 CHECK_PTP_RC (ptp_transaction(params, &ptp, PTP_DP_SENDDATA, strlen(remote_fn), (unsigned char**)&remote_fn, NULL));
3863
3864 PTP_CNT_INIT(ptp, PTP_OC_CHDK, PTP_CHDK_DownloadFile);
3865 return ptp_transaction_new (params, &ptp, PTP_DP_GETDATA, 0, handler);
3866}
3867
Linus Walleije206af62011-04-19 01:51:39 +02003868#if 0
Linus Walleij9783ce32014-06-02 21:44:29 +02003869int ptp_chdk_upload(PTPParams* params, char *local_fn, char *remote_fn)
Linus Walleije206af62011-04-19 01:51:39 +02003870{
3871 uint16_t ret;
3872 PTPContainer ptp;
3873 char *buf = NULL;
3874 FILE *f;
Linus Walleij9783ce32014-06-02 21:44:29 +02003875 unsigned file_len,data_len,file_name_len;
Linus Walleije206af62011-04-19 01:51:39 +02003876
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003877 PTP_CNT_INIT(ptp, PTP_OC_CHDK, PTP_CHDK_UploadFile);
Linus Walleije206af62011-04-19 01:51:39 +02003878
Linus Walleije206af62011-04-19 01:51:39 +02003879 f = fopen(local_fn,"rb");
3880 if ( f == NULL )
3881 {
3882 ptp_error(params,"could not open file \'%s\'",local_fn);
3883 return 0;
3884 }
3885
Linus Walleije206af62011-04-19 01:51:39 +02003886 fseek(f,0,SEEK_END);
Linus Walleij9783ce32014-06-02 21:44:29 +02003887 file_len = ftell(f);
Linus Walleije206af62011-04-19 01:51:39 +02003888 fseek(f,0,SEEK_SET);
3889
Linus Walleij9783ce32014-06-02 21:44:29 +02003890 file_name_len = strlen(remote_fn);
3891 data_len = 4 + file_name_len + file_len;
3892 buf = malloc(data_len);
3893 memcpy(buf,&file_name_len,4);
3894 memcpy(buf+4,remote_fn,file_name_len);
3895 fread(buf+4+file_name_len,1,file_len,f);
Linus Walleije206af62011-04-19 01:51:39 +02003896
3897 fclose(f);
3898
Linus Walleij9783ce32014-06-02 21:44:29 +02003899 ret=ptp_transaction(params, &ptp, PTP_DP_SENDDATA, data_len, &buf, NULL);
Linus Walleije206af62011-04-19 01:51:39 +02003900
3901 free(buf);
3902
Linus Walleij9783ce32014-06-02 21:44:29 +02003903 if ( ret != PTP_RC_OK )
Linus Walleije206af62011-04-19 01:51:39 +02003904 {
3905 ptp_error(params,"unexpected return code 0x%x",ret);
3906 return 0;
3907 }
3908 return 1;
3909}
3910
Linus Walleije206af62011-04-19 01:51:39 +02003911#endif
3912
Linus Walleij9783ce32014-06-02 21:44:29 +02003913/*
3914 * Preliminary remote capture over USB code. Corresponding CHDK code is in the ptp-remote-capture-test
3915 * This is under development and should not be included in builds for general distribution
3916 */
3917/*
3918 * isready: 0: not ready, lowest 2 bits: available image formats, 0x10000000: error
3919 */
Linus Walleije206af62011-04-19 01:51:39 +02003920uint16_t
Linus Walleij9783ce32014-06-02 21:44:29 +02003921ptp_chdk_rcisready(PTPParams* params, int *isready, int *imgnum)
3922{
Linus Walleij9783ce32014-06-02 21:44:29 +02003923 PTPContainer ptp;
3924
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003925 PTP_CNT_INIT(ptp, PTP_OC_CHDK, PTP_CHDK_RemoteCaptureIsReady);
3926 *isready = *imgnum = 0;
3927 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL));
Linus Walleij9783ce32014-06-02 21:44:29 +02003928 *isready=ptp.Param1;
3929 *imgnum=ptp.Param2;
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003930 return PTP_RC_OK;
Linus Walleij9783ce32014-06-02 21:44:29 +02003931}
3932
3933uint16_t
3934ptp_chdk_rcgetchunk(PTPParams* params, int fmt, ptp_chdk_rc_chunk *chunk)
3935{
Linus Walleij9783ce32014-06-02 21:44:29 +02003936 PTPContainer ptp;
3937
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003938 PTP_CNT_INIT(ptp, PTP_OC_CHDK, PTP_CHDK_RemoteCaptureGetData, fmt); //get chunk
Linus Walleij9783ce32014-06-02 21:44:29 +02003939
3940 chunk->data = NULL;
3941 chunk->size = 0;
3942 chunk->offset = 0;
3943 chunk->last = 0;
Linus Walleij9783ce32014-06-02 21:44:29 +02003944 // TODO should allow ptp_getdata_transaction to send chunks directly to file, or to mem
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003945 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &chunk->data, NULL));
Linus Walleij9783ce32014-06-02 21:44:29 +02003946 chunk->size = ptp.Param1;
3947 chunk->last = (ptp.Param2 == 0);
3948 chunk->offset = ptp.Param3; //-1 for none
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003949 return PTP_RC_OK;
Linus Walleij9783ce32014-06-02 21:44:29 +02003950}
3951
3952uint16_t
3953ptp_chdk_exec_lua(PTPParams* params, char *script, int flags, int *script_id, int *status)
3954{
Linus Walleij9783ce32014-06-02 21:44:29 +02003955 PTPContainer ptp;
3956
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003957 PTP_CNT_INIT(ptp, PTP_OC_CHDK, PTP_CHDK_ExecuteScript, PTP_CHDK_SL_LUA | flags);
3958 *script_id = 0;
3959 *status = 0;
3960 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_SENDDATA, strlen(script)+1, (unsigned char**)&script, NULL));
3961 *script_id = ptp.Param1;
3962 *status = ptp.Param2;
3963 return PTP_RC_OK;
Linus Walleij9783ce32014-06-02 21:44:29 +02003964}
3965
3966uint16_t
3967ptp_chdk_get_version(PTPParams* params, int *major, int *minor)
Linus Walleije206af62011-04-19 01:51:39 +02003968{
Linus Walleije206af62011-04-19 01:51:39 +02003969 PTPContainer ptp;
3970
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003971 PTP_CNT_INIT(ptp, PTP_OC_CHDK, PTP_CHDK_Version);
3972 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL));
Linus Walleij9783ce32014-06-02 21:44:29 +02003973 *major = ptp.Param1;
3974 *minor = ptp.Param2;
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003975 return PTP_RC_OK;
Linus Walleije206af62011-04-19 01:51:39 +02003976}
3977
3978uint16_t
Linus Walleij9783ce32014-06-02 21:44:29 +02003979ptp_chdk_get_script_status(PTPParams* params, unsigned *status)
3980{
Linus Walleije206af62011-04-19 01:51:39 +02003981 PTPContainer ptp;
3982
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003983 PTP_CNT_INIT(ptp, PTP_OC_CHDK, PTP_CHDK_ScriptStatus);
3984 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL));
Linus Walleij9783ce32014-06-02 21:44:29 +02003985 *status = ptp.Param1;
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003986 return PTP_RC_OK;
Linus Walleije206af62011-04-19 01:51:39 +02003987}
Linus Walleij9783ce32014-06-02 21:44:29 +02003988uint16_t
3989ptp_chdk_get_script_support(PTPParams* params, unsigned *status)
Linus Walleije206af62011-04-19 01:51:39 +02003990{
Linus Walleij9783ce32014-06-02 21:44:29 +02003991 PTPContainer ptp;
Linus Walleije206af62011-04-19 01:51:39 +02003992
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003993 PTP_CNT_INIT(ptp, PTP_OC_CHDK, PTP_CHDK_ScriptSupport);
3994 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL));
Linus Walleij9783ce32014-06-02 21:44:29 +02003995 *status = ptp.Param1;
Marcus Meissner3d692dc2016-02-21 12:34:06 +01003996 return PTP_RC_OK;
Linus Walleije206af62011-04-19 01:51:39 +02003997}
Linus Walleije206af62011-04-19 01:51:39 +02003998
3999uint16_t
Linus Walleij9783ce32014-06-02 21:44:29 +02004000ptp_chdk_write_script_msg(PTPParams* params, char *data, unsigned size, int target_script_id, int *status)
Linus Walleije206af62011-04-19 01:51:39 +02004001{
Linus Walleije206af62011-04-19 01:51:39 +02004002 PTPContainer ptp;
Linus Walleij9783ce32014-06-02 21:44:29 +02004003
4004 // a zero length data phase appears to do bad things, camera stops responding to PTP
4005 if(!size) {
4006 ptp_error(params,"zero length message not allowed");
4007 *status = 0;
Marcus Meissner3d692dc2016-02-21 12:34:06 +01004008 return PTP_ERROR_BADPARAM;
Linus Walleij9783ce32014-06-02 21:44:29 +02004009 }
Marcus Meissner3d692dc2016-02-21 12:34:06 +01004010 PTP_CNT_INIT(ptp, PTP_OC_CHDK, PTP_CHDK_WriteScriptMsg, target_script_id);
4011 *status = 0;
4012 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, (unsigned char**)&data, NULL));
Linus Walleij9783ce32014-06-02 21:44:29 +02004013 *status = ptp.Param1;
Marcus Meissner3d692dc2016-02-21 12:34:06 +01004014 return PTP_RC_OK;
Linus Walleij9783ce32014-06-02 21:44:29 +02004015}
4016uint16_t
4017ptp_chdk_read_script_msg(PTPParams* params, ptp_chdk_script_msg **msg)
4018{
Marcus Meissner3d692dc2016-02-21 12:34:06 +01004019 PTPContainer ptp;
4020 unsigned char *data;
Linus Walleije206af62011-04-19 01:51:39 +02004021
Marcus Meissner3d692dc2016-02-21 12:34:06 +01004022 PTP_CNT_INIT(ptp, PTP_OC_CHDK, PTP_CHDK_ReadScriptMsg);
Linus Walleij9783ce32014-06-02 21:44:29 +02004023
4024 *msg = NULL;
4025
4026 /* camera will always send data, otherwise getdata will cause problems */
Marcus Meissner3d692dc2016-02-21 12:34:06 +01004027 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, NULL));
Marcus Meissneraa7d91a2017-03-16 15:59:48 +01004028 if (!data) {
4029 ptp_error(params,"no data received");
4030 return PTP_ERROR_BADPARAM;
4031 }
Linus Walleij9783ce32014-06-02 21:44:29 +02004032
4033 /* for convenience, always allocate an extra byte and null it*/
4034 *msg = malloc(sizeof(ptp_chdk_script_msg) + ptp.Param4 + 1);
4035 (*msg)->type = ptp.Param1;
4036 (*msg)->subtype = ptp.Param2;
4037 (*msg)->script_id = ptp.Param3;
4038 (*msg)->size = ptp.Param4;
4039 memcpy((*msg)->data,data,(*msg)->size);
4040 (*msg)->data[(*msg)->size] = 0;
4041 free(data);
Marcus Meissner3d692dc2016-02-21 12:34:06 +01004042 return PTP_RC_OK;
Linus Walleije206af62011-04-19 01:51:39 +02004043}
4044
Linus Walleij9783ce32014-06-02 21:44:29 +02004045uint16_t
Marcus Meissner3d692dc2016-02-21 12:34:06 +01004046ptp_chdk_get_live_data(PTPParams* params, unsigned flags, unsigned char **data, unsigned int *data_size)
4047{
Linus Walleij9783ce32014-06-02 21:44:29 +02004048 PTPContainer ptp;
Linus Walleij9783ce32014-06-02 21:44:29 +02004049
Marcus Meissner3d692dc2016-02-21 12:34:06 +01004050 PTP_CNT_INIT(ptp, PTP_OC_CHDK, PTP_CHDK_GetDisplayData, flags);
Linus Walleij9783ce32014-06-02 21:44:29 +02004051 *data_size = 0;
Marcus Meissner3d692dc2016-02-21 12:34:06 +01004052 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, data, NULL));
Linus Walleij9783ce32014-06-02 21:44:29 +02004053 *data_size = ptp.Param1;
Marcus Meissner3d692dc2016-02-21 12:34:06 +01004054 return PTP_RC_OK;
Linus Walleij9783ce32014-06-02 21:44:29 +02004055}
4056
4057uint16_t
4058ptp_chdk_call_function(PTPParams* params, int *args, int size, int *ret)
4059{
Linus Walleij9783ce32014-06-02 21:44:29 +02004060 PTPContainer ptp;
4061
Marcus Meissner3d692dc2016-02-21 12:34:06 +01004062 PTP_CNT_INIT(ptp, PTP_OC_CHDK, PTP_CHDK_CallFunction);
4063 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size*sizeof(int), (unsigned char **) &args, NULL));
4064 if (ret)
Linus Walleij9783ce32014-06-02 21:44:29 +02004065 *ret = ptp.Param1;
Marcus Meissner3d692dc2016-02-21 12:34:06 +01004066 return PTP_RC_OK;
Linus Walleij9783ce32014-06-02 21:44:29 +02004067}
4068
4069
4070
Linus Walleije206af62011-04-19 01:51:39 +02004071
Linus Walleija381e8a2013-03-05 21:00:06 +01004072/**
4073 * Android MTP Extensions
4074 */
4075
4076/**
4077 * ptp_android_getpartialobject64:
4078 * params: PTPParams*
4079 * handle - Object handle
4080 * offset - Offset into object
4081 * maxbytes - Maximum of bytes to read
4082 * object - pointer to data area
4083 * len - pointer to returned length
4084 *
4085 * Get object 'handle' from device and store the data in newly
4086 * allocated 'object'. Start from offset and read at most maxbytes.
4087 *
4088 * This is a 64bit offset version of the standard GetPartialObject.
4089 *
4090 * Return values: Some PTP_RC_* code.
4091 **/
4092uint16_t
4093ptp_android_getpartialobject64 (PTPParams* params, uint32_t handle, uint64_t offset,
4094 uint32_t maxbytes, unsigned char** object,
4095 uint32_t *len)
4096{
4097 PTPContainer ptp;
4098
Marcus Meissner56f937f2017-04-01 21:47:44 +02004099 /* casts due to varargs otherwise pushing 64bit values on the stack */
4100 PTP_CNT_INIT(ptp, PTP_OC_ANDROID_GetPartialObject64, handle, ((uint32_t)offset & 0xFFFFFFFF), (uint32_t)(offset >> 32), maxbytes);
Linus Walleija381e8a2013-03-05 21:00:06 +01004101 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, object, len);
4102}
4103
4104uint16_t
4105ptp_android_sendpartialobject (PTPParams* params, uint32_t handle, uint64_t offset,
4106 unsigned char* object, uint32_t len)
4107{
Marcus Meissner3d692dc2016-02-21 12:34:06 +01004108 PTPContainer ptp;
4109 uint16_t ret;
Linus Walleija381e8a2013-03-05 21:00:06 +01004110
Marcus Meissner121aac92017-04-01 22:10:50 +02004111 PTP_CNT_INIT(ptp, PTP_OC_ANDROID_SendPartialObject, handle, (uint32_t)(offset & 0xFFFFFFFF), (uint32_t)(offset >> 32), len);
Linus Walleija381e8a2013-03-05 21:00:06 +01004112
4113 /*
4114 * MtpServer.cpp is buggy: it uses write() without offset
4115 * rather than pwrite to send the data for data coming with
4116 * the header packet
4117 */
4118 params->split_header_data = 1;
Marcus Meissner3d692dc2016-02-21 12:34:06 +01004119 ret=ptp_transaction(params, &ptp, PTP_DP_SENDDATA, len, &object, NULL);
Linus Walleija381e8a2013-03-05 21:00:06 +01004120 params->split_header_data = 0;
4121
Marcus Meissner3d692dc2016-02-21 12:34:06 +01004122 return ret;
Linus Walleija381e8a2013-03-05 21:00:06 +01004123}
4124
Linus Walleije206af62011-04-19 01:51:39 +02004125
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00004126/* Non PTP protocol functions */
4127/* devinfo testing functions */
4128
4129int
Linus Walleijb02a0662006-04-25 08:05:09 +00004130ptp_event_issupported(PTPParams* params, uint16_t event)
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00004131{
Linus Walleij2ad5b722013-11-04 02:07:44 +01004132 unsigned int i=0;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00004133
Linus Walleijb02a0662006-04-25 08:05:09 +00004134 for (;i<params->deviceinfo.EventsSupported_len;i++) {
4135 if (params->deviceinfo.EventsSupported[i]==event)
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00004136 return 1;
4137 }
4138 return 0;
4139}
4140
Linus Walleijb02a0662006-04-25 08:05:09 +00004141
4142int
4143ptp_property_issupported(PTPParams* params, uint16_t property)
4144{
Linus Walleij2ad5b722013-11-04 02:07:44 +01004145 unsigned int i;
Linus Walleijb02a0662006-04-25 08:05:09 +00004146
Linus Walleijf0bf4372007-07-01 21:47:38 +00004147 for (i=0;i<params->deviceinfo.DevicePropertiesSupported_len;i++)
Linus Walleijb02a0662006-04-25 08:05:09 +00004148 if (params->deviceinfo.DevicePropertiesSupported[i]==property)
4149 return 1;
4150 return 0;
4151}
4152
Linus Walleijf0bf4372007-07-01 21:47:38 +00004153void
4154ptp_free_objectinfo (PTPObjectInfo *oi)
4155{
4156 if (!oi) return;
Linus Walleij5d533bb2007-07-17 21:48:57 +00004157 free (oi->Filename); oi->Filename = NULL;
4158 free (oi->Keywords); oi->Keywords = NULL;
Linus Walleijf0bf4372007-07-01 21:47:38 +00004159}
4160
Linus Walleijd4637502009-06-14 23:03:33 +00004161void
4162ptp_free_object (PTPObject *ob)
4163{
Linus Walleij2ad5b722013-11-04 02:07:44 +01004164 unsigned int i;
Linus Walleijd4637502009-06-14 23:03:33 +00004165 if (!ob) return;
4166
4167 ptp_free_objectinfo (&ob->oi);
4168 for (i=0;i<ob->nrofmtpprops;i++)
4169 ptp_destroy_object_prop(&ob->mtpprops[i]);
4170 ob->flags = 0;
4171}
4172
Marcus Meissner3d692dc2016-02-21 12:34:06 +01004173/* PTP error descriptions */
4174static struct {
4175 uint16_t rc;
4176 uint16_t vendor;
4177 const char *txt;
4178} ptp_errors[] = {
4179 {PTP_RC_Undefined, 0, N_("PTP Undefined Error")},
4180 {PTP_RC_OK, 0, N_("PTP OK!")},
4181 {PTP_RC_GeneralError, 0, N_("PTP General Error")},
4182 {PTP_RC_SessionNotOpen, 0, N_("PTP Session Not Open")},
4183 {PTP_RC_InvalidTransactionID, 0, N_("PTP Invalid Transaction ID")},
4184 {PTP_RC_OperationNotSupported, 0, N_("PTP Operation Not Supported")},
4185 {PTP_RC_ParameterNotSupported, 0, N_("PTP Parameter Not Supported")},
4186 {PTP_RC_IncompleteTransfer, 0, N_("PTP Incomplete Transfer")},
4187 {PTP_RC_InvalidStorageId, 0, N_("PTP Invalid Storage ID")},
4188 {PTP_RC_InvalidObjectHandle, 0, N_("PTP Invalid Object Handle")},
4189 {PTP_RC_DevicePropNotSupported, 0, N_("PTP Device Prop Not Supported")},
4190 {PTP_RC_InvalidObjectFormatCode,0, N_("PTP Invalid Object Format Code")},
4191 {PTP_RC_StoreFull, 0, N_("PTP Store Full")},
4192 {PTP_RC_ObjectWriteProtected, 0, N_("PTP Object Write Protected")},
4193 {PTP_RC_StoreReadOnly, 0, N_("PTP Store Read Only")},
4194 {PTP_RC_AccessDenied, 0, N_("PTP Access Denied")},
4195 {PTP_RC_NoThumbnailPresent, 0, N_("PTP No Thumbnail Present")},
4196 {PTP_RC_SelfTestFailed, 0, N_("PTP Self Test Failed")},
4197 {PTP_RC_PartialDeletion, 0, N_("PTP Partial Deletion")},
4198 {PTP_RC_StoreNotAvailable, 0, N_("PTP Store Not Available")},
4199 {PTP_RC_SpecificationByFormatUnsupported, 0, N_("PTP Specification By Format Unsupported")},
4200 {PTP_RC_NoValidObjectInfo, 0, N_("PTP No Valid Object Info")},
4201 {PTP_RC_InvalidCodeFormat, 0, N_("PTP Invalid Code Format")},
4202 {PTP_RC_UnknownVendorCode, 0, N_("PTP Unknown Vendor Code")},
4203 {PTP_RC_CaptureAlreadyTerminated, 0, N_("PTP Capture Already Terminated")},
4204 {PTP_RC_DeviceBusy, 0, N_("PTP Device Busy")},
4205 {PTP_RC_InvalidParentObject, 0, N_("PTP Invalid Parent Object")},
4206 {PTP_RC_InvalidDevicePropFormat,0, N_("PTP Invalid Device Prop Format")},
4207 {PTP_RC_InvalidDevicePropValue, 0, N_("PTP Invalid Device Prop Value")},
4208 {PTP_RC_InvalidParameter, 0, N_("PTP Invalid Parameter")},
4209 {PTP_RC_SessionAlreadyOpened, 0, N_("PTP Session Already Opened")},
4210 {PTP_RC_TransactionCanceled, 0, N_("PTP Transaction Canceled")},
4211 {PTP_RC_SpecificationOfDestinationUnsupported, 0, N_("PTP Specification Of Destination Unsupported")},
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00004212
Marcus Meissner3d692dc2016-02-21 12:34:06 +01004213 {PTP_RC_EK_FilenameRequired, PTP_VENDOR_EASTMAN_KODAK, N_("Filename Required")},
4214 {PTP_RC_EK_FilenameConflicts, PTP_VENDOR_EASTMAN_KODAK, N_("Filename Conflicts")},
4215 {PTP_RC_EK_FilenameInvalid, PTP_VENDOR_EASTMAN_KODAK, N_("Filename Invalid")},
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00004216
Marcus Meissner3d692dc2016-02-21 12:34:06 +01004217 {PTP_RC_NIKON_HardwareError, PTP_VENDOR_NIKON, N_("Hardware Error")},
4218 {PTP_RC_NIKON_OutOfFocus, PTP_VENDOR_NIKON, N_("Out of Focus")},
4219 {PTP_RC_NIKON_ChangeCameraModeFailed, PTP_VENDOR_NIKON, N_("Change Camera Mode Failed")},
4220 {PTP_RC_NIKON_InvalidStatus, PTP_VENDOR_NIKON, N_("Invalid Status")},
4221 {PTP_RC_NIKON_SetPropertyNotSupported, PTP_VENDOR_NIKON, N_("Set Property Not Supported")},
4222 {PTP_RC_NIKON_WbResetError, PTP_VENDOR_NIKON, N_("Whitebalance Reset Error")},
4223 {PTP_RC_NIKON_DustReferenceError, PTP_VENDOR_NIKON, N_("Dust Reference Error")},
4224 {PTP_RC_NIKON_ShutterSpeedBulb, PTP_VENDOR_NIKON, N_("Shutter Speed Bulb")},
4225 {PTP_RC_NIKON_MirrorUpSequence, PTP_VENDOR_NIKON, N_("Mirror Up Sequence")},
4226 {PTP_RC_NIKON_CameraModeNotAdjustFNumber, PTP_VENDOR_NIKON, N_("Camera Mode Not Adjust FNumber")},
4227 {PTP_RC_NIKON_NotLiveView, PTP_VENDOR_NIKON, N_("Not in Liveview")},
4228 {PTP_RC_NIKON_MfDriveStepEnd, PTP_VENDOR_NIKON, N_("Mf Drive Step End")},
4229 {PTP_RC_NIKON_MfDriveStepInsufficiency, PTP_VENDOR_NIKON, N_("Mf Drive Step Insufficiency")},
4230 {PTP_RC_NIKON_AdvancedTransferCancel, PTP_VENDOR_NIKON, N_("Advanced Transfer Cancel")},
4231
4232 {PTP_RC_CANON_UNKNOWN_COMMAND, PTP_VENDOR_CANON, N_("Unknown Command")},
4233 {PTP_RC_CANON_OPERATION_REFUSED,PTP_VENDOR_CANON, N_("Operation Refused")},
4234 {PTP_RC_CANON_LENS_COVER, PTP_VENDOR_CANON, N_("Lens Cover Present")},
4235 {PTP_RC_CANON_BATTERY_LOW, PTP_VENDOR_CANON, N_("Battery Low")},
4236 {PTP_RC_CANON_NOT_READY, PTP_VENDOR_CANON, N_("Camera Not Ready")},
4237
4238 {PTP_ERROR_TIMEOUT, 0, N_("PTP Timeout")},
4239 {PTP_ERROR_CANCEL, 0, N_("PTP Cancel Request")},
4240 {PTP_ERROR_BADPARAM, 0, N_("PTP Invalid Parameter")},
4241 {PTP_ERROR_RESP_EXPECTED, 0, N_("PTP Response Expected")},
4242 {PTP_ERROR_DATA_EXPECTED, 0, N_("PTP Data Expected")},
4243 {PTP_ERROR_IO, 0, N_("PTP I/O Error")},
4244 {0, 0, NULL}
Linus Walleijb02a0662006-04-25 08:05:09 +00004245};
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00004246
Marcus Meissner3d692dc2016-02-21 12:34:06 +01004247const char *
4248ptp_strerror(uint16_t ret, uint16_t vendor)
4249{
4250 int i;
4251
4252 for (i=0; ptp_errors[i].txt != NULL; i++)
4253 if ((ptp_errors[i].rc == ret) && ((ptp_errors[i].vendor == 0) || (ptp_errors[i].vendor == vendor)))
Linus Walleij3a1a82c2012-07-03 19:36:28 +02004254 return ptp_errors[i].txt;
4255 return NULL;
4256}
4257
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00004258const char*
Linus Walleijb02a0662006-04-25 08:05:09 +00004259ptp_get_property_description(PTPParams* params, uint16_t dpc)
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00004260{
4261 int i;
Linus Walleija823a702006-08-27 21:27:46 +00004262 /* Device Property descriptions */
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00004263 struct {
4264 uint16_t dpc;
4265 const char *txt;
4266 } ptp_device_properties[] = {
Linus Walleijb02a0662006-04-25 08:05:09 +00004267 {PTP_DPC_Undefined, N_("Undefined PTP Property")},
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00004268 {PTP_DPC_BatteryLevel, N_("Battery Level")},
4269 {PTP_DPC_FunctionalMode, N_("Functional Mode")},
4270 {PTP_DPC_ImageSize, N_("Image Size")},
4271 {PTP_DPC_CompressionSetting, N_("Compression Setting")},
4272 {PTP_DPC_WhiteBalance, N_("White Balance")},
4273 {PTP_DPC_RGBGain, N_("RGB Gain")},
4274 {PTP_DPC_FNumber, N_("F-Number")},
4275 {PTP_DPC_FocalLength, N_("Focal Length")},
4276 {PTP_DPC_FocusDistance, N_("Focus Distance")},
4277 {PTP_DPC_FocusMode, N_("Focus Mode")},
4278 {PTP_DPC_ExposureMeteringMode, N_("Exposure Metering Mode")},
4279 {PTP_DPC_FlashMode, N_("Flash Mode")},
4280 {PTP_DPC_ExposureTime, N_("Exposure Time")},
4281 {PTP_DPC_ExposureProgramMode, N_("Exposure Program Mode")},
4282 {PTP_DPC_ExposureIndex,
4283 N_("Exposure Index (film speed ISO)")},
4284 {PTP_DPC_ExposureBiasCompensation,
4285 N_("Exposure Bias Compensation")},
Linus Walleij53c5f4e2007-08-13 08:27:58 +00004286 {PTP_DPC_DateTime, N_("Date & Time")},
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00004287 {PTP_DPC_CaptureDelay, N_("Pre-Capture Delay")},
4288 {PTP_DPC_StillCaptureMode, N_("Still Capture Mode")},
4289 {PTP_DPC_Contrast, N_("Contrast")},
4290 {PTP_DPC_Sharpness, N_("Sharpness")},
4291 {PTP_DPC_DigitalZoom, N_("Digital Zoom")},
4292 {PTP_DPC_EffectMode, N_("Effect Mode")},
4293 {PTP_DPC_BurstNumber, N_("Burst Number")},
4294 {PTP_DPC_BurstInterval, N_("Burst Interval")},
4295 {PTP_DPC_TimelapseNumber, N_("Timelapse Number")},
4296 {PTP_DPC_TimelapseInterval, N_("Timelapse Interval")},
4297 {PTP_DPC_FocusMeteringMode, N_("Focus Metering Mode")},
4298 {PTP_DPC_UploadURL, N_("Upload URL")},
4299 {PTP_DPC_Artist, N_("Artist")},
4300 {PTP_DPC_CopyrightInfo, N_("Copyright Info")},
Marcus Meissner3d692dc2016-02-21 12:34:06 +01004301 {PTP_DPC_SupportedStreams, N_("Supported Streams")},
4302 {PTP_DPC_EnabledStreams, N_("Enabled Streams")},
4303 {PTP_DPC_VideoFormat, N_("Video Format")},
4304 {PTP_DPC_VideoResolution, N_("Video Resolution")},
4305 {PTP_DPC_VideoQuality, N_("Video Quality")},
4306 {PTP_DPC_VideoFrameRate, N_("Video Framerate")},
4307 {PTP_DPC_VideoContrast, N_("Video Contrast")},
4308 {PTP_DPC_VideoBrightness, N_("Video Brightness")},
4309 {PTP_DPC_AudioFormat, N_("Audio Format")},
4310 {PTP_DPC_AudioBitrate, N_("Audio Bitrate")},
4311 {PTP_DPC_AudioSamplingRate, N_("Audio Samplingrate")},
4312 {PTP_DPC_AudioBitPerSample, N_("Audio Bits per sample")},
4313 {PTP_DPC_AudioVolume, N_("Audio Volume")},
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00004314 {0,NULL}
4315 };
4316 struct {
4317 uint16_t dpc;
4318 const char *txt;
4319 } ptp_device_properties_EK[] = {
Linus Walleijb02a0662006-04-25 08:05:09 +00004320 {PTP_DPC_EK_ColorTemperature, N_("Color Temperature")},
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00004321 {PTP_DPC_EK_DateTimeStampFormat,
Linus Walleijb02a0662006-04-25 08:05:09 +00004322 N_("Date Time Stamp Format")},
4323 {PTP_DPC_EK_BeepMode, N_("Beep Mode")},
4324 {PTP_DPC_EK_VideoOut, N_("Video Out")},
4325 {PTP_DPC_EK_PowerSaving, N_("Power Saving")},
4326 {PTP_DPC_EK_UI_Language, N_("UI Language")},
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00004327 {0,NULL}
4328 };
4329
4330 struct {
4331 uint16_t dpc;
4332 const char *txt;
Linus Walleijb02a0662006-04-25 08:05:09 +00004333 } ptp_device_properties_Canon[] = {
4334 {PTP_DPC_CANON_BeepMode, N_("Beep Mode")},
Linus Walleij53c5f4e2007-08-13 08:27:58 +00004335 {PTP_DPC_CANON_BatteryKind, N_("Battery Type")},
Linus Walleijf0bf4372007-07-01 21:47:38 +00004336 {PTP_DPC_CANON_BatteryStatus, N_("Battery Mode")},
4337 {PTP_DPC_CANON_UILockType, N_("UILockType")},
4338 {PTP_DPC_CANON_CameraMode, N_("Camera Mode")},
Linus Walleijb02a0662006-04-25 08:05:09 +00004339 {PTP_DPC_CANON_ImageQuality, N_("Image Quality")},
Linus Walleijf0bf4372007-07-01 21:47:38 +00004340 {PTP_DPC_CANON_FullViewFileFormat, N_("Full View File Format")},
Linus Walleijb02a0662006-04-25 08:05:09 +00004341 {PTP_DPC_CANON_ImageSize, N_("Image Size")},
Linus Walleijf0bf4372007-07-01 21:47:38 +00004342 {PTP_DPC_CANON_SelfTime, N_("Self Time")},
Linus Walleijb02a0662006-04-25 08:05:09 +00004343 {PTP_DPC_CANON_FlashMode, N_("Flash Mode")},
Linus Walleijf0bf4372007-07-01 21:47:38 +00004344 {PTP_DPC_CANON_Beep, N_("Beep")},
Linus Walleijb02a0662006-04-25 08:05:09 +00004345 {PTP_DPC_CANON_ShootingMode, N_("Shooting Mode")},
Linus Walleijf0bf4372007-07-01 21:47:38 +00004346 {PTP_DPC_CANON_ImageMode, N_("Image Mode")},
4347 {PTP_DPC_CANON_DriveMode, N_("Drive Mode")},
4348 {PTP_DPC_CANON_EZoom, N_("Zoom")},
Linus Walleijb02a0662006-04-25 08:05:09 +00004349 {PTP_DPC_CANON_MeteringMode, N_("Metering Mode")},
4350 {PTP_DPC_CANON_AFDistance, N_("AF Distance")},
4351 {PTP_DPC_CANON_FocusingPoint, N_("Focusing Point")},
4352 {PTP_DPC_CANON_WhiteBalance, N_("White Balance")},
Linus Walleijf0bf4372007-07-01 21:47:38 +00004353 {PTP_DPC_CANON_SlowShutterSetting, N_("Slow Shutter Setting")},
4354 {PTP_DPC_CANON_AFMode, N_("AF Mode")},
4355 {PTP_DPC_CANON_ImageStabilization, N_("Image Stabilization")},
4356 {PTP_DPC_CANON_Contrast, N_("Contrast")},
4357 {PTP_DPC_CANON_ColorGain, N_("Color Gain")},
4358 {PTP_DPC_CANON_Sharpness, N_("Sharpness")},
4359 {PTP_DPC_CANON_Sensitivity, N_("Sensitivity")},
4360 {PTP_DPC_CANON_ParameterSet, N_("Parameter Set")},
Linus Walleijb02a0662006-04-25 08:05:09 +00004361 {PTP_DPC_CANON_ISOSpeed, N_("ISO Speed")},
4362 {PTP_DPC_CANON_Aperture, N_("Aperture")},
Linus Walleij53c5f4e2007-08-13 08:27:58 +00004363 {PTP_DPC_CANON_ShutterSpeed, N_("Shutter Speed")},
Linus Walleijb02a0662006-04-25 08:05:09 +00004364 {PTP_DPC_CANON_ExpCompensation, N_("Exposure Compensation")},
Linus Walleijf0bf4372007-07-01 21:47:38 +00004365 {PTP_DPC_CANON_FlashCompensation, N_("Flash Compensation")},
4366 {PTP_DPC_CANON_AEBExposureCompensation, N_("AEB Exposure Compensation")},
4367 {PTP_DPC_CANON_AvOpen, N_("Av Open")},
4368 {PTP_DPC_CANON_AvMax, N_("Av Max")},
4369 {PTP_DPC_CANON_FocalLength, N_("Focal Length")},
4370 {PTP_DPC_CANON_FocalLengthTele, N_("Focal Length Tele")},
4371 {PTP_DPC_CANON_FocalLengthWide, N_("Focal Length Wide")},
4372 {PTP_DPC_CANON_FocalLengthDenominator, N_("Focal Length Denominator")},
4373 {PTP_DPC_CANON_CaptureTransferMode, N_("Capture Transfer Mode")},
Linus Walleijb02a0662006-04-25 08:05:09 +00004374 {PTP_DPC_CANON_Zoom, N_("Zoom")},
Linus Walleijf0bf4372007-07-01 21:47:38 +00004375 {PTP_DPC_CANON_NamePrefix, N_("Name Prefix")},
Linus Walleijb02a0662006-04-25 08:05:09 +00004376 {PTP_DPC_CANON_SizeQualityMode, N_("Size Quality Mode")},
Linus Walleijf0bf4372007-07-01 21:47:38 +00004377 {PTP_DPC_CANON_SupportedThumbSize, N_("Supported Thumb Size")},
4378 {PTP_DPC_CANON_SizeOfOutputDataFromCamera, N_("Size of Output Data from Camera")},
4379 {PTP_DPC_CANON_SizeOfInputDataToCamera, N_("Size of Input Data to Camera")},
4380 {PTP_DPC_CANON_RemoteAPIVersion,N_("Remote API Version")},
Linus Walleijb02a0662006-04-25 08:05:09 +00004381 {PTP_DPC_CANON_FirmwareVersion, N_("Firmware Version")},
4382 {PTP_DPC_CANON_CameraModel, N_("Camera Model")},
4383 {PTP_DPC_CANON_CameraOwner, N_("Camera Owner")},
4384 {PTP_DPC_CANON_UnixTime, N_("UNIX Time")},
Linus Walleijf0bf4372007-07-01 21:47:38 +00004385 {PTP_DPC_CANON_CameraBodyID, N_("Camera Body ID")},
4386 {PTP_DPC_CANON_CameraOutput, N_("Camera Output")},
4387 {PTP_DPC_CANON_DispAv, N_("Disp Av")},
4388 {PTP_DPC_CANON_AvOpenApex, N_("Av Open Apex")},
Linus Walleijb02a0662006-04-25 08:05:09 +00004389 {PTP_DPC_CANON_DZoomMagnification, N_("Digital Zoom Magnification")},
Linus Walleijf0bf4372007-07-01 21:47:38 +00004390 {PTP_DPC_CANON_MlSpotPos, N_("Ml Spot Position")},
4391 {PTP_DPC_CANON_DispAvMax, N_("Disp Av Max")},
4392 {PTP_DPC_CANON_AvMaxApex, N_("Av Max Apex")},
4393 {PTP_DPC_CANON_EZoomStartPosition, N_("EZoom Start Position")},
Linus Walleij53c5f4e2007-08-13 08:27:58 +00004394 {PTP_DPC_CANON_FocalLengthOfTele, N_("Focal Length Tele")},
Linus Walleijf0bf4372007-07-01 21:47:38 +00004395 {PTP_DPC_CANON_EZoomSizeOfTele, N_("EZoom Size of Tele")},
Linus Walleijb02a0662006-04-25 08:05:09 +00004396 {PTP_DPC_CANON_PhotoEffect, N_("Photo Effect")},
4397 {PTP_DPC_CANON_AssistLight, N_("Assist Light")},
Linus Walleij2f622812008-08-30 22:06:58 +00004398 {PTP_DPC_CANON_FlashQuantityCount, N_("Flash Quantity Count")},
Linus Walleijf0bf4372007-07-01 21:47:38 +00004399 {PTP_DPC_CANON_RotationAngle, N_("Rotation Angle")},
4400 {PTP_DPC_CANON_RotationScene, N_("Rotation Scene")},
4401 {PTP_DPC_CANON_EventEmulateMode,N_("Event Emulate Mode")},
4402 {PTP_DPC_CANON_DPOFVersion, N_("DPOF Version")},
4403 {PTP_DPC_CANON_TypeOfSupportedSlideShow, N_("Type of Slideshow")},
4404 {PTP_DPC_CANON_AverageFilesizes,N_("Average Filesizes")},
4405 {PTP_DPC_CANON_ModelID, N_("Model ID")},
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00004406 {0,NULL}
4407 };
Linus Walleijb02a0662006-04-25 08:05:09 +00004408
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00004409 struct {
4410 uint16_t dpc;
4411 const char *txt;
Linus Walleijb02a0662006-04-25 08:05:09 +00004412 } ptp_device_properties_Nikon[] = {
Linus Walleijd1e14e02008-12-14 01:07:30 +00004413 {PTP_DPC_NIKON_ShootingBank, /* 0xD010 */
4414 N_("Shooting Bank")},
4415 {PTP_DPC_NIKON_ShootingBankNameA, /* 0xD011 */
4416 N_("Shooting Bank Name A")},
4417 {PTP_DPC_NIKON_ShootingBankNameB, /* 0xD012 */
4418 N_("Shooting Bank Name B")},
4419 {PTP_DPC_NIKON_ShootingBankNameC, /* 0xD013 */
4420 N_("Shooting Bank Name C")},
4421 {PTP_DPC_NIKON_ShootingBankNameD, /* 0xD014 */
4422 N_("Shooting Bank Name D")},
Linus Walleij1a0c3012009-07-23 23:06:58 +00004423 {PTP_DPC_NIKON_ResetBank0, /* 0xD015 */
4424 N_("Reset Bank 0")},
Linus Walleijd1e14e02008-12-14 01:07:30 +00004425 {PTP_DPC_NIKON_RawCompression, /* 0xD016 */
4426 N_("Raw Compression")},
Linus Walleijb02a0662006-04-25 08:05:09 +00004427 {PTP_DPC_NIKON_WhiteBalanceAutoBias, /* 0xD017 */
4428 N_("Auto White Balance Bias")},
4429 {PTP_DPC_NIKON_WhiteBalanceTungstenBias, /* 0xD018 */
4430 N_("Tungsten White Balance Bias")},
Linus Walleij4f40d112006-09-21 07:44:53 +00004431 {PTP_DPC_NIKON_WhiteBalanceFluorescentBias, /* 0xD019 */
4432 N_("Fluorescent White Balance Bias")},
Linus Walleijb02a0662006-04-25 08:05:09 +00004433 {PTP_DPC_NIKON_WhiteBalanceDaylightBias, /* 0xD01a */
4434 N_("Daylight White Balance Bias")},
4435 {PTP_DPC_NIKON_WhiteBalanceFlashBias, /* 0xD01b */
4436 N_("Flash White Balance Bias")},
4437 {PTP_DPC_NIKON_WhiteBalanceCloudyBias, /* 0xD01c */
4438 N_("Cloudy White Balance Bias")},
4439 {PTP_DPC_NIKON_WhiteBalanceShadeBias, /* 0xD01d */
4440 N_("Shady White Balance Bias")},
4441 {PTP_DPC_NIKON_WhiteBalanceColorTemperature, /* 0xD01e */
4442 N_("White Balance Colour Temperature")},
Linus Walleij7e3b3072009-01-19 22:51:17 +00004443 {PTP_DPC_NIKON_WhiteBalancePresetNo, /* 0xD01f */
4444 N_("White Balance Preset Number")},
Linus Walleij1a0c3012009-07-23 23:06:58 +00004445 {PTP_DPC_NIKON_WhiteBalancePresetName0, /* 0xD020 */
4446 N_("White Balance Preset Name 0")},
4447 {PTP_DPC_NIKON_WhiteBalancePresetName1, /* 0xD021 */
4448 N_("White Balance Preset Name 1")},
4449 {PTP_DPC_NIKON_WhiteBalancePresetName2, /* 0xD022 */
4450 N_("White Balance Preset Name 2")},
4451 {PTP_DPC_NIKON_WhiteBalancePresetName3, /* 0xD023 */
4452 N_("White Balance Preset Name 3")},
4453 {PTP_DPC_NIKON_WhiteBalancePresetName4, /* 0xD024 */
4454 N_("White Balance Preset Name 4")},
Linus Walleij7e3b3072009-01-19 22:51:17 +00004455 {PTP_DPC_NIKON_WhiteBalancePresetVal0, /* 0xD025 */
4456 N_("White Balance Preset Value 0")},
4457 {PTP_DPC_NIKON_WhiteBalancePresetVal1, /* 0xD026 */
4458 N_("White Balance Preset Value 1")},
4459 {PTP_DPC_NIKON_WhiteBalancePresetVal2, /* 0xD027 */
4460 N_("White Balance Preset Value 2")},
4461 {PTP_DPC_NIKON_WhiteBalancePresetVal3, /* 0xD028 */
4462 N_("White Balance Preset Value 3")},
4463 {PTP_DPC_NIKON_WhiteBalancePresetVal4, /* 0xD029 */
4464 N_("White Balance Preset Value 4")},
Linus Walleijb02a0662006-04-25 08:05:09 +00004465 {PTP_DPC_NIKON_ImageSharpening, /* 0xD02a */
4466 N_("Sharpening")},
4467 {PTP_DPC_NIKON_ToneCompensation, /* 0xD02b */
4468 N_("Tone Compensation")},
4469 {PTP_DPC_NIKON_ColorModel, /* 0xD02c */
4470 N_("Color Model")},
4471 {PTP_DPC_NIKON_HueAdjustment, /* 0xD02d */
4472 N_("Hue Adjustment")},
4473 {PTP_DPC_NIKON_NonCPULensDataFocalLength, /* 0xD02e */
4474 N_("Lens Focal Length (Non CPU)")},
4475 {PTP_DPC_NIKON_NonCPULensDataMaximumAperture, /* 0xD02f */
Linus Walleij1a0c3012009-07-23 23:06:58 +00004476 N_("Lens Maximum Aperture (Non CPU)")},
4477 {PTP_DPC_NIKON_ShootingMode, /* 0xD030 */
4478 N_("Shooting Mode")},
4479 {PTP_DPC_NIKON_JPEG_Compression_Policy, /* 0xD031 */
4480 N_("JPEG Compression Policy")},
4481 {PTP_DPC_NIKON_ColorSpace, /* 0xD032 */
4482 N_("Color Space")},
4483 {PTP_DPC_NIKON_AutoDXCrop, /* 0xD033 */
4484 N_("Auto DX Crop")},
Linus Walleijb7c1a672013-03-05 09:08:44 +01004485 {PTP_DPC_NIKON_FlickerReduction, /* 0xD034 */
4486 N_("Flicker Reduction")},
4487 {PTP_DPC_NIKON_RemoteMode, /* 0xD035 */
4488 N_("Remote Mode")},
4489 {PTP_DPC_NIKON_VideoMode, /* 0xD036 */
4490 N_("Video Mode")},
4491 {PTP_DPC_NIKON_EffectMode, /* 0xD037 */
4492 N_("Effect Mode")},
Linus Walleijb02a0662006-04-25 08:05:09 +00004493 {PTP_DPC_NIKON_CSMMenuBankSelect, /* 0xD040 */
4494 "PTP_DPC_NIKON_CSMMenuBankSelect"},
4495 {PTP_DPC_NIKON_MenuBankNameA, /* 0xD041 */
Linus Walleij7e3b3072009-01-19 22:51:17 +00004496 N_("Menu Bank Name A")},
Linus Walleijb02a0662006-04-25 08:05:09 +00004497 {PTP_DPC_NIKON_MenuBankNameB, /* 0xD042 */
Linus Walleij7e3b3072009-01-19 22:51:17 +00004498 N_("Menu Bank Name B")},
Linus Walleijb02a0662006-04-25 08:05:09 +00004499 {PTP_DPC_NIKON_MenuBankNameC, /* 0xD043 */
Linus Walleij7e3b3072009-01-19 22:51:17 +00004500 N_("Menu Bank Name C")},
Linus Walleijb02a0662006-04-25 08:05:09 +00004501 {PTP_DPC_NIKON_MenuBankNameD, /* 0xD044 */
Linus Walleij7e3b3072009-01-19 22:51:17 +00004502 N_("Menu Bank Name D")},
4503 {PTP_DPC_NIKON_ResetBank, /* 0xD045 */
4504 N_("Reset Menu Bank")},
Linus Walleijb02a0662006-04-25 08:05:09 +00004505 {PTP_DPC_NIKON_A1AFCModePriority, /* 0xD048 */
4506 "PTP_DPC_NIKON_A1AFCModePriority"},
4507 {PTP_DPC_NIKON_A2AFSModePriority, /* 0xD049 */
4508 "PTP_DPC_NIKON_A2AFSModePriority"},
4509 {PTP_DPC_NIKON_A3GroupDynamicAF, /* 0xD04a */
4510 "PTP_DPC_NIKON_A3GroupDynamicAF"},
4511 {PTP_DPC_NIKON_A4AFActivation, /* 0xD04b */
4512 "PTP_DPC_NIKON_A4AFActivation"},
Linus Walleij1a0c3012009-07-23 23:06:58 +00004513 {PTP_DPC_NIKON_FocusAreaIllumManualFocus, /* 0xD04c */
4514 "PTP_DPC_NIKON_FocusAreaIllumManualFocus"},
Linus Walleijb02a0662006-04-25 08:05:09 +00004515 {PTP_DPC_NIKON_FocusAreaIllumContinuous, /* 0xD04d */
4516 "PTP_DPC_NIKON_FocusAreaIllumContinuous"},
4517 {PTP_DPC_NIKON_FocusAreaIllumWhenSelected, /* 0xD04e */
4518 "PTP_DPC_NIKON_FocusAreaIllumWhenSelected"},
4519 {PTP_DPC_NIKON_FocusAreaWrap, /* 0xD04f */
4520 N_("Focus Area Wrap")},
Linus Walleij1a0c3012009-07-23 23:06:58 +00004521 {PTP_DPC_NIKON_VerticalAFON, /* 0xD050 */
Linus Walleijb02a0662006-04-25 08:05:09 +00004522 N_("Vertical AF On")},
Linus Walleij1a0c3012009-07-23 23:06:58 +00004523 {PTP_DPC_NIKON_AFLockOn, /* 0xD051 */
4524 N_("AF Lock On")},
4525 {PTP_DPC_NIKON_FocusAreaZone, /* 0xD052 */
4526 N_("Focus Area Zone")},
4527 {PTP_DPC_NIKON_EnableCopyright, /* 0xD053 */
4528 N_("Enable Copyright")},
Linus Walleijb02a0662006-04-25 08:05:09 +00004529 {PTP_DPC_NIKON_ISOAuto, /* 0xD054 */
4530 N_("Auto ISO")},
Linus Walleij1a0c3012009-07-23 23:06:58 +00004531 {PTP_DPC_NIKON_EVISOStep, /* 0xD055 */
4532 N_("Exposure ISO Step")},
Linus Walleijb02a0662006-04-25 08:05:09 +00004533 {PTP_DPC_NIKON_EVStep, /* 0xD056 */
4534 N_("Exposure Step")},
Linus Walleij1a0c3012009-07-23 23:06:58 +00004535 {PTP_DPC_NIKON_EVStepExposureComp, /* 0xD057 */
Linus Walleijb02a0662006-04-25 08:05:09 +00004536 N_("Exposure Compensation (EV)")},
4537 {PTP_DPC_NIKON_ExposureCompensation, /* 0xD058 */
4538 N_("Exposure Compensation")},
4539 {PTP_DPC_NIKON_CenterWeightArea, /* 0xD059 */
4540 N_("Centre Weight Area")},
Linus Walleij1a0c3012009-07-23 23:06:58 +00004541 {PTP_DPC_NIKON_ExposureBaseMatrix, /* 0xD05A */
4542 N_("Exposure Base Matrix")},
4543 {PTP_DPC_NIKON_ExposureBaseCenter, /* 0xD05B */
4544 N_("Exposure Base Center")},
4545 {PTP_DPC_NIKON_ExposureBaseSpot, /* 0xD05C */
4546 N_("Exposure Base Spot")},
Linus Walleijd6f25ba2011-11-14 23:00:52 +01004547 {PTP_DPC_NIKON_LiveViewAFArea, /* 0xD05D */
4548 N_("Live View AF Area")},
Linus Walleij1a0c3012009-07-23 23:06:58 +00004549 {PTP_DPC_NIKON_AELockMode, /* 0xD05E */
Linus Walleijb02a0662006-04-25 08:05:09 +00004550 N_("Exposure Lock")},
Linus Walleij1a0c3012009-07-23 23:06:58 +00004551 {PTP_DPC_NIKON_AELAFLMode, /* 0xD05F */
Linus Walleijb02a0662006-04-25 08:05:09 +00004552 N_("Focus Lock")},
Linus Walleijd6f25ba2011-11-14 23:00:52 +01004553 {PTP_DPC_NIKON_LiveViewAFFocus, /* 0xD061 */
4554 N_("Live View AF Focus")},
Linus Walleijb02a0662006-04-25 08:05:09 +00004555 {PTP_DPC_NIKON_MeterOff, /* 0xD062 */
4556 N_("Auto Meter Off Time")},
4557 {PTP_DPC_NIKON_SelfTimer, /* 0xD063 */
4558 N_("Self Timer Delay")},
4559 {PTP_DPC_NIKON_MonitorOff, /* 0xD064 */
4560 N_("LCD Off Time")},
Linus Walleij1a0c3012009-07-23 23:06:58 +00004561 {PTP_DPC_NIKON_ImgConfTime, /* 0xD065 */
4562 N_("Img Conf Time")},
Linus Walleij3a1a82c2012-07-03 19:36:28 +02004563 {PTP_DPC_NIKON_AutoOffTimers, /* 0xD066 */
4564 N_("Auto Off Timers")},
Linus Walleij1a0c3012009-07-23 23:06:58 +00004565 {PTP_DPC_NIKON_AngleLevel, /* 0xD067 */
4566 N_("Angle Level")},
Linus Walleijb02a0662006-04-25 08:05:09 +00004567 {PTP_DPC_NIKON_D1ShootingSpeed, /* 0xD068 */
4568 N_("Shooting Speed")},
4569 {PTP_DPC_NIKON_D2MaximumShots, /* 0xD069 */
Linus Walleij53c5f4e2007-08-13 08:27:58 +00004570 N_("Maximum Shots")},
Linus Walleij0d762cc2010-04-04 23:34:27 +00004571 {PTP_DPC_NIKON_ExposureDelayMode, /* 0xD06A */
Linus Walleij1a0c3012009-07-23 23:06:58 +00004572 N_("Exposure delay mode")},
4573 {PTP_DPC_NIKON_LongExposureNoiseReduction, /* 0xD06B */
Linus Walleijb02a0662006-04-25 08:05:09 +00004574 N_("Long Exposure Noise Reduction")},
Linus Walleij1a0c3012009-07-23 23:06:58 +00004575 {PTP_DPC_NIKON_FileNumberSequence, /* 0xD06C */
Linus Walleijb02a0662006-04-25 08:05:09 +00004576 N_("File Number Sequencing")},
Linus Walleij1a0c3012009-07-23 23:06:58 +00004577 {PTP_DPC_NIKON_ControlPanelFinderRearControl, /* 0xD06D */
4578 "PTP_DPC_NIKON_ControlPanelFinderRearControl"},
4579 {PTP_DPC_NIKON_ControlPanelFinderViewfinder, /* 0xD06E */
Linus Walleijd208f9c2006-04-27 14:16:06 +00004580 "PTP_DPC_NIKON_ControlPanelFinderViewfinder"},
Linus Walleij1a0c3012009-07-23 23:06:58 +00004581 {PTP_DPC_NIKON_D7Illumination, /* 0xD06F */
4582 N_("LCD Illumination")},
4583 {PTP_DPC_NIKON_NrHighISO, /* 0xD070 */
4584 N_("High ISO noise reduction")},
4585 {PTP_DPC_NIKON_SHSET_CH_GUID_DISP, /* 0xD071 */
4586 N_("On screen tips")},
4587 {PTP_DPC_NIKON_ArtistName, /* 0xD072 */
4588 N_("Artist Name")},
4589 {PTP_DPC_NIKON_CopyrightInfo, /* 0xD073 */
4590 N_("Copyright Information")},
4591 {PTP_DPC_NIKON_FlashSyncSpeed, /* 0xD074 */
Linus Walleijb02a0662006-04-25 08:05:09 +00004592 N_("Flash Sync. Speed")},
4593 {PTP_DPC_NIKON_FlashShutterSpeed, /* 0xD075 */
4594 N_("Flash Shutter Speed")},
4595 {PTP_DPC_NIKON_E3AAFlashMode, /* 0xD076 */
4596 N_("Flash Mode")},
4597 {PTP_DPC_NIKON_E4ModelingFlash, /* 0xD077 */
4598 N_("Modeling Flash")},
4599 {PTP_DPC_NIKON_BracketSet, /* 0xD078 */
4600 N_("Bracket Set")},
4601 {PTP_DPC_NIKON_E6ManualModeBracketing, /* 0xD079 */
4602 N_("Manual Mode Bracketing")},
Linus Walleij1a0c3012009-07-23 23:06:58 +00004603 {PTP_DPC_NIKON_BracketOrder, /* 0xD07A */
Linus Walleijb02a0662006-04-25 08:05:09 +00004604 N_("Bracket Order")},
Linus Walleij1a0c3012009-07-23 23:06:58 +00004605 {PTP_DPC_NIKON_E8AutoBracketSelection, /* 0xD07B */
Linus Walleijb02a0662006-04-25 08:05:09 +00004606 N_("Auto Bracket Selection")},
Linus Walleijd1e14e02008-12-14 01:07:30 +00004607 {PTP_DPC_NIKON_BracketingSet, N_("NIKON Auto Bracketing Set")}, /* 0xD07C */
Linus Walleijb02a0662006-04-25 08:05:09 +00004608 {PTP_DPC_NIKON_F1CenterButtonShootingMode, /* 0xD080 */
4609 N_("Center Button Shooting Mode")},
4610 {PTP_DPC_NIKON_CenterButtonPlaybackMode, /* 0xD081 */
4611 N_("Center Button Playback Mode")},
4612 {PTP_DPC_NIKON_F2Multiselector, /* 0xD082 */
4613 N_("Multiselector")},
4614 {PTP_DPC_NIKON_F3PhotoInfoPlayback, /* 0xD083 */
4615 N_("Photo Info. Playback")},
4616 {PTP_DPC_NIKON_F4AssignFuncButton, /* 0xD084 */
4617 N_("Assign Func. Button")},
4618 {PTP_DPC_NIKON_F5CustomizeCommDials, /* 0xD085 */
4619 N_("Customise Command Dials")},
4620 {PTP_DPC_NIKON_ReverseCommandDial, /* 0xD086 */
4621 N_("Reverse Command Dial")},
4622 {PTP_DPC_NIKON_ApertureSetting, /* 0xD087 */
4623 N_("Aperture Setting")},
4624 {PTP_DPC_NIKON_MenusAndPlayback, /* 0xD088 */
4625 N_("Menus and Playback")},
4626 {PTP_DPC_NIKON_F6ButtonsAndDials, /* 0xD089 */
4627 N_("Buttons and Dials")},
Linus Walleij1a0c3012009-07-23 23:06:58 +00004628 {PTP_DPC_NIKON_NoCFCard, /* 0xD08A */
Linus Walleijb02a0662006-04-25 08:05:09 +00004629 N_("No CF Card Release")},
Linus Walleij1a0c3012009-07-23 23:06:58 +00004630 {PTP_DPC_NIKON_CenterButtonZoomRatio, /* 0xD08B */
4631 N_("Center Button Zoom Ratio")},
4632 {PTP_DPC_NIKON_FunctionButton2, /* 0xD08C */
4633 N_("Function Button 2")},
4634 {PTP_DPC_NIKON_AFAreaPoint, /* 0xD08D */
4635 N_("AF Area Point")},
4636 {PTP_DPC_NIKON_NormalAFOn, /* 0xD08E */
4637 N_("Normal AF On")},
Linus Walleijb7c1a672013-03-05 09:08:44 +01004638 {PTP_DPC_NIKON_CleanImageSensor, /* 0xD08F */
4639 N_("Clean Image Sensor")},
Linus Walleijd1e14e02008-12-14 01:07:30 +00004640 {PTP_DPC_NIKON_ImageCommentString, /* 0xD090 */
4641 N_("Image Comment String")},
Linus Walleij7e3b3072009-01-19 22:51:17 +00004642 {PTP_DPC_NIKON_ImageCommentEnable, /* 0xD091 */
4643 N_("Image Comment Enable")},
Linus Walleijb02a0662006-04-25 08:05:09 +00004644 {PTP_DPC_NIKON_ImageRotation, /* 0xD092 */
4645 N_("Image Rotation")},
Linus Walleij1a0c3012009-07-23 23:06:58 +00004646 {PTP_DPC_NIKON_ManualSetLensNo, /* 0xD093 */
4647 N_("Manual Set Lens Number")},
4648 {PTP_DPC_NIKON_MovScreenSize, /* 0xD0A0 */
4649 N_("Movie Screen Size")},
4650 {PTP_DPC_NIKON_MovVoice, /* 0xD0A1 */
4651 N_("Movie Voice")},
Linus Walleijb7c1a672013-03-05 09:08:44 +01004652 {PTP_DPC_NIKON_MovMicrophone, /* 0xD0A2 */
4653 N_("Movie Microphone")},
4654 {PTP_DPC_NIKON_MovFileSlot, /* 0xD0A3 */
4655 N_("Movie Card Slot")},
4656 {PTP_DPC_NIKON_ManualMovieSetting, /* 0xD0A6 */
4657 N_("Manual Movie Setting")},
Marcus Meissner3d692dc2016-02-21 12:34:06 +01004658 {PTP_DPC_NIKON_MovQuality, /* 0xD0A7 */
4659 N_("Movie Quality")},
Linus Walleijb7c1a672013-03-05 09:08:44 +01004660 {PTP_DPC_NIKON_MonitorOffDelay, /* 0xD0B3 */
4661 N_("Monitor Off Delay")},
Linus Walleij1a0c3012009-07-23 23:06:58 +00004662 {PTP_DPC_NIKON_Bracketing, /* 0xD0C0 */
Linus Walleij7e3b3072009-01-19 22:51:17 +00004663 N_("Bracketing Enable")},
Linus Walleij1a0c3012009-07-23 23:06:58 +00004664 {PTP_DPC_NIKON_AutoExposureBracketStep, /* 0xD0C1 */
Linus Walleij7e3b3072009-01-19 22:51:17 +00004665 N_("Exposure Bracketing Step")},
Linus Walleij1a0c3012009-07-23 23:06:58 +00004666 {PTP_DPC_NIKON_AutoExposureBracketProgram, /* 0xD0C2 */
Linus Walleij7e3b3072009-01-19 22:51:17 +00004667 N_("Exposure Bracketing Program")},
Linus Walleij1a0c3012009-07-23 23:06:58 +00004668 {PTP_DPC_NIKON_AutoExposureBracketCount, /* 0xD0C3 */
Linus Walleij7e3b3072009-01-19 22:51:17 +00004669 N_("Auto Exposure Bracket Count")},
4670 {PTP_DPC_NIKON_WhiteBalanceBracketStep, N_("White Balance Bracket Step")}, /* 0xD0C4 */
4671 {PTP_DPC_NIKON_WhiteBalanceBracketProgram, N_("White Balance Bracket Program")}, /* 0xD0C5 */
Linus Walleijd1e14e02008-12-14 01:07:30 +00004672 {PTP_DPC_NIKON_LensID, /* 0xD0E0 */
4673 N_("Lens ID")},
Linus Walleij7e3b3072009-01-19 22:51:17 +00004674 {PTP_DPC_NIKON_LensSort, /* 0xD0E1 */
4675 N_("Lens Sort")},
4676 {PTP_DPC_NIKON_LensType, /* 0xD0E2 */
4677 N_("Lens Type")},
Linus Walleijd1e14e02008-12-14 01:07:30 +00004678 {PTP_DPC_NIKON_FocalLengthMin, /* 0xD0E3 */
4679 N_("Min. Focal Length")},
4680 {PTP_DPC_NIKON_FocalLengthMax, /* 0xD0E4 */
4681 N_("Max. Focal Length")},
4682 {PTP_DPC_NIKON_MaxApAtMinFocalLength, /* 0xD0E5 */
4683 N_("Max. Aperture at Min. Focal Length")},
4684 {PTP_DPC_NIKON_MaxApAtMaxFocalLength, /* 0xD0E6 */
4685 N_("Max. Aperture at Max. Focal Length")},
Linus Walleij1a0c3012009-07-23 23:06:58 +00004686 {PTP_DPC_NIKON_FinderISODisp, /* 0xD0F0 */
4687 N_("Finder ISO Display")},
4688 {PTP_DPC_NIKON_AutoOffPhoto, /* 0xD0F2 */
4689 N_("Auto Off Photo")},
4690 {PTP_DPC_NIKON_AutoOffMenu, /* 0xD0F3 */
4691 N_("Auto Off Menu")},
4692 {PTP_DPC_NIKON_AutoOffInfo, /* 0xD0F4 */
4693 N_("Auto Off Info")},
4694 {PTP_DPC_NIKON_SelfTimerShootNum, /* 0xD0F5 */
4695 N_("Self Timer Shot Number")},
4696 {PTP_DPC_NIKON_VignetteCtrl, /* 0xD0F7 */
4697 N_("Vignette Control")},
Linus Walleij3a1a82c2012-07-03 19:36:28 +02004698 {PTP_DPC_NIKON_AutoDistortionControl, /* 0xD0F8 */
4699 N_("Auto Distortion Control")},
Linus Walleijb7c1a672013-03-05 09:08:44 +01004700 {PTP_DPC_NIKON_SceneMode, /* 0xD0F9 */
4701 N_("Scene Mode")},
Linus Walleijd1e14e02008-12-14 01:07:30 +00004702 {PTP_DPC_NIKON_ExposureTime, /* 0xD100 */
4703 N_("Nikon Exposure Time")},
4704 {PTP_DPC_NIKON_ACPower, N_("AC Power")}, /* 0xD101 */
Linus Walleij7e3b3072009-01-19 22:51:17 +00004705 {PTP_DPC_NIKON_WarningStatus, N_("Warning Status")},/* 0xD102 */
Linus Walleijd1e14e02008-12-14 01:07:30 +00004706 {PTP_DPC_NIKON_MaximumShots, /* 0xD103 */
4707 N_("Maximum Shots")},
Linus Walleij7e3b3072009-01-19 22:51:17 +00004708 {PTP_DPC_NIKON_AFLockStatus, N_("AF Locked")},/* 0xD104 */
4709 {PTP_DPC_NIKON_AELockStatus, N_("AE Locked")},/* 0xD105 */
4710 {PTP_DPC_NIKON_FVLockStatus, N_("FV Locked")},/* 0xD106 */
Linus Walleijb02a0662006-04-25 08:05:09 +00004711 {PTP_DPC_NIKON_AutofocusLCDTopMode2, /* 0xD107 */
4712 N_("AF LCD Top Mode 2")},
4713 {PTP_DPC_NIKON_AutofocusArea, /* 0xD108 */
4714 N_("Active AF Sensor")},
Linus Walleij7e3b3072009-01-19 22:51:17 +00004715 {PTP_DPC_NIKON_FlexibleProgram, /* 0xD109 */
4716 N_("Flexible Program")},
Linus Walleij1a0c3012009-07-23 23:06:58 +00004717 {PTP_DPC_NIKON_LightMeter, /* 0xD10A */
Linus Walleijb02a0662006-04-25 08:05:09 +00004718 N_("Exposure Meter")},
Linus Walleij1a0c3012009-07-23 23:06:58 +00004719 {PTP_DPC_NIKON_RecordingMedia, /* 0xD10B */
Linus Walleij7e756532009-05-06 21:25:09 +00004720 N_("Recording Media")},
Linus Walleij1a0c3012009-07-23 23:06:58 +00004721 {PTP_DPC_NIKON_USBSpeed, /* 0xD10C */
Linus Walleij7e756532009-05-06 21:25:09 +00004722 N_("USB Speed")},
Linus Walleij1a0c3012009-07-23 23:06:58 +00004723 {PTP_DPC_NIKON_CCDNumber, /* 0xD10D */
Linus Walleij7e756532009-05-06 21:25:09 +00004724 N_("CCD Serial Number")},
Linus Walleij1a0c3012009-07-23 23:06:58 +00004725 {PTP_DPC_NIKON_CameraOrientation, /* 0xD10E */
Linus Walleijd1e14e02008-12-14 01:07:30 +00004726 N_("Camera Orientation")},
Linus Walleij1a0c3012009-07-23 23:06:58 +00004727 {PTP_DPC_NIKON_GroupPtnType, /* 0xD10F */
4728 N_("Group PTN Type")},
4729 {PTP_DPC_NIKON_FNumberLock, /* 0xD110 */
4730 N_("FNumber Lock")},
Linus Walleijb02a0662006-04-25 08:05:09 +00004731 {PTP_DPC_NIKON_ExposureApertureLock, /* 0xD111 */
4732 N_("Exposure Aperture Lock")},
Linus Walleij1a0c3012009-07-23 23:06:58 +00004733 {PTP_DPC_NIKON_TVLockSetting, /* 0xD112 */
4734 N_("TV Lock Setting")},
4735 {PTP_DPC_NIKON_AVLockSetting, /* 0xD113 */
4736 N_("AV Lock Setting")},
4737 {PTP_DPC_NIKON_IllumSetting, /* 0xD114 */
4738 N_("Illum Setting")},
4739 {PTP_DPC_NIKON_FocusPointBright, /* 0xD115 */
4740 N_("Focus Point Bright")},
Linus Walleij7e3b3072009-01-19 22:51:17 +00004741 {PTP_DPC_NIKON_ExternalFlashAttached, /* 0xD120 */
4742 N_("External Flash Attached")},
4743 {PTP_DPC_NIKON_ExternalFlashStatus, /* 0xD121 */
4744 N_("External Flash Status")},
4745 {PTP_DPC_NIKON_ExternalFlashSort, /* 0xD122 */
4746 N_("External Flash Sort")},
Linus Walleij1a0c3012009-07-23 23:06:58 +00004747 {PTP_DPC_NIKON_ExternalFlashMode, /* 0xD123 */
4748 N_("External Flash Mode")},
Linus Walleij7e3b3072009-01-19 22:51:17 +00004749 {PTP_DPC_NIKON_ExternalFlashCompensation, /* 0xD124 */
4750 N_("External Flash Compensation")},
4751 {PTP_DPC_NIKON_NewExternalFlashMode, /* 0xD125 */
4752 N_("External Flash Mode")},
Linus Walleijd1e14e02008-12-14 01:07:30 +00004753 {PTP_DPC_NIKON_FlashExposureCompensation, /* 0xD126 */
4754 N_("Flash Exposure Compensation")},
Linus Walleij3a1a82c2012-07-03 19:36:28 +02004755 {PTP_DPC_NIKON_HDRMode, /* 0xD130 */
4756 N_("HDR Mode")},
4757 {PTP_DPC_NIKON_HDRHighDynamic, /* 0xD131 */
4758 N_("HDR High Dynamic")},
4759 {PTP_DPC_NIKON_HDRSmoothing, /* 0xD132 */
4760 N_("HDR Smoothing")},
Linus Walleijb02a0662006-04-25 08:05:09 +00004761 {PTP_DPC_NIKON_OptimizeImage, /* 0xD140 */
4762 N_("Optimize Image")},
4763 {PTP_DPC_NIKON_Saturation, /* 0xD142 */
4764 N_("Saturation")},
Linus Walleij1a0c3012009-07-23 23:06:58 +00004765 {PTP_DPC_NIKON_BW_FillerEffect, /* 0xD143 */
4766 N_("BW Filler Effect")},
4767 {PTP_DPC_NIKON_BW_Sharpness, /* 0xD144 */
4768 N_("BW Sharpness")},
4769 {PTP_DPC_NIKON_BW_Contrast, /* 0xD145 */
4770 N_("BW Contrast")},
4771 {PTP_DPC_NIKON_BW_Setting_Type, /* 0xD146 */
4772 N_("BW Setting Type")},
4773 {PTP_DPC_NIKON_Slot2SaveMode, /* 0xD148 */
4774 N_("Slot 2 Save Mode")},
4775 {PTP_DPC_NIKON_RawBitMode, /* 0xD149 */
4776 N_("Raw Bit Mode")},
Linus Walleij2ad5b722013-11-04 02:07:44 +01004777 {PTP_DPC_NIKON_ActiveDLighting, /* 0xD14E */
4778 N_("Active D-Lighting")},
Linus Walleij1a0c3012009-07-23 23:06:58 +00004779 {PTP_DPC_NIKON_FlourescentType, /* 0xD14F */
4780 N_("Flourescent Type")},
4781 {PTP_DPC_NIKON_TuneColourTemperature, /* 0xD150 */
4782 N_("Tune Colour Temperature")},
4783 {PTP_DPC_NIKON_TunePreset0, /* 0xD151 */
4784 N_("Tune Preset 0")},
4785 {PTP_DPC_NIKON_TunePreset1, /* 0xD152 */
4786 N_("Tune Preset 1")},
4787 {PTP_DPC_NIKON_TunePreset2, /* 0xD153 */
4788 N_("Tune Preset 2")},
4789 {PTP_DPC_NIKON_TunePreset3, /* 0xD154 */
4790 N_("Tune Preset 3")},
4791 {PTP_DPC_NIKON_TunePreset4, /* 0xD155 */
4792 N_("Tune Preset 4")},
Linus Walleijd1e14e02008-12-14 01:07:30 +00004793 {PTP_DPC_NIKON_BeepOff, /* 0xD160 */
4794 N_("AF Beep Mode")},
4795 {PTP_DPC_NIKON_AutofocusMode, /* 0xD161 */
4796 N_("Autofocus Mode")},
4797 {PTP_DPC_NIKON_AFAssist, /* 0xD163 */
4798 N_("AF Assist Lamp")},
4799 {PTP_DPC_NIKON_PADVPMode, /* 0xD164 */
4800 N_("Auto ISO P/A/DVP Setting")},
4801 {PTP_DPC_NIKON_ImageReview, /* 0xD165 */
4802 N_("Image Review")},
4803 {PTP_DPC_NIKON_AFAreaIllumination, /* 0xD166 */
4804 N_("AF Area Illumination")},
4805 {PTP_DPC_NIKON_FlashMode, /* 0xD167 */
4806 N_("Flash Mode")},
4807 {PTP_DPC_NIKON_FlashCommanderMode, /* 0xD168 */
4808 N_("Flash Commander Mode")},
4809 {PTP_DPC_NIKON_FlashSign, /* 0xD169 */
4810 N_("Flash Sign")},
Linus Walleijb7c1a672013-03-05 09:08:44 +01004811 {PTP_DPC_NIKON_ISO_Auto, /* 0xD16A */
Linus Walleij1a0c3012009-07-23 23:06:58 +00004812 N_("ISO Auto")},
Linus Walleijd1e14e02008-12-14 01:07:30 +00004813 {PTP_DPC_NIKON_RemoteTimeout, /* 0xD16B */
4814 N_("Remote Timeout")},
4815 {PTP_DPC_NIKON_GridDisplay, /* 0xD16C */
4816 N_("Viewfinder Grid Display")},
4817 {PTP_DPC_NIKON_FlashModeManualPower, /* 0xD16D */
4818 N_("Flash Mode Manual Power")},
4819 {PTP_DPC_NIKON_FlashModeCommanderPower, /* 0xD16E */
4820 N_("Flash Mode Commander Power")},
Linus Walleij1a0c3012009-07-23 23:06:58 +00004821 {PTP_DPC_NIKON_AutoFP, /* 0xD16F */
4822 N_("Auto FP")},
Linus Walleijb02a0662006-04-25 08:05:09 +00004823 {PTP_DPC_NIKON_CSMMenu, /* 0xD180 */
4824 N_("CSM Menu")},
Linus Walleij1a0c3012009-07-23 23:06:58 +00004825 {PTP_DPC_NIKON_WarningDisplay, /* 0xD181 */
4826 N_("Warning Display")},
4827 {PTP_DPC_NIKON_BatteryCellKind, /* 0xD182 */
4828 N_("Battery Cell Kind")},
4829 {PTP_DPC_NIKON_ISOAutoHiLimit, /* 0xD183 */
4830 N_("ISO Auto High Limit")},
4831 {PTP_DPC_NIKON_DynamicAFArea, /* 0xD184 */
4832 N_("Dynamic AF Area")},
4833 {PTP_DPC_NIKON_ContinuousSpeedHigh, /* 0xD186 */
4834 N_("Continuous Speed High")},
4835 {PTP_DPC_NIKON_InfoDispSetting, /* 0xD187 */
4836 N_("Info Disp Setting")},
4837 {PTP_DPC_NIKON_PreviewButton, /* 0xD189 */
4838 N_("Preview Button")},
4839 {PTP_DPC_NIKON_PreviewButton2, /* 0xD18A */
4840 N_("Preview Button 2")},
4841 {PTP_DPC_NIKON_AEAFLockButton2, /* 0xD18B */
4842 N_("AEAF Lock Button 2")},
4843 {PTP_DPC_NIKON_IndicatorDisp, /* 0xD18D */
4844 N_("Indicator Display")},
4845 {PTP_DPC_NIKON_CellKindPriority, /* 0xD18E */
4846 N_("Cell Kind Priority")},
Linus Walleijd1e14e02008-12-14 01:07:30 +00004847 {PTP_DPC_NIKON_BracketingFramesAndSteps, /* 0xD190 */
4848 N_("Bracketing Frames and Steps")},
Linus Walleij1a0c3012009-07-23 23:06:58 +00004849 {PTP_DPC_NIKON_LiveViewMode, /* 0xD1A0 */
4850 N_("Live View Mode")},
4851 {PTP_DPC_NIKON_LiveViewDriveMode, /* 0xD1A1 */
4852 N_("Live View Drive Mode")},
Linus Walleij7e756532009-05-06 21:25:09 +00004853 {PTP_DPC_NIKON_LiveViewStatus, /* 0xD1A2 */
4854 N_("Live View Status")},
4855 {PTP_DPC_NIKON_LiveViewImageZoomRatio, /* 0xD1A3 */
4856 N_("Live View Image Zoom Ratio")},
4857 {PTP_DPC_NIKON_LiveViewProhibitCondition, /* 0xD1A4 */
4858 N_("Live View Prohibit Condition")},
4859 {PTP_DPC_NIKON_ExposureDisplayStatus, /* 0xD1B0 */
4860 N_("Exposure Display Status")},
Linus Walleij7e756532009-05-06 21:25:09 +00004861 {PTP_DPC_NIKON_ExposureIndicateStatus, /* 0xD1B1 */
4862 N_("Exposure Indicate Status")},
Linus Walleijb7c1a672013-03-05 09:08:44 +01004863 {PTP_DPC_NIKON_InfoDispErrStatus, /* 0xD1B2 */
4864 N_("Info Display Error Status")},
4865 {PTP_DPC_NIKON_ExposureIndicateLightup, /* 0xD1B3 */
Linus Walleij7e756532009-05-06 21:25:09 +00004866 N_("Exposure Indicate Lightup")},
Linus Walleijd1e14e02008-12-14 01:07:30 +00004867 {PTP_DPC_NIKON_FlashOpen, /* 0xD1C0 */
4868 N_("Flash Open")},
4869 {PTP_DPC_NIKON_FlashCharged, /* 0xD1C1 */
4870 N_("Flash Charged")},
Linus Walleij1a0c3012009-07-23 23:06:58 +00004871 {PTP_DPC_NIKON_FlashMRepeatValue, /* 0xD1D0 */
4872 N_("Flash MRepeat Value")},
4873 {PTP_DPC_NIKON_FlashMRepeatCount, /* 0xD1D1 */
4874 N_("Flash MRepeat Count")},
4875 {PTP_DPC_NIKON_FlashMRepeatInterval, /* 0xD1D2 */
4876 N_("Flash MRepeat Interval")},
4877 {PTP_DPC_NIKON_FlashCommandChannel, /* 0xD1D3 */
4878 N_("Flash Command Channel")},
4879 {PTP_DPC_NIKON_FlashCommandSelfMode, /* 0xD1D4 */
4880 N_("Flash Command Self Mode")},
4881 {PTP_DPC_NIKON_FlashCommandSelfCompensation, /* 0xD1D5 */
4882 N_("Flash Command Self Compensation")},
4883 {PTP_DPC_NIKON_FlashCommandSelfValue, /* 0xD1D6 */
4884 N_("Flash Command Self Value")},
4885 {PTP_DPC_NIKON_FlashCommandAMode, /* 0xD1D7 */
4886 N_("Flash Command A Mode")},
4887 {PTP_DPC_NIKON_FlashCommandACompensation, /* 0xD1D8 */
4888 N_("Flash Command A Compensation")},
4889 {PTP_DPC_NIKON_FlashCommandAValue, /* 0xD1D9 */
4890 N_("Flash Command A Value")},
4891 {PTP_DPC_NIKON_FlashCommandBMode, /* 0xD1DA */
4892 N_("Flash Command B Mode")},
4893 {PTP_DPC_NIKON_FlashCommandBCompensation, /* 0xD1DB */
4894 N_("Flash Command B Compensation")},
4895 {PTP_DPC_NIKON_FlashCommandBValue, /* 0xD1DC */
4896 N_("Flash Command B Value")},
Linus Walleij7e756532009-05-06 21:25:09 +00004897 {PTP_DPC_NIKON_ActivePicCtrlItem, /* 0xD200 */
4898 N_("Active Pic Ctrl Item")},
4899 {PTP_DPC_NIKON_ChangePicCtrlItem, /* 0xD201 */
4900 N_("Change Pic Ctrl Item")},
Marcus Meissner3d692dc2016-02-21 12:34:06 +01004901 /* nikon 1 stuff */
4902 {PTP_DPC_NIKON_1_ISO, /* 0xf002 */
4903 N_("ISO")},
4904 {PTP_DPC_NIKON_1_ImageSize, /* 0xf00a */
4905 N_("Image Size")},
4906 {PTP_DPC_NIKON_1_LongExposureNoiseReduction, /* 0xF00D */
4907 N_("Long Exposure Noise Reduction")},
4908 {PTP_DPC_NIKON_1_MovQuality, /* 0xF01C */
4909 N_("Movie Quality")},
4910 {PTP_DPC_NIKON_1_HiISONoiseReduction, /* 0xF00E */
4911 N_("High ISO Noise Reduction")},
4912 {PTP_DPC_NIKON_1_WhiteBalance, /* 0xF00C */
4913 N_("White Balance")},
4914 {PTP_DPC_NIKON_1_ImageCompression, /* 0xF009 */
4915 N_("Image Compression")},
4916 {PTP_DPC_NIKON_1_ActiveDLighting, /* 0xF00F */
4917 N_("Active D-Lighting")},
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00004918 {0,NULL}
4919 };
Linus Walleij545c7792006-06-13 15:22:30 +00004920 struct {
4921 uint16_t dpc;
4922 const char *txt;
4923 } ptp_device_properties_MTP[] = {
Linus Walleij1a0c3012009-07-23 23:06:58 +00004924 {PTP_DPC_MTP_SecureTime, N_("Secure Time")}, /* D101 */
4925 {PTP_DPC_MTP_DeviceCertificate, N_("Device Certificate")}, /* D102 */
4926 {PTP_DPC_MTP_RevocationInfo, N_("Revocation Info")}, /* D103 */
4927 {PTP_DPC_MTP_SynchronizationPartner, /* D401 */
Linus Walleij545c7792006-06-13 15:22:30 +00004928 N_("Synchronization Partner")},
Linus Walleij1a0c3012009-07-23 23:06:58 +00004929 {PTP_DPC_MTP_DeviceFriendlyName, /* D402 */
Linus Walleij53c5f4e2007-08-13 08:27:58 +00004930 N_("Friendly Device Name")},
Linus Walleij1a0c3012009-07-23 23:06:58 +00004931 {PTP_DPC_MTP_VolumeLevel, N_("Volume Level")}, /* D403 */
4932 {PTP_DPC_MTP_DeviceIcon, N_("Device Icon")}, /* D405 */
4933 {PTP_DPC_MTP_SessionInitiatorInfo, N_("Session Initiator Info")},/* D406 */
4934 {PTP_DPC_MTP_PerceivedDeviceType, N_("Perceived Device Type")},/* D407 */
4935 {PTP_DPC_MTP_PlaybackRate, N_("Playback Rate")}, /* D410 */
4936 {PTP_DPC_MTP_PlaybackObject, N_("Playback Object")}, /* D411 */
4937 {PTP_DPC_MTP_PlaybackContainerIndex, /* D412 */
Linus Walleij545c7792006-06-13 15:22:30 +00004938 N_("Playback Container Index")},
Linus Walleij1a0c3012009-07-23 23:06:58 +00004939 {PTP_DPC_MTP_PlaybackPosition, N_("Playback Position")}, /* D413 */
4940 {PTP_DPC_MTP_PlaysForSureID, N_("PlaysForSure ID")}, /* D131 (?) */
Linus Walleij545c7792006-06-13 15:22:30 +00004941 {0,NULL}
4942 };
Linus Walleije29ca682010-01-30 08:15:25 +00004943 struct {
4944 uint16_t dpc;
4945 const char *txt;
4946 } ptp_device_properties_FUJI[] = {
4947 {PTP_DPC_FUJI_ColorTemperature, N_("Color Temperature")}, /* 0xD017 */
4948 {PTP_DPC_FUJI_Quality, N_("Quality")}, /* 0xD018 */
4949 {PTP_DPC_FUJI_Quality, N_("Release Mode")}, /* 0xD201 */
4950 {PTP_DPC_FUJI_Quality, N_("Focus Areas")}, /* 0xD206 */
4951 {PTP_DPC_FUJI_Quality, N_("AE Lock")}, /* 0xD213 */
4952 {PTP_DPC_FUJI_Quality, N_("Aperture")}, /* 0xD218 */
4953 {PTP_DPC_FUJI_Quality, N_("Shutter Speed")}, /* 0xD219 */
4954 {0,NULL}
4955 };
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00004956
Marcus Meissner3d692dc2016-02-21 12:34:06 +01004957 struct {
4958 uint16_t dpc;
4959 const char *txt;
4960 } ptp_device_properties_SONY[] = {
4961 {PTP_DPC_SONY_DPCCompensation, ("DOC Compensation")}, /* 0xD200 */
4962 {PTP_DPC_SONY_DRangeOptimize, ("DRangeOptimize")}, /* 0xD201 */
4963 {PTP_DPC_SONY_ImageSize, N_("Image size")}, /* 0xD203 */
4964 {PTP_DPC_SONY_ShutterSpeed, N_("Shutter speed")}, /* 0xD20D */
4965 {PTP_DPC_SONY_ColorTemp, N_("Color temperature")}, /* 0xD20F */
4966 {PTP_DPC_SONY_CCFilter, ("CC Filter")}, /* 0xD210 */
4967 {PTP_DPC_SONY_AspectRatio, N_("Aspect Ratio")}, /* 0xD211 */
Marcus Meissneraa7d91a2017-03-16 15:59:48 +01004968 {PTP_DPC_SONY_FocusFound, N_("Focus status")}, /* 0xD213 */
4969 {PTP_DPC_SONY_ObjectInMemory, N_("Objects in memory")}, /* 0xD215 */
Marcus Meissner3d692dc2016-02-21 12:34:06 +01004970 {PTP_DPC_SONY_ExposeIndex, N_("Expose Index")}, /* 0xD216 */
Marcus Meissneraa7d91a2017-03-16 15:59:48 +01004971 {PTP_DPC_SONY_BatteryLevel, N_("Battery Level")}, /* 0xD218 */
Marcus Meissner3d692dc2016-02-21 12:34:06 +01004972 {PTP_DPC_SONY_PictureEffect, N_("Picture Effect")}, /* 0xD21B */
4973 {PTP_DPC_SONY_ABFilter, N_("AB Filter")}, /* 0xD21C */
4974 {PTP_DPC_SONY_ISO, N_("ISO")}, /* 0xD21E */
4975 {PTP_DPC_SONY_Movie, N_("Movie")}, /* 0xD2C8 */
4976 {PTP_DPC_SONY_StillImage, N_("Still Image")}, /* 0xD2C7 */
4977 {0,NULL}
4978 };
4979
Marcus Meissneraa7d91a2017-03-16 15:59:48 +01004980 struct {
4981 uint16_t dpc;
4982 const char *txt;
4983 } ptp_device_properties_PARROT[] = {
4984 {PTP_DPC_PARROT_PhotoSensorEnableMask, "PhotoSensorEnableMask"}, /* 0xD201 */
4985 {PTP_DPC_PARROT_PhotoSensorsKeepOn, "PhotoSensorsKeepOn"}, /* 0xD202 */
4986 {PTP_DPC_PARROT_MultispectralImageSize, "MultispectralImageSize"}, /* 0xD203 */
4987 {PTP_DPC_PARROT_MainBitDepth, "MainBitDepth"}, /* 0xD204 */
4988 {PTP_DPC_PARROT_MultispectralBitDepth, "MultispectralBitDepth"}, /* 0xD205 */
4989 {PTP_DPC_PARROT_HeatingEnable, "HeatingEnable"}, /* 0xD206 */
4990 {PTP_DPC_PARROT_WifiStatus, "WifiStatus"}, /* 0xD207 */
4991 {PTP_DPC_PARROT_WifiSSID, "WifiSSID"}, /* 0xD208 */
4992 {PTP_DPC_PARROT_WifiEncryptionType, "WifiEncryptionType"}, /* 0xD209 */
4993 {PTP_DPC_PARROT_WifiPassphrase, "WifiPassphrase"}, /* 0xD20A */
4994 {PTP_DPC_PARROT_WifiChannel, "WifiChannel"}, /* 0xD20B */
4995 {PTP_DPC_PARROT_Localization, "Localization"}, /* 0xD20C */
4996 {PTP_DPC_PARROT_WifiMode, "WifiMode"}, /* 0xD20D */
4997 {PTP_DPC_PARROT_AntiFlickeringFrequency, "AntiFlickeringFrequency"}, /* 0xD210 */
4998 {PTP_DPC_PARROT_DisplayOverlayMask, "DisplayOverlayMask"}, /* 0xD211 */
4999 {PTP_DPC_PARROT_GPSInterval, "GPSInterval"}, /* 0xD212 */
5000 {PTP_DPC_PARROT_MultisensorsExposureMeteringMode,"MultisensorsExposureMeteringMode"}, /* 0xD213 */
5001 {PTP_DPC_PARROT_MultisensorsExposureTime, "MultisensorsExposureTime"}, /* 0xD214 */
5002 {PTP_DPC_PARROT_MultisensorsExposureProgramMode,"MultisensorsExposureProgramMode"}, /* 0xD215 */
5003 {PTP_DPC_PARROT_MultisensorsExposureIndex, "MultisensorsExposureIndex"}, /* 0xD216 */
5004 {PTP_DPC_PARROT_MultisensorsIrradianceGain, "MultisensorsIrradianceGain"}, /* 0xD217 */
5005 {PTP_DPC_PARROT_MultisensorsIrradianceIntegrationTime,"MultisensorsIrradianceIntegrationTime"}, /* 0xD218 */
5006 {PTP_DPC_PARROT_OverlapRate, "OverlapRate"}, /* 0xD219 */
5007 {0,NULL}
5008 };
5009
Marcus Meissner3d692dc2016-02-21 12:34:06 +01005010
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00005011 for (i=0; ptp_device_properties[i].txt!=NULL; i++)
5012 if (ptp_device_properties[i].dpc==dpc)
5013 return (ptp_device_properties[i].txt);
5014
Linus Walleij749282b2009-08-12 22:56:59 +00005015 if (params->deviceinfo.VendorExtensionID==PTP_VENDOR_MICROSOFT
5016 || params->deviceinfo.VendorExtensionID==PTP_VENDOR_MTP)
Linus Walleij545c7792006-06-13 15:22:30 +00005017 for (i=0; ptp_device_properties_MTP[i].txt!=NULL; i++)
5018 if (ptp_device_properties_MTP[i].dpc==dpc)
5019 return (ptp_device_properties_MTP[i].txt);
5020
Linus Walleijb02a0662006-04-25 08:05:09 +00005021 if (params->deviceinfo.VendorExtensionID==PTP_VENDOR_EASTMAN_KODAK)
5022 for (i=0; ptp_device_properties_EK[i].txt!=NULL; i++)
5023 if (ptp_device_properties_EK[i].dpc==dpc)
5024 return (ptp_device_properties_EK[i].txt);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00005025
Linus Walleijb02a0662006-04-25 08:05:09 +00005026 if (params->deviceinfo.VendorExtensionID==PTP_VENDOR_CANON)
5027 for (i=0; ptp_device_properties_Canon[i].txt!=NULL; i++)
5028 if (ptp_device_properties_Canon[i].dpc==dpc)
5029 return (ptp_device_properties_Canon[i].txt);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00005030
Linus Walleijb02a0662006-04-25 08:05:09 +00005031 if (params->deviceinfo.VendorExtensionID==PTP_VENDOR_NIKON)
5032 for (i=0; ptp_device_properties_Nikon[i].txt!=NULL; i++)
5033 if (ptp_device_properties_Nikon[i].dpc==dpc)
5034 return (ptp_device_properties_Nikon[i].txt);
5035
Linus Walleije29ca682010-01-30 08:15:25 +00005036 if (params->deviceinfo.VendorExtensionID==PTP_VENDOR_FUJI)
5037 for (i=0; ptp_device_properties_FUJI[i].txt!=NULL; i++)
5038 if (ptp_device_properties_FUJI[i].dpc==dpc)
5039 return (ptp_device_properties_FUJI[i].txt);
5040
Marcus Meissner3d692dc2016-02-21 12:34:06 +01005041 if (params->deviceinfo.VendorExtensionID==PTP_VENDOR_SONY)
5042 for (i=0; ptp_device_properties_SONY[i].txt!=NULL; i++)
5043 if (ptp_device_properties_SONY[i].dpc==dpc)
5044 return (ptp_device_properties_SONY[i].txt);
Marcus Meissneraa7d91a2017-03-16 15:59:48 +01005045 if (params->deviceinfo.VendorExtensionID==PTP_VENDOR_PARROT)
5046 for (i=0; ptp_device_properties_PARROT[i].txt!=NULL; i++)
5047 if (ptp_device_properties_PARROT[i].dpc==dpc)
5048 return (ptp_device_properties_PARROT[i].txt);
5049
Marcus Meissner3d692dc2016-02-21 12:34:06 +01005050
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00005051 return NULL;
5052}
5053
Linus Walleijb02a0662006-04-25 08:05:09 +00005054static int64_t
5055_value_to_num(PTPPropertyValue *data, uint16_t dt) {
5056 if (dt == PTP_DTC_STR) {
5057 if (!data->str)
5058 return 0;
5059 return atol(data->str);
5060 }
5061 if (dt & PTP_DTC_ARRAY_MASK) {
5062 return 0;
5063 } else {
5064 switch (dt) {
5065 case PTP_DTC_UNDEF:
5066 return 0;
5067 case PTP_DTC_INT8:
5068 return data->i8;
5069 case PTP_DTC_UINT8:
5070 return data->u8;
5071 case PTP_DTC_INT16:
5072 return data->i16;
5073 case PTP_DTC_UINT16:
5074 return data->u16;
5075 case PTP_DTC_INT32:
5076 return data->i32;
5077 case PTP_DTC_UINT32:
5078 return data->u32;
5079 /*
5080 PTP_DTC_INT64
5081 PTP_DTC_UINT64
5082 PTP_DTC_INT128
5083 PTP_DTC_UINT128
5084 */
5085 default:
5086 return 0;
5087 }
5088 }
5089
5090 return 0;
5091}
5092
5093#define PTP_VAL_BOOL(dpc) {dpc, 0, N_("Off")}, {dpc, 1, N_("On")}
Linus Walleijd49955b2008-11-09 17:20:00 +00005094#define PTP_VENDOR_VAL_BOOL(dpc,vendor) {dpc, vendor, 0, N_("Off")}, {dpc, vendor, 1, N_("On")}
5095#define PTP_VENDOR_VAL_RBOOL(dpc,vendor) {dpc, vendor, 0, N_("On")}, {dpc, vendor, 1, N_("Off")}
5096#define PTP_VENDOR_VAL_YN(dpc,vendor) {dpc, vendor, 0, N_("No")}, {dpc, vendor, 1, N_("Yes")}
Linus Walleijb02a0662006-04-25 08:05:09 +00005097
5098int
5099ptp_render_property_value(PTPParams* params, uint16_t dpc,
Linus Walleij2ad5b722013-11-04 02:07:44 +01005100 PTPDevicePropDesc *dpd, unsigned int length, char *out)
Linus Walleijb02a0662006-04-25 08:05:09 +00005101{
Linus Walleij2ad5b722013-11-04 02:07:44 +01005102 unsigned int i;
Linus Walleijd49955b2008-11-09 17:20:00 +00005103 int64_t kval;
Linus Walleijb02a0662006-04-25 08:05:09 +00005104
5105 struct {
5106 uint16_t dpc;
Linus Walleijd49955b2008-11-09 17:20:00 +00005107 uint16_t vendor;
Linus Walleijb02a0662006-04-25 08:05:09 +00005108 double coef;
5109 double bias;
5110 const char *format;
5111 } ptp_value_trans[] = {
Linus Walleij1a0c3012009-07-23 23:06:58 +00005112 {PTP_DPC_BatteryLevel, 0, 1.0, 0.0, "%.0f%%"}, /* 5001 */
5113 {PTP_DPC_FNumber, 0, 0.01, 0.0, "f/%.2g"}, /* 5007 */
5114 {PTP_DPC_FocalLength, 0, 0.01, 0.0, "%.0f mm"}, /* 5008 */
5115 {PTP_DPC_FocusDistance, 0, 0.01, 0.0, "%.0f mm"}, /* 5009 */
5116 {PTP_DPC_ExposureTime, 0, 0.00001, 0.0, "%.2g sec"}, /* 500D */
5117 {PTP_DPC_ExposureIndex, 0, 1.0, 0.0, "ISO %.0f"}, /* 500F */
5118 {PTP_DPC_ExposureBiasCompensation, 0, 0.001, 0.0, N_("%.1f stops")},/* 5010 */
Linus Walleije29ca682010-01-30 08:15:25 +00005119 {PTP_DPC_CaptureDelay, 0, 0.001, 0.0, "%.1fs"}, /* 5012 */
Linus Walleij1a0c3012009-07-23 23:06:58 +00005120 {PTP_DPC_DigitalZoom, 0, 0.1, 0.0, "%.1f"}, /* 5016 */
Linus Walleije29ca682010-01-30 08:15:25 +00005121 {PTP_DPC_BurstInterval, 0, 0.001, 0.0, "%.1fs"}, /* 5019 */
Linus Walleijd49955b2008-11-09 17:20:00 +00005122
Linus Walleij1a0c3012009-07-23 23:06:58 +00005123 /* Nikon device properties */
5124 {PTP_DPC_NIKON_LightMeter, PTP_VENDOR_NIKON, 0.08333, 0.0, N_("%.1f stops")},/* D10A */
5125 {PTP_DPC_NIKON_FlashExposureCompensation, PTP_VENDOR_NIKON, 0.16666, 0.0, N_("%.1f stops")}, /* D126 */
5126 {PTP_DPC_NIKON_CenterWeightArea, PTP_VENDOR_NIKON, 2.0, 6.0, N_("%.0f mm")},/* D059 */
5127 {PTP_DPC_NIKON_FocalLengthMin, PTP_VENDOR_NIKON, 0.01, 0.0, "%.0f mm"}, /* D0E3 */
5128 {PTP_DPC_NIKON_FocalLengthMax, PTP_VENDOR_NIKON, 0.01, 0.0, "%.0f mm"}, /* D0E4 */
5129 {PTP_DPC_NIKON_MaxApAtMinFocalLength, PTP_VENDOR_NIKON, 0.01, 0.0, "f/%.2g"}, /* D0E5 */
5130 {PTP_DPC_NIKON_MaxApAtMaxFocalLength, PTP_VENDOR_NIKON, 0.01, 0.0, "f/%.2g"}, /* D0E6 */
5131 {PTP_DPC_NIKON_ExternalFlashCompensation, PTP_VENDOR_NIKON, 1.0/6.0, 0.0,"%.0f"}, /* D124 */
5132 {PTP_DPC_NIKON_ExposureIndicateStatus, PTP_VENDOR_NIKON, 0.08333, 0.0, N_("%.1f stops")},/* D1B1 - FIXME: check if correct. */
Linus Walleijb7c1a672013-03-05 09:08:44 +01005133 {PTP_DPC_NIKON_AngleLevel, PTP_VENDOR_NIKON, 1.0/65536, 0.0, "%.1f'"},/* 0xD067 */
Linus Walleijd49955b2008-11-09 17:20:00 +00005134 {0, 0, 0.0, 0.0, NULL}
Linus Walleijb02a0662006-04-25 08:05:09 +00005135 };
5136
5137 struct {
5138 uint16_t dpc;
Linus Walleijd49955b2008-11-09 17:20:00 +00005139 uint16_t vendor;
Linus Walleijb02a0662006-04-25 08:05:09 +00005140 int64_t key;
5141 char *value;
Linus Walleijd49955b2008-11-09 17:20:00 +00005142 } ptp_value_list[] = {
Linus Walleij1a0c3012009-07-23 23:06:58 +00005143 {PTP_DPC_CompressionSetting, 0, 0, N_("JPEG Basic")}, /* 5004 */
Linus Walleijd49955b2008-11-09 17:20:00 +00005144 {PTP_DPC_CompressionSetting, 0, 1, N_("JPEG Norm")},
5145 {PTP_DPC_CompressionSetting, 0, 2, N_("JPEG Fine")},
5146 {PTP_DPC_CompressionSetting, 0, 4, N_("RAW")},
5147 {PTP_DPC_CompressionSetting, 0, 5, N_("RAW + JPEG Basic")},
5148 {PTP_DPC_WhiteBalance, 0, 1, N_("Manual")},
Linus Walleij1a0c3012009-07-23 23:06:58 +00005149 {PTP_DPC_WhiteBalance, 0, 2, N_("Automatic")}, /* 5005 */
Linus Walleijd49955b2008-11-09 17:20:00 +00005150 {PTP_DPC_WhiteBalance, 0, 3, N_("One-push Automatic")},
5151 {PTP_DPC_WhiteBalance, 0, 4, N_("Daylight")},
5152 {PTP_DPC_WhiteBalance, 0, 5, N_("Fluorescent")},
5153 {PTP_DPC_WhiteBalance, 0, 6, N_("Incandescent")},
5154 {PTP_DPC_WhiteBalance, 0, 7, N_("Flash")},
5155 {PTP_DPC_WhiteBalance, PTP_VENDOR_NIKON, 32784, N_("Cloudy")},
5156 {PTP_DPC_WhiteBalance, PTP_VENDOR_NIKON, 32785, N_("Shade")},
5157 {PTP_DPC_WhiteBalance, PTP_VENDOR_NIKON, 32786, N_("Color Temperature")},
5158 {PTP_DPC_WhiteBalance, PTP_VENDOR_NIKON, 32787, N_("Preset")},
Linus Walleij1a0c3012009-07-23 23:06:58 +00005159 {PTP_DPC_FocusMode, 0, 1, N_("Manual Focus")}, /* 500A */
5160 {PTP_DPC_FocusMode, 0, 2, N_("Automatic")},
5161 {PTP_DPC_FocusMode, 0, 3, N_("Automatic Macro (close-up)")},
5162 {PTP_DPC_FocusMode, PTP_VENDOR_NIKON, 32784, "AF-S"},
5163 {PTP_DPC_FocusMode, PTP_VENDOR_NIKON, 32785, "AF-C"},
5164 {PTP_DPC_FocusMode, PTP_VENDOR_NIKON, 32786, "AF-A"},
5165 {PTP_DPC_ExposureMeteringMode, 0, 1, N_("Average")}, /* 500B */
5166 {PTP_DPC_ExposureMeteringMode, 0, 2, N_("Center Weighted Average")},
5167 {PTP_DPC_ExposureMeteringMode, 0, 3, N_("Multi-spot")},
5168 {PTP_DPC_ExposureMeteringMode, 0, 4, N_("Center-spot")},
5169 {PTP_DPC_FlashMode, 0, 0, N_("Undefined")}, /* 500C */
Linus Walleij7e3b3072009-01-19 22:51:17 +00005170 {PTP_DPC_FlashMode, 0, 1, N_("Automatic flash")},
5171 {PTP_DPC_FlashMode, 0, 2, N_("Flash off")},
5172 {PTP_DPC_FlashMode, 0, 3, N_("Fill flash")},
5173 {PTP_DPC_FlashMode, 0, 4, N_("Automatic Red-eye Reduction")},
5174 {PTP_DPC_FlashMode, 0, 5, N_("Red-eye fill flash")},
5175 {PTP_DPC_FlashMode, 0, 6, N_("External sync")},
Linus Walleijd6f25ba2011-11-14 23:00:52 +01005176 {PTP_DPC_FlashMode, PTP_VENDOR_NIKON, 32784, N_("Auto")},
5177 {PTP_DPC_FlashMode, PTP_VENDOR_NIKON, 32785, N_("Auto Slow Sync")},
Linus Walleij7e3b3072009-01-19 22:51:17 +00005178 {PTP_DPC_FlashMode, PTP_VENDOR_NIKON, 32786, N_("Rear Curtain Sync + Slow Sync")},
5179 {PTP_DPC_FlashMode, PTP_VENDOR_NIKON, 32787, N_("Red-eye Reduction + Slow Sync")},
Linus Walleij1a0c3012009-07-23 23:06:58 +00005180 {PTP_DPC_ExposureProgramMode, 0, 1, "M"}, /* 500E */
Linus Walleijd49955b2008-11-09 17:20:00 +00005181 {PTP_DPC_ExposureProgramMode, 0, 3, "A"},
5182 {PTP_DPC_ExposureProgramMode, 0, 4, "S"},
5183 {PTP_DPC_ExposureProgramMode, 0, 2, "P"},
5184 {PTP_DPC_ExposureProgramMode, PTP_VENDOR_NIKON, 32784, N_("Auto")},
5185 {PTP_DPC_ExposureProgramMode, PTP_VENDOR_NIKON, 32785, N_("Portrait")},
5186 {PTP_DPC_ExposureProgramMode, PTP_VENDOR_NIKON, 32786, N_("Landscape")},
5187 {PTP_DPC_ExposureProgramMode, PTP_VENDOR_NIKON, 32787, N_("Macro")},
5188 {PTP_DPC_ExposureProgramMode, PTP_VENDOR_NIKON, 32788, N_("Sports")},
5189 {PTP_DPC_ExposureProgramMode, PTP_VENDOR_NIKON, 32790, N_("Night Landscape")},
5190 {PTP_DPC_ExposureProgramMode, PTP_VENDOR_NIKON, 32789, N_("Night Portrait")},
Linus Walleij1a0c3012009-07-23 23:06:58 +00005191 {PTP_DPC_StillCaptureMode, 0, 1, N_("Single Shot")}, /* 5013 */
Linus Walleijd49955b2008-11-09 17:20:00 +00005192 {PTP_DPC_StillCaptureMode, 0, 2, N_("Power Wind")},
Linus Walleij7e3b3072009-01-19 22:51:17 +00005193 {PTP_DPC_StillCaptureMode, 0, 3, N_("Timelapse")},
Linus Walleijd49955b2008-11-09 17:20:00 +00005194 {PTP_DPC_StillCaptureMode, PTP_VENDOR_NIKON, 32784, N_("Continuous Low Speed")},
5195 {PTP_DPC_StillCaptureMode, PTP_VENDOR_NIKON, 32785, N_("Timer")},
5196 {PTP_DPC_StillCaptureMode, PTP_VENDOR_NIKON, 32787, N_("Remote")},
5197 {PTP_DPC_StillCaptureMode, PTP_VENDOR_NIKON, 32787, N_("Mirror Up")},
5198 {PTP_DPC_StillCaptureMode, PTP_VENDOR_NIKON, 32788, N_("Timer + Remote")},
Linus Walleij1a0c3012009-07-23 23:06:58 +00005199 {PTP_DPC_FocusMeteringMode, 0, 1, N_("Centre-spot")}, /* 501C */
5200 {PTP_DPC_FocusMeteringMode, 0, 2, N_("Multi-spot")},
5201 {PTP_DPC_FocusMeteringMode, PTP_VENDOR_NIKON, 32784, N_("Single Area")},
5202 {PTP_DPC_FocusMeteringMode, PTP_VENDOR_NIKON, 32785, N_("Closest Subject")},
5203 {PTP_DPC_FocusMeteringMode, PTP_VENDOR_NIKON, 32786, N_("Group Dynamic")},
Linus Walleijb02a0662006-04-25 08:05:09 +00005204
Linus Walleij1a0c3012009-07-23 23:06:58 +00005205
5206 /* Nikon specific device properties */
5207 {PTP_DPC_NIKON_ImageSharpening, PTP_VENDOR_NIKON, 0, N_("Auto")}, /* D02A */
Linus Walleijd49955b2008-11-09 17:20:00 +00005208 {PTP_DPC_NIKON_ImageSharpening, PTP_VENDOR_NIKON, 1, N_("Normal")},
5209 {PTP_DPC_NIKON_ImageSharpening, PTP_VENDOR_NIKON, 2, N_("Low")},
5210 {PTP_DPC_NIKON_ImageSharpening, PTP_VENDOR_NIKON, 3, N_("Medium Low")},
5211 {PTP_DPC_NIKON_ImageSharpening, PTP_VENDOR_NIKON, 4, N_("Medium high")},
5212 {PTP_DPC_NIKON_ImageSharpening, PTP_VENDOR_NIKON, 5, N_("High")},
5213 {PTP_DPC_NIKON_ImageSharpening, PTP_VENDOR_NIKON, 6, N_("None")},
Linus Walleijb02a0662006-04-25 08:05:09 +00005214
Linus Walleij1a0c3012009-07-23 23:06:58 +00005215 {PTP_DPC_NIKON_ToneCompensation, PTP_VENDOR_NIKON, 0, N_("Auto")}, /* D02B */
Linus Walleijd49955b2008-11-09 17:20:00 +00005216 {PTP_DPC_NIKON_ToneCompensation, PTP_VENDOR_NIKON, 1, N_("Normal")},
5217 {PTP_DPC_NIKON_ToneCompensation, PTP_VENDOR_NIKON, 2, N_("Low contrast")},
5218 {PTP_DPC_NIKON_ToneCompensation, PTP_VENDOR_NIKON, 3, N_("Medium Low")},
5219 {PTP_DPC_NIKON_ToneCompensation, PTP_VENDOR_NIKON, 4, N_("Medium High")},
5220 {PTP_DPC_NIKON_ToneCompensation, PTP_VENDOR_NIKON, 5, N_("High control")},
5221 {PTP_DPC_NIKON_ToneCompensation, PTP_VENDOR_NIKON, 6, N_("Custom")},
Linus Walleijb02a0662006-04-25 08:05:09 +00005222
Linus Walleij1a0c3012009-07-23 23:06:58 +00005223 {PTP_DPC_NIKON_ColorModel, PTP_VENDOR_NIKON, 0, "sRGB"}, /* D02C */
5224 {PTP_DPC_NIKON_ColorModel, PTP_VENDOR_NIKON, 1, "AdobeRGB"},
5225 {PTP_DPC_NIKON_ColorModel, PTP_VENDOR_NIKON, 2, "sRGB"},
Linus Walleijb02a0662006-04-25 08:05:09 +00005226
Linus Walleij1a0c3012009-07-23 23:06:58 +00005227 PTP_VENDOR_VAL_BOOL(PTP_DPC_NIKON_AutoDXCrop,PTP_VENDOR_NIKON), /* D033 */
Linus Walleijd1e14e02008-12-14 01:07:30 +00005228
Linus Walleij1a0c3012009-07-23 23:06:58 +00005229 PTP_VENDOR_VAL_BOOL(PTP_DPC_NIKON_FocusAreaWrap,PTP_VENDOR_NIKON), /* D04F */
Linus Walleijd1e14e02008-12-14 01:07:30 +00005230
Linus Walleij1a0c3012009-07-23 23:06:58 +00005231 PTP_VENDOR_VAL_BOOL(PTP_DPC_NIKON_EnableCopyright,PTP_VENDOR_NIKON), /* D053 */
5232 PTP_VENDOR_VAL_BOOL(PTP_DPC_NIKON_ISOAuto,PTP_VENDOR_NIKON), /* D054 */
Linus Walleijd49955b2008-11-09 17:20:00 +00005233
Linus Walleij1a0c3012009-07-23 23:06:58 +00005234 /* FIXME! this is not ISO Auto (which is a bool) Perhaps ISO Auto Time?*/
5235 {PTP_DPC_NIKON_ISOAuto, PTP_VENDOR_NIKON, 0, "1/125"}, /* D054 */
Linus Walleij7e3b3072009-01-19 22:51:17 +00005236 {PTP_DPC_NIKON_ISOAuto, PTP_VENDOR_NIKON, 1, "1/60"},
5237 {PTP_DPC_NIKON_ISOAuto, PTP_VENDOR_NIKON, 2, "1/30"},
5238 {PTP_DPC_NIKON_ISOAuto, PTP_VENDOR_NIKON, 3, "1/15"},
5239 {PTP_DPC_NIKON_ISOAuto, PTP_VENDOR_NIKON, 4, "1/8"},
5240 {PTP_DPC_NIKON_ISOAuto, PTP_VENDOR_NIKON, 5, "1/4"},
5241 {PTP_DPC_NIKON_ISOAuto, PTP_VENDOR_NIKON, 6, "1/2"},
5242 {PTP_DPC_NIKON_ISOAuto, PTP_VENDOR_NIKON, 7, "1"},
5243 {PTP_DPC_NIKON_ISOAuto, PTP_VENDOR_NIKON, 8, "2"},
5244 {PTP_DPC_NIKON_ISOAuto, PTP_VENDOR_NIKON, 9, "4"},
5245 {PTP_DPC_NIKON_ISOAuto, PTP_VENDOR_NIKON, 10, "8"},
5246 {PTP_DPC_NIKON_ISOAuto, PTP_VENDOR_NIKON, 11, "15"},
5247 {PTP_DPC_NIKON_ISOAuto, PTP_VENDOR_NIKON, 12, "30"},
5248
Linus Walleij1a0c3012009-07-23 23:06:58 +00005249 {PTP_DPC_NIKON_EVStep, PTP_VENDOR_NIKON, 0, "1/3"}, /* D056 */
5250 {PTP_DPC_NIKON_EVStep, PTP_VENDOR_NIKON, 1, "1/2"},
Linus Walleijd1e14e02008-12-14 01:07:30 +00005251
Linus Walleij1a0c3012009-07-23 23:06:58 +00005252 PTP_VENDOR_VAL_BOOL(PTP_DPC_NIKON_ExposureCompensation,PTP_VENDOR_NIKON),/*D058 */
5253 PTP_VENDOR_VAL_BOOL(PTP_DPC_NIKON_AELockMode,PTP_VENDOR_NIKON), /* D05E */
Linus Walleij7e3b3072009-01-19 22:51:17 +00005254
Linus Walleij1a0c3012009-07-23 23:06:58 +00005255 {PTP_DPC_NIKON_AELAFLMode, PTP_VENDOR_NIKON, 0, N_("AE/AF Lock")}, /* D05F */
5256 {PTP_DPC_NIKON_AELAFLMode, PTP_VENDOR_NIKON, 1, N_("AF Lock only")},
5257 {PTP_DPC_NIKON_AELAFLMode, PTP_VENDOR_NIKON, 2, N_("AE Lock only")},
5258 {PTP_DPC_NIKON_AELAFLMode, PTP_VENDOR_NIKON, 3, N_("AF Lock Hold")},
5259 {PTP_DPC_NIKON_AELAFLMode, PTP_VENDOR_NIKON, 4, N_("AF On")},
5260 {PTP_DPC_NIKON_AELAFLMode, PTP_VENDOR_NIKON, 5, N_("Flash Lock")},
5261
5262 {PTP_DPC_NIKON_MeterOff, PTP_VENDOR_NIKON, 0, N_("4 seconds")}, /* D062 */
Linus Walleij7e3b3072009-01-19 22:51:17 +00005263 {PTP_DPC_NIKON_MeterOff, PTP_VENDOR_NIKON, 1, N_("6 seconds")},
5264 {PTP_DPC_NIKON_MeterOff, PTP_VENDOR_NIKON, 2, N_("8 seconds")},
5265 {PTP_DPC_NIKON_MeterOff, PTP_VENDOR_NIKON, 3, N_("16 seconds")},
5266 {PTP_DPC_NIKON_MeterOff, PTP_VENDOR_NIKON, 4, N_("30 minutes")},
5267 {PTP_DPC_NIKON_MeterOff, PTP_VENDOR_NIKON, 5, N_("30 seconds")},
5268
Linus Walleij1a0c3012009-07-23 23:06:58 +00005269 {PTP_DPC_NIKON_SelfTimer, PTP_VENDOR_NIKON, 0, N_("2 seconds")}, /* D063 */
5270 {PTP_DPC_NIKON_SelfTimer, PTP_VENDOR_NIKON, 1, N_("5 seconds")},
5271 {PTP_DPC_NIKON_SelfTimer, PTP_VENDOR_NIKON, 2, N_("10 seconds")},
5272 {PTP_DPC_NIKON_SelfTimer, PTP_VENDOR_NIKON, 3, N_("20 seconds")},
5273
5274 {PTP_DPC_NIKON_MonitorOff, PTP_VENDOR_NIKON, 0, N_("10 seconds")}, /* D064 */
5275 {PTP_DPC_NIKON_MonitorOff, PTP_VENDOR_NIKON, 1, N_("20 seconds")},
5276 {PTP_DPC_NIKON_MonitorOff, PTP_VENDOR_NIKON, 2, N_("1 minute")},
5277 {PTP_DPC_NIKON_MonitorOff, PTP_VENDOR_NIKON, 3, N_("5 minutes")},
5278 {PTP_DPC_NIKON_MonitorOff, PTP_VENDOR_NIKON, 4, N_("10 minutes")},
5279 {PTP_DPC_NIKON_MonitorOff, PTP_VENDOR_NIKON, 5, N_("5 seconds")}, /* d80 observed */
5280
Linus Walleij0d762cc2010-04-04 23:34:27 +00005281 PTP_VENDOR_VAL_BOOL(PTP_DPC_NIKON_ExposureDelayMode,PTP_VENDOR_NIKON), /* D06A */
Linus Walleij1a0c3012009-07-23 23:06:58 +00005282 PTP_VENDOR_VAL_BOOL(PTP_DPC_NIKON_LongExposureNoiseReduction,PTP_VENDOR_NIKON), /* D06B */
5283 PTP_VENDOR_VAL_BOOL(PTP_DPC_NIKON_FileNumberSequence,PTP_VENDOR_NIKON), /* D06C */
5284 PTP_VENDOR_VAL_BOOL(PTP_DPC_NIKON_D7Illumination,PTP_VENDOR_NIKON), /* D06F */
5285
5286 PTP_VENDOR_VAL_BOOL(PTP_DPC_NIKON_SHSET_CH_GUID_DISP,PTP_VENDOR_NIKON), /* D071 */
5287
5288 {PTP_DPC_NIKON_FlashShutterSpeed, PTP_VENDOR_NIKON, 0, "1/60s"}, /* D075 */
5289 {PTP_DPC_NIKON_FlashShutterSpeed, PTP_VENDOR_NIKON, 1, "1/30s"},
5290 {PTP_DPC_NIKON_FlashShutterSpeed, PTP_VENDOR_NIKON, 2, "1/15s"},
5291 {PTP_DPC_NIKON_FlashShutterSpeed, PTP_VENDOR_NIKON, 3, "1/8s"},
5292 {PTP_DPC_NIKON_FlashShutterSpeed, PTP_VENDOR_NIKON, 4, "1/4s"},
5293 {PTP_DPC_NIKON_FlashShutterSpeed, PTP_VENDOR_NIKON, 5, "1/2s"},
5294 {PTP_DPC_NIKON_FlashShutterSpeed, PTP_VENDOR_NIKON, 6, "1s"},
5295 {PTP_DPC_NIKON_FlashShutterSpeed, PTP_VENDOR_NIKON, 7, "2s"},
5296 {PTP_DPC_NIKON_FlashShutterSpeed, PTP_VENDOR_NIKON, 8, "4s"},
5297 {PTP_DPC_NIKON_FlashShutterSpeed, PTP_VENDOR_NIKON, 9, "8s"},
5298 {PTP_DPC_NIKON_FlashShutterSpeed, PTP_VENDOR_NIKON, 10, "15s"},
5299 {PTP_DPC_NIKON_FlashShutterSpeed, PTP_VENDOR_NIKON, 11, "30s"},
5300
5301 PTP_VENDOR_VAL_BOOL(PTP_DPC_NIKON_E4ModelingFlash,PTP_VENDOR_NIKON), /* D077 */
5302
5303 {PTP_DPC_NIKON_BracketSet, PTP_VENDOR_NIKON, 0, N_("AE & Flash")}, /* D078 */
Linus Walleij7e3b3072009-01-19 22:51:17 +00005304 {PTP_DPC_NIKON_BracketSet, PTP_VENDOR_NIKON, 1, N_("AE only")},
5305 {PTP_DPC_NIKON_BracketSet, PTP_VENDOR_NIKON, 2, N_("Flash only")},
5306 {PTP_DPC_NIKON_BracketSet, PTP_VENDOR_NIKON, 3, N_("WB bracketing")},
5307
Linus Walleij1a0c3012009-07-23 23:06:58 +00005308 {PTP_DPC_NIKON_BracketOrder, PTP_VENDOR_NIKON, 0, N_("MTR > Under")}, /* D07A */
Linus Walleij7e3b3072009-01-19 22:51:17 +00005309 {PTP_DPC_NIKON_BracketOrder, PTP_VENDOR_NIKON, 1, N_("Under > MTR")},
5310
Linus Walleij1a0c3012009-07-23 23:06:58 +00005311 {PTP_DPC_NIKON_F1CenterButtonShootingMode, PTP_VENDOR_NIKON, 0, N_("Reset focus point to center")}, /* D080 */
5312 {PTP_DPC_NIKON_F1CenterButtonShootingMode, PTP_VENDOR_NIKON, 1, N_("Highlight active focus point")},
5313 {PTP_DPC_NIKON_F1CenterButtonShootingMode, PTP_VENDOR_NIKON, 2, N_("Unused")},
Linus Walleij7e3b3072009-01-19 22:51:17 +00005314
Linus Walleij1a0c3012009-07-23 23:06:58 +00005315 PTP_VENDOR_VAL_BOOL(PTP_DPC_NIKON_F3PhotoInfoPlayback,PTP_VENDOR_NIKON),/* D083 */
5316 PTP_VENDOR_VAL_BOOL(PTP_DPC_NIKON_F5CustomizeCommDials,PTP_VENDOR_NIKON),/* D085 */
5317 PTP_VENDOR_VAL_BOOL(PTP_DPC_NIKON_ReverseCommandDial,PTP_VENDOR_NIKON), /* D086 */
5318 PTP_VENDOR_VAL_RBOOL(PTP_DPC_NIKON_F6ButtonsAndDials,PTP_VENDOR_NIKON), /* D089 */
5319 PTP_VENDOR_VAL_RBOOL(PTP_DPC_NIKON_NoCFCard,PTP_VENDOR_NIKON), /* D08A */
5320 PTP_VENDOR_VAL_RBOOL(PTP_DPC_NIKON_AFAreaPoint,PTP_VENDOR_NIKON), /* D08D */
Linus Walleij7e3b3072009-01-19 22:51:17 +00005321
Linus Walleij1a0c3012009-07-23 23:06:58 +00005322 PTP_VENDOR_VAL_BOOL(PTP_DPC_NIKON_ImageCommentEnable,PTP_VENDOR_NIKON), /* D091 */
5323 PTP_VENDOR_VAL_RBOOL(PTP_DPC_NIKON_ImageRotation,PTP_VENDOR_NIKON), /* D092 */
5324
Linus Walleij9dd61b12011-06-08 00:45:17 +02005325 PTP_VENDOR_VAL_RBOOL(PTP_DPC_NIKON_MovVoice,PTP_VENDOR_NIKON), /* D0A1 */
Linus Walleij1a0c3012009-07-23 23:06:58 +00005326
5327 PTP_VENDOR_VAL_BOOL(PTP_DPC_NIKON_Bracketing,PTP_VENDOR_NIKON), /* D0C0 */
5328
Linus Walleijd6f25ba2011-11-14 23:00:52 +01005329 /* http://www.rottmerhusen.com/objektives/lensid/nikkor.html is complete */
Linus Walleij1a0c3012009-07-23 23:06:58 +00005330 {PTP_DPC_NIKON_LensID, PTP_VENDOR_NIKON, 0, N_("Unknown")}, /* D0E0 */
5331 {PTP_DPC_NIKON_LensID, PTP_VENDOR_NIKON, 38, "Sigma 70-300mm 1:4-5.6 D APO Macro"},
5332 {PTP_DPC_NIKON_LensID, PTP_VENDOR_NIKON, 83, "AF Nikkor 80-200mm 1:2.8 D ED"},
5333 {PTP_DPC_NIKON_LensID, PTP_VENDOR_NIKON, 118, "AF Nikkor 50mm 1:1.8 D"},
5334 {PTP_DPC_NIKON_LensID, PTP_VENDOR_NIKON, 127, "AF-S Nikkor 18-70mm 1:3.5-4.5G ED DX"},
5335 {PTP_DPC_NIKON_LensID, PTP_VENDOR_NIKON, 139, "AF-S Nikkor 18-200mm 1:3.5-5.6 GED DX VR"},
5336 {PTP_DPC_NIKON_LensID, PTP_VENDOR_NIKON, 147, "AF-S Nikkor 24-70mm 1:2.8G ED DX"},
5337 {PTP_DPC_NIKON_LensID, PTP_VENDOR_NIKON, 154, "AF-S Nikkor 18-55mm 1:3.5-F5.6G DX VR"},
Linus Walleij0d762cc2010-04-04 23:34:27 +00005338 {PTP_DPC_NIKON_LensID, PTP_VENDOR_NIKON, 159, "AF-S Nikkor 35mm 1:1.8G DX"},
Linus Walleij1a0c3012009-07-23 23:06:58 +00005339 {PTP_DPC_NIKON_FinderISODisp, PTP_VENDOR_NIKON, 0, "Show ISO sensitivity"},/* 0xD0F0 */
5340 {PTP_DPC_NIKON_FinderISODisp, PTP_VENDOR_NIKON, 1, "Show ISO/Easy ISO"},
5341 {PTP_DPC_NIKON_FinderISODisp, PTP_VENDOR_NIKON, 2, "Show frame count"},
5342
Linus Walleijb7c1a672013-03-05 09:08:44 +01005343 {PTP_DPC_NIKON_RawCompression, PTP_VENDOR_NIKON, 0, N_("Lossless")}, /* D016 */
5344 {PTP_DPC_NIKON_RawCompression, PTP_VENDOR_NIKON, 1, N_("Lossy")},
5345
Linus Walleij1a0c3012009-07-23 23:06:58 +00005346 PTP_VENDOR_VAL_YN(PTP_DPC_NIKON_ACPower,PTP_VENDOR_NIKON), /* D101 */
5347 PTP_VENDOR_VAL_YN(PTP_DPC_NIKON_AFLockStatus,PTP_VENDOR_NIKON), /* D104 */
5348 PTP_VENDOR_VAL_YN(PTP_DPC_NIKON_AELockStatus,PTP_VENDOR_NIKON), /* D105 */
5349 PTP_VENDOR_VAL_YN(PTP_DPC_NIKON_FVLockStatus,PTP_VENDOR_NIKON), /* D106 */
5350
5351 {PTP_DPC_NIKON_AutofocusArea, PTP_VENDOR_NIKON, 0, N_("Centre")}, /* D108 */
5352 {PTP_DPC_NIKON_AutofocusArea, PTP_VENDOR_NIKON, 1, N_("Top")},
5353 {PTP_DPC_NIKON_AutofocusArea, PTP_VENDOR_NIKON, 2, N_("Bottom")},
5354 {PTP_DPC_NIKON_AutofocusArea, PTP_VENDOR_NIKON, 3, N_("Left")},
5355 {PTP_DPC_NIKON_AutofocusArea, PTP_VENDOR_NIKON, 4, N_("Right")},
5356
5357 {PTP_DPC_NIKON_RecordingMedia, PTP_VENDOR_NIKON, 0, N_("Card")}, /* D10B */
5358 {PTP_DPC_NIKON_RecordingMedia, PTP_VENDOR_NIKON, 1, N_("SDRam")},
5359
5360 {PTP_DPC_NIKON_USBSpeed, PTP_VENDOR_NIKON, 0, N_("USB 1.1")}, /* D10C */
5361 {PTP_DPC_NIKON_USBSpeed, PTP_VENDOR_NIKON, 1, N_("USB 2.0")},
5362
5363 {PTP_DPC_NIKON_CameraOrientation, PTP_VENDOR_NIKON, 0, "0'"}, /* D10E */
5364 {PTP_DPC_NIKON_CameraOrientation, PTP_VENDOR_NIKON, 1, "270'"},
5365 {PTP_DPC_NIKON_CameraOrientation, PTP_VENDOR_NIKON, 2, "90'"},
5366 {PTP_DPC_NIKON_CameraOrientation, PTP_VENDOR_NIKON, 3, "180'"},
5367
5368 PTP_VENDOR_VAL_YN(PTP_DPC_NIKON_FNumberLock,PTP_VENDOR_NIKON), /* D110 */
5369 PTP_VENDOR_VAL_YN(PTP_DPC_NIKON_ExposureApertureLock,PTP_VENDOR_NIKON), /* D111 */
5370 PTP_VENDOR_VAL_YN(PTP_DPC_NIKON_TVLockSetting,PTP_VENDOR_NIKON), /* D112 */
5371 PTP_VENDOR_VAL_YN(PTP_DPC_NIKON_AVLockSetting,PTP_VENDOR_NIKON), /* D113 */
5372
5373 {PTP_DPC_NIKON_IllumSetting,PTP_VENDOR_NIKON,0,N_("LCD Backlight")}, /* D114 */
5374 {PTP_DPC_NIKON_IllumSetting,PTP_VENDOR_NIKON,1,N_("LCD Backlight and Info Display")},
5375
5376 PTP_VENDOR_VAL_YN(PTP_DPC_NIKON_ExternalFlashAttached,PTP_VENDOR_NIKON),/* D120 */
5377 PTP_VENDOR_VAL_YN(PTP_DPC_NIKON_ExternalFlashStatus,PTP_VENDOR_NIKON), /* D121 */
5378
5379 {PTP_DPC_NIKON_OptimizeImage, PTP_VENDOR_NIKON, 0, N_("Normal")}, /* D140 */
5380 {PTP_DPC_NIKON_OptimizeImage, PTP_VENDOR_NIKON, 1, N_("Vivid")},
5381 {PTP_DPC_NIKON_OptimizeImage, PTP_VENDOR_NIKON, 2, N_("Sharper")},
5382 {PTP_DPC_NIKON_OptimizeImage, PTP_VENDOR_NIKON, 3, N_("Softer")},
5383 {PTP_DPC_NIKON_OptimizeImage, PTP_VENDOR_NIKON, 4, N_("Direct Print")},
5384 {PTP_DPC_NIKON_OptimizeImage, PTP_VENDOR_NIKON, 5, N_("Portrait")},
5385 {PTP_DPC_NIKON_OptimizeImage, PTP_VENDOR_NIKON, 6, N_("Landscape")},
5386 {PTP_DPC_NIKON_OptimizeImage, PTP_VENDOR_NIKON, 7, N_("Custom")},
5387
5388 {PTP_DPC_NIKON_Saturation, PTP_VENDOR_NIKON, 0, N_("Normal")}, /* D142 */
5389 {PTP_DPC_NIKON_Saturation, PTP_VENDOR_NIKON, 1, N_("Moderate")},
5390 {PTP_DPC_NIKON_Saturation, PTP_VENDOR_NIKON, 2, N_("Enhanced")},
5391
5392 PTP_VENDOR_VAL_RBOOL(PTP_DPC_NIKON_BeepOff,PTP_VENDOR_NIKON), /* D160 */
5393
5394 {PTP_DPC_NIKON_AutofocusMode, PTP_VENDOR_NIKON, 0, N_("AF-S")}, /* D161 */
5395 {PTP_DPC_NIKON_AutofocusMode, PTP_VENDOR_NIKON, 1, N_("AF-C")},
5396 {PTP_DPC_NIKON_AutofocusMode, PTP_VENDOR_NIKON, 2, N_("AF-A")},
5397 {PTP_DPC_NIKON_AutofocusMode, PTP_VENDOR_NIKON, 3, N_("MF (fixed)")},
5398 {PTP_DPC_NIKON_AutofocusMode, PTP_VENDOR_NIKON, 4, N_("MF (selection)")},
5399
5400 PTP_VENDOR_VAL_RBOOL(PTP_DPC_NIKON_AFAssist,PTP_VENDOR_NIKON), /* D163 */
5401
5402 {PTP_DPC_NIKON_PADVPMode, PTP_VENDOR_NIKON, 0, "1/125"}, /* D164 */
Linus Walleij7e3b3072009-01-19 22:51:17 +00005403 {PTP_DPC_NIKON_PADVPMode, PTP_VENDOR_NIKON, 1, "1/60"},
5404 {PTP_DPC_NIKON_PADVPMode, PTP_VENDOR_NIKON, 2, "1/30"},
5405 {PTP_DPC_NIKON_PADVPMode, PTP_VENDOR_NIKON, 3, "1/15"},
5406 {PTP_DPC_NIKON_PADVPMode, PTP_VENDOR_NIKON, 4, "1/8"},
5407 {PTP_DPC_NIKON_PADVPMode, PTP_VENDOR_NIKON, 5, "1/4"},
5408 {PTP_DPC_NIKON_PADVPMode, PTP_VENDOR_NIKON, 6, "1/2"},
5409 {PTP_DPC_NIKON_PADVPMode, PTP_VENDOR_NIKON, 7, "1"},
5410 {PTP_DPC_NIKON_PADVPMode, PTP_VENDOR_NIKON, 8, "2"},
5411 {PTP_DPC_NIKON_PADVPMode, PTP_VENDOR_NIKON, 9, "4"},
5412 {PTP_DPC_NIKON_PADVPMode, PTP_VENDOR_NIKON, 10, "8"},
5413 {PTP_DPC_NIKON_PADVPMode, PTP_VENDOR_NIKON, 11, "15"},
5414 {PTP_DPC_NIKON_PADVPMode, PTP_VENDOR_NIKON, 12, "30"},
5415
Linus Walleij1a0c3012009-07-23 23:06:58 +00005416 PTP_VENDOR_VAL_RBOOL(PTP_DPC_NIKON_ImageReview,PTP_VENDOR_NIKON), /* D165 */
5417
5418 {PTP_DPC_NIKON_AFAreaIllumination, PTP_VENDOR_NIKON, 0, N_("Auto")}, /* D166 */
5419 {PTP_DPC_NIKON_AFAreaIllumination, PTP_VENDOR_NIKON, 1, N_("Off")},
5420 {PTP_DPC_NIKON_AFAreaIllumination, PTP_VENDOR_NIKON, 2, N_("On")},
5421
5422 {PTP_DPC_NIKON_FlashMode, PTP_VENDOR_NIKON, 0, "iTTL"}, /* D167 */
5423 {PTP_DPC_NIKON_FlashMode, PTP_VENDOR_NIKON, 1, N_("Manual")},
5424 {PTP_DPC_NIKON_FlashMode, PTP_VENDOR_NIKON, 2, N_("Commander")},
5425
5426 {PTP_DPC_NIKON_FlashCommanderMode, PTP_VENDOR_NIKON, 0, N_("TTL")}, /* D168 */
5427 {PTP_DPC_NIKON_FlashCommanderMode, PTP_VENDOR_NIKON, 1, N_("Auto Aperture")},
5428 {PTP_DPC_NIKON_FlashCommanderMode, PTP_VENDOR_NIKON, 2, N_("Full Manual")},
5429
5430 PTP_VENDOR_VAL_RBOOL(PTP_DPC_NIKON_FlashSign,PTP_VENDOR_NIKON), /* D169 */
5431
5432 {PTP_DPC_NIKON_RemoteTimeout, PTP_VENDOR_NIKON, 0, N_("1 min")}, /* D16B */
5433 {PTP_DPC_NIKON_RemoteTimeout, PTP_VENDOR_NIKON, 1, N_("5 mins")},
5434 {PTP_DPC_NIKON_RemoteTimeout, PTP_VENDOR_NIKON, 2, N_("10 mins")},
5435 {PTP_DPC_NIKON_RemoteTimeout, PTP_VENDOR_NIKON, 3, N_("15 mins")},
5436
5437 PTP_VENDOR_VAL_BOOL(PTP_DPC_NIKON_GridDisplay,PTP_VENDOR_NIKON), /* D16C */
5438
5439 {PTP_DPC_NIKON_FlashModeManualPower, PTP_VENDOR_NIKON, 0, N_("Full")}, /* D16D */
5440 {PTP_DPC_NIKON_FlashModeManualPower, PTP_VENDOR_NIKON, 1, "1/2"},
5441 {PTP_DPC_NIKON_FlashModeManualPower, PTP_VENDOR_NIKON, 2, "1/4"},
5442 {PTP_DPC_NIKON_FlashModeManualPower, PTP_VENDOR_NIKON, 3, "1/8"},
5443 {PTP_DPC_NIKON_FlashModeManualPower, PTP_VENDOR_NIKON, 4, "1/16"},
5444
5445 {PTP_DPC_NIKON_FlashModeCommanderPower, PTP_VENDOR_NIKON, 0, N_("Full")},/* D16E */
5446 {PTP_DPC_NIKON_FlashModeCommanderPower, PTP_VENDOR_NIKON, 1, "1/2"},
5447 {PTP_DPC_NIKON_FlashModeCommanderPower, PTP_VENDOR_NIKON, 2, "1/4"},
5448 {PTP_DPC_NIKON_FlashModeCommanderPower, PTP_VENDOR_NIKON, 3, "1/8"},
5449 {PTP_DPC_NIKON_FlashModeCommanderPower, PTP_VENDOR_NIKON, 4, "1/16"},
5450 {PTP_DPC_NIKON_FlashModeCommanderPower, PTP_VENDOR_NIKON, 5, "1/32"},
5451 {PTP_DPC_NIKON_FlashModeCommanderPower, PTP_VENDOR_NIKON, 6, "1/64"},
5452 {PTP_DPC_NIKON_FlashModeCommanderPower, PTP_VENDOR_NIKON, 7, "1/128"},
5453
5454 PTP_VENDOR_VAL_YN(PTP_DPC_NIKON_CSMMenu,PTP_VENDOR_NIKON), /* D180 */
5455 PTP_VENDOR_VAL_YN(PTP_DPC_NIKON_WarningDisplay,PTP_VENDOR_NIKON), /* D181 */
5456
5457 {PTP_DPC_NIKON_BatteryCellKind, PTP_VENDOR_NIKON, 0, "LR6 (AA alkaline)"},/* D182 */
5458 {PTP_DPC_NIKON_BatteryCellKind, PTP_VENDOR_NIKON, 1, "HR6 (AA Ni-Mh)"},
5459 {PTP_DPC_NIKON_BatteryCellKind, PTP_VENDOR_NIKON, 2, "FR6 (AA Lithium)"},
5460 {PTP_DPC_NIKON_BatteryCellKind, PTP_VENDOR_NIKON, 3, "ZR6 (AA Ni-Mn)"},
5461
5462 {PTP_DPC_NIKON_ISOAutoHiLimit, PTP_VENDOR_NIKON, 0, "400"}, /* D183 */
5463 {PTP_DPC_NIKON_ISOAutoHiLimit, PTP_VENDOR_NIKON, 1, "800"},
5464 {PTP_DPC_NIKON_ISOAutoHiLimit, PTP_VENDOR_NIKON, 2, "1600"},
5465 {PTP_DPC_NIKON_ISOAutoHiLimit, PTP_VENDOR_NIKON, 3, "3200"},
5466 {PTP_DPC_NIKON_ISOAutoHiLimit, PTP_VENDOR_NIKON, 4, "Hi 1"},
Linus Walleijd6f25ba2011-11-14 23:00:52 +01005467 {PTP_DPC_NIKON_ISOAutoHiLimit, PTP_VENDOR_NIKON, 5, "Hi 2"},
Linus Walleij1a0c3012009-07-23 23:06:58 +00005468
5469 {PTP_DPC_NIKON_InfoDispSetting, PTP_VENDOR_NIKON, 0, N_("Auto")}, /* 0xD187 */
5470 {PTP_DPC_NIKON_InfoDispSetting, PTP_VENDOR_NIKON, 1, N_("Dark on light")},
5471 {PTP_DPC_NIKON_InfoDispSetting, PTP_VENDOR_NIKON, 2, N_("Light on dark")},
5472
5473 PTP_VENDOR_VAL_YN(PTP_DPC_NIKON_IndicatorDisp,PTP_VENDOR_NIKON), /* D18D */
5474
5475 PTP_VENDOR_VAL_YN(PTP_DPC_NIKON_LiveViewStatus,PTP_VENDOR_NIKON), /* D1A2 */
5476
5477 PTP_VENDOR_VAL_YN(PTP_DPC_NIKON_ExposureDisplayStatus,PTP_VENDOR_NIKON),/* D1B0 */
5478 PTP_VENDOR_VAL_YN(PTP_DPC_NIKON_InfoDispErrStatus,PTP_VENDOR_NIKON), /* D1B2 */
5479 PTP_VENDOR_VAL_YN(PTP_DPC_NIKON_ExposureIndicateLightup,PTP_VENDOR_NIKON),/* D1B3 */
5480
5481 PTP_VENDOR_VAL_YN(PTP_DPC_NIKON_FlashOpen,PTP_VENDOR_NIKON), /* D1C0 */
5482 PTP_VENDOR_VAL_YN(PTP_DPC_NIKON_FlashCharged,PTP_VENDOR_NIKON), /* D1C1 */
Linus Walleij7e3b3072009-01-19 22:51:17 +00005483
Linus Walleijb7c1a672013-03-05 09:08:44 +01005484 PTP_VENDOR_VAL_YN(PTP_DPC_NIKON_ManualMovieSetting,PTP_VENDOR_NIKON), /* 0xD0A6 */
5485
5486 {PTP_DPC_NIKON_FlickerReduction, PTP_VENDOR_NIKON, 0, "50Hz"}, /* 0xD034 */
5487 {PTP_DPC_NIKON_FlickerReduction, PTP_VENDOR_NIKON, 1, "60Hz"},
5488
5489 {PTP_DPC_NIKON_RemoteMode, PTP_VENDOR_NIKON, 0, N_("Delayed Remote")}, /* 0xD035 */
5490 {PTP_DPC_NIKON_RemoteMode, PTP_VENDOR_NIKON, 1, N_("Quick Response")}, /* 0xD035 */
5491 {PTP_DPC_NIKON_RemoteMode, PTP_VENDOR_NIKON, 2, N_("Remote Mirror Up")},/* 0xD035 */
5492
5493 {PTP_DPC_NIKON_MonitorOffDelay, PTP_VENDOR_NIKON, 0, "5min"}, /* 0xD0b3 */
5494 {PTP_DPC_NIKON_MonitorOffDelay, PTP_VENDOR_NIKON, 1, "10min"}, /* 0xD0b3 */
5495 {PTP_DPC_NIKON_MonitorOffDelay, PTP_VENDOR_NIKON, 2, "15min"}, /* 0xD0b3 */
5496 {PTP_DPC_NIKON_MonitorOffDelay, PTP_VENDOR_NIKON, 3, "20min"}, /* 0xD0b3 */
5497 {PTP_DPC_NIKON_MonitorOffDelay, PTP_VENDOR_NIKON, 4, "30min"}, /* 0xD0b3 */
5498
5499
Linus Walleijd49955b2008-11-09 17:20:00 +00005500 /* Canon stuff */
Linus Walleijd1e14e02008-12-14 01:07:30 +00005501 PTP_VENDOR_VAL_BOOL(PTP_DPC_CANON_AssistLight,PTP_VENDOR_CANON),
Linus Walleijd49955b2008-11-09 17:20:00 +00005502 PTP_VENDOR_VAL_RBOOL(PTP_DPC_CANON_RotationScene,PTP_VENDOR_CANON),
5503 PTP_VENDOR_VAL_RBOOL(PTP_DPC_CANON_BeepMode,PTP_VENDOR_CANON),
Linus Walleijd1e14e02008-12-14 01:07:30 +00005504 PTP_VENDOR_VAL_BOOL(PTP_DPC_CANON_Beep,PTP_VENDOR_CANON),
Linus Walleijd49955b2008-11-09 17:20:00 +00005505
5506 {PTP_DPC_CANON_RotationAngle, PTP_VENDOR_CANON, 0, "0'"},
5507 {PTP_DPC_CANON_RotationAngle, PTP_VENDOR_CANON, 3, "270'"},
5508 {PTP_DPC_CANON_RotationAngle, PTP_VENDOR_CANON, 1, "90'"},
5509
5510 {PTP_DPC_CANON_BatteryKind, PTP_VENDOR_CANON, 0, N_("Unknown")},
5511 {PTP_DPC_CANON_BatteryKind, PTP_VENDOR_CANON, 1, N_("AC")},
5512 {PTP_DPC_CANON_BatteryKind, PTP_VENDOR_CANON, 2, N_("Lithium Ion")},
5513 {PTP_DPC_CANON_BatteryKind, PTP_VENDOR_CANON, 3, N_("Nickel hydride")},
5514 {PTP_DPC_CANON_BatteryKind, PTP_VENDOR_CANON, 4, N_("Nickel cadmium")},
5515 {PTP_DPC_CANON_BatteryKind, PTP_VENDOR_CANON, 5, N_("Alkalium manganese")},
5516
5517 {PTP_DPC_CANON_BatteryStatus, PTP_VENDOR_CANON, 0, N_("Undefined")},
5518 {PTP_DPC_CANON_BatteryStatus, PTP_VENDOR_CANON, 1, N_("Normal")},
5519 {PTP_DPC_CANON_BatteryStatus, PTP_VENDOR_CANON, 2, N_("Warning Level 1")},
5520 {PTP_DPC_CANON_BatteryStatus, PTP_VENDOR_CANON, 3, N_("Emergency")},
5521 {PTP_DPC_CANON_BatteryStatus, PTP_VENDOR_CANON, 4, N_("Warning Level 0")},
Linus Walleijd1e14e02008-12-14 01:07:30 +00005522
5523 {PTP_DPC_CANON_ImageQuality, PTP_VENDOR_CANON, 0, N_("Undefined")},
5524 {PTP_DPC_CANON_ImageQuality, PTP_VENDOR_CANON, 1, N_("Economy")},
5525 {PTP_DPC_CANON_ImageQuality, PTP_VENDOR_CANON, 2, N_("Normal")},
5526 {PTP_DPC_CANON_ImageQuality, PTP_VENDOR_CANON, 3, N_("Fine")},
5527 {PTP_DPC_CANON_ImageQuality, PTP_VENDOR_CANON, 4, N_("Lossless")},
5528 {PTP_DPC_CANON_ImageQuality, PTP_VENDOR_CANON, 5, N_("SuperFine")},
5529
5530 {PTP_DPC_CANON_FullViewFileFormat, PTP_VENDOR_CANON, 0, N_("Undefined")},
5531 {PTP_DPC_CANON_FullViewFileFormat, PTP_VENDOR_CANON, 1, N_("JPEG")},
5532 {PTP_DPC_CANON_FullViewFileFormat, PTP_VENDOR_CANON, 2, N_("CRW")},
5533
5534 {PTP_DPC_CANON_ImageSize, PTP_VENDOR_CANON, 0, N_("Large")},
5535 {PTP_DPC_CANON_ImageSize, PTP_VENDOR_CANON, 1, N_("Medium 1")},
5536 {PTP_DPC_CANON_ImageSize, PTP_VENDOR_CANON, 2, N_("Small")},
5537 {PTP_DPC_CANON_ImageSize, PTP_VENDOR_CANON, 3, N_("Medium 2")},
5538 {PTP_DPC_CANON_ImageSize, PTP_VENDOR_CANON, 7, N_("Medium 3")},
5539
5540 {PTP_DPC_CANON_SelfTime, PTP_VENDOR_CANON, 0, N_("Not used")},
5541 {PTP_DPC_CANON_SelfTime, PTP_VENDOR_CANON, 100, N_("10 seconds")},
5542 {PTP_DPC_CANON_SelfTime, PTP_VENDOR_CANON, 20, N_("2 seconds")},
5543
5544 {PTP_DPC_CANON_FlashMode, PTP_VENDOR_CANON, 0, N_("Off")},
5545 {PTP_DPC_CANON_FlashMode, PTP_VENDOR_CANON, 1, N_("Auto")},
5546 {PTP_DPC_CANON_FlashMode, PTP_VENDOR_CANON, 2, N_("On")},
5547 {PTP_DPC_CANON_FlashMode, PTP_VENDOR_CANON, 3, N_("Red Eye Suppression")},
5548 {PTP_DPC_CANON_FlashMode, PTP_VENDOR_CANON, 4, N_("Low Speed Synchronization")},
5549 {PTP_DPC_CANON_FlashMode, PTP_VENDOR_CANON, 5, N_("Auto + Red Eye Suppression")},
5550 {PTP_DPC_CANON_FlashMode, PTP_VENDOR_CANON, 6, N_("On + Red Eye Suppression")},
5551
5552 {PTP_DPC_CANON_ShootingMode, PTP_VENDOR_CANON, 0, N_("Auto")},
5553 {PTP_DPC_CANON_ShootingMode, PTP_VENDOR_CANON, 1, N_("P")},
5554 {PTP_DPC_CANON_ShootingMode, PTP_VENDOR_CANON, 2, N_("Tv")},
5555 {PTP_DPC_CANON_ShootingMode, PTP_VENDOR_CANON, 3, N_("Av")},
5556 {PTP_DPC_CANON_ShootingMode, PTP_VENDOR_CANON, 4, N_("M")},
5557 {PTP_DPC_CANON_ShootingMode, PTP_VENDOR_CANON, 5, N_("A_DEP")},
5558 {PTP_DPC_CANON_ShootingMode, PTP_VENDOR_CANON, 6, N_("M_DEP")},
5559 {PTP_DPC_CANON_ShootingMode, PTP_VENDOR_CANON, 7, N_("Bulb")},
5560 /* more actually */
5561
5562 {PTP_DPC_CANON_ImageMode, PTP_VENDOR_CANON, 0, N_("Auto")},
5563 {PTP_DPC_CANON_ImageMode, PTP_VENDOR_CANON, 1, N_("Manual")},
5564 {PTP_DPC_CANON_ImageMode, PTP_VENDOR_CANON, 2, N_("Distant View")},
5565 {PTP_DPC_CANON_ImageMode, PTP_VENDOR_CANON, 3, N_("High-Speed Shutter")},
5566 {PTP_DPC_CANON_ImageMode, PTP_VENDOR_CANON, 4, N_("Low-Speed Shutter")},
5567 {PTP_DPC_CANON_ImageMode, PTP_VENDOR_CANON, 5, N_("Night View")},
5568 {PTP_DPC_CANON_ImageMode, PTP_VENDOR_CANON, 6, N_("Grayscale")},
5569 {PTP_DPC_CANON_ImageMode, PTP_VENDOR_CANON, 7, N_("Sepia")},
5570 {PTP_DPC_CANON_ImageMode, PTP_VENDOR_CANON, 8, N_("Portrait")},
5571 {PTP_DPC_CANON_ImageMode, PTP_VENDOR_CANON, 9, N_("Sports")},
5572 {PTP_DPC_CANON_ImageMode, PTP_VENDOR_CANON, 10, N_("Macro")},
5573 {PTP_DPC_CANON_ImageMode, PTP_VENDOR_CANON, 11, N_("Monochrome")},
5574 {PTP_DPC_CANON_ImageMode, PTP_VENDOR_CANON, 12, N_("Pan Focus")},
5575 {PTP_DPC_CANON_ImageMode, PTP_VENDOR_CANON, 13, N_("Neutral")},
5576 {PTP_DPC_CANON_ImageMode, PTP_VENDOR_CANON, 14, N_("Soft")},
5577
5578 {PTP_DPC_CANON_DriveMode, PTP_VENDOR_CANON, 0, N_("Single-Frame Shooting")},
5579 {PTP_DPC_CANON_DriveMode, PTP_VENDOR_CANON, 1, N_("Continuous Shooting")},
5580 {PTP_DPC_CANON_DriveMode, PTP_VENDOR_CANON, 2, N_("Timer (Single) Shooting")},
5581 {PTP_DPC_CANON_DriveMode, PTP_VENDOR_CANON, 4, N_("Continuous Low-speed Shooting")},
5582 {PTP_DPC_CANON_DriveMode, PTP_VENDOR_CANON, 5, N_("Continuous High-speed Shooting")},
5583
5584 {PTP_DPC_CANON_EZoom, PTP_VENDOR_CANON, 0, N_("Off")},
5585 {PTP_DPC_CANON_EZoom, PTP_VENDOR_CANON, 1, N_("2x")},
5586 {PTP_DPC_CANON_EZoom, PTP_VENDOR_CANON, 2, N_("4x")},
5587 {PTP_DPC_CANON_EZoom, PTP_VENDOR_CANON, 3, N_("Smooth")},
5588
5589 {PTP_DPC_CANON_MeteringMode, PTP_VENDOR_CANON, 0, N_("Center-weighted Metering")},
5590 {PTP_DPC_CANON_MeteringMode, PTP_VENDOR_CANON, 1, N_("Spot Metering")},
5591 {PTP_DPC_CANON_MeteringMode, PTP_VENDOR_CANON, 2, N_("Average Metering")},
5592 {PTP_DPC_CANON_MeteringMode, PTP_VENDOR_CANON, 3, N_("Evaluative Metering")},
5593 {PTP_DPC_CANON_MeteringMode, PTP_VENDOR_CANON, 4, N_("Partial Metering")},
5594 {PTP_DPC_CANON_MeteringMode, PTP_VENDOR_CANON, 5, N_("Center-weighted Average Metering")},
5595 {PTP_DPC_CANON_MeteringMode, PTP_VENDOR_CANON, 6, N_("Spot Metering Interlocked with AF Frame")},
5596 {PTP_DPC_CANON_MeteringMode, PTP_VENDOR_CANON, 7, N_("Multi-Spot Metering")},
5597
5598 {PTP_DPC_CANON_AFDistance, PTP_VENDOR_CANON, 0, N_("Manual")},
5599 {PTP_DPC_CANON_AFDistance, PTP_VENDOR_CANON, 1, N_("Auto")},
5600 {PTP_DPC_CANON_AFDistance, PTP_VENDOR_CANON, 2, N_("Unknown")},
5601 {PTP_DPC_CANON_AFDistance, PTP_VENDOR_CANON, 3, N_("Zone Focus (Close-up)")},
5602 {PTP_DPC_CANON_AFDistance, PTP_VENDOR_CANON, 4, N_("Zone Focus (Very Close)")},
5603 {PTP_DPC_CANON_AFDistance, PTP_VENDOR_CANON, 5, N_("Zone Focus (Close)")},
5604 {PTP_DPC_CANON_AFDistance, PTP_VENDOR_CANON, 6, N_("Zone Focus (Medium)")},
5605 {PTP_DPC_CANON_AFDistance, PTP_VENDOR_CANON, 7, N_("Zone Focus (Far)")},
5606
5607 {PTP_DPC_CANON_FocusingPoint, PTP_VENDOR_CANON, 0, N_("Invalid")},
5608 {PTP_DPC_CANON_FocusingPoint, PTP_VENDOR_CANON, 0x1000, N_("Focusing Point on Center Only, Manual")},
5609 {PTP_DPC_CANON_FocusingPoint, PTP_VENDOR_CANON, 0x1001, N_("Focusing Point on Center Only, Auto")},
5610 {PTP_DPC_CANON_FocusingPoint, PTP_VENDOR_CANON, 0x3000, N_("Multiple Focusing Points (No Specification), Manual")},
5611 {PTP_DPC_CANON_FocusingPoint, PTP_VENDOR_CANON, 0x3001, N_("Multiple Focusing Points, Auto")},
5612 {PTP_DPC_CANON_FocusingPoint, PTP_VENDOR_CANON, 0x3002, N_("Multiple Focusing Points (Right)")},
5613 {PTP_DPC_CANON_FocusingPoint, PTP_VENDOR_CANON, 0x3003, N_("Multiple Focusing Points (Center)")},
5614 {PTP_DPC_CANON_FocusingPoint, PTP_VENDOR_CANON, 0x3004, N_("Multiple Focusing Points (Left)")},
5615
5616 {PTP_DPC_CANON_WhiteBalance, PTP_VENDOR_CANON, 0, N_("Auto")},
5617 {PTP_DPC_CANON_WhiteBalance, PTP_VENDOR_CANON, 1, N_("Daylight")},
5618 {PTP_DPC_CANON_WhiteBalance, PTP_VENDOR_CANON, 2, N_("Cloudy")},
5619 {PTP_DPC_CANON_WhiteBalance, PTP_VENDOR_CANON, 3, N_("Tungsten")},
5620 {PTP_DPC_CANON_WhiteBalance, PTP_VENDOR_CANON, 4, N_("Fluorescent")},
5621 {PTP_DPC_CANON_WhiteBalance, PTP_VENDOR_CANON, 6, N_("Preset")},
5622 {PTP_DPC_CANON_WhiteBalance, PTP_VENDOR_CANON, 7, N_("Fluorescent H")},
5623 {PTP_DPC_CANON_WhiteBalance, PTP_VENDOR_CANON, 9, N_("Color Temperature")},
5624 {PTP_DPC_CANON_WhiteBalance, PTP_VENDOR_CANON, 10, N_("Custom Whitebalance PC-1")},
5625 {PTP_DPC_CANON_WhiteBalance, PTP_VENDOR_CANON, 11, N_("Custom Whitebalance PC-2")},
5626 {PTP_DPC_CANON_WhiteBalance, PTP_VENDOR_CANON, 12, N_("Custom Whitebalance PC-3")},
5627 {PTP_DPC_CANON_WhiteBalance, PTP_VENDOR_CANON, 13, N_("Missing Number")},
5628 {PTP_DPC_CANON_WhiteBalance, PTP_VENDOR_CANON, 14, N_("Fluorescent H")}, /* dup? */
5629
5630 {PTP_DPC_CANON_SlowShutterSetting, PTP_VENDOR_CANON, 0, N_("Off")},
5631 {PTP_DPC_CANON_SlowShutterSetting, PTP_VENDOR_CANON, 1, N_("Night View")},
5632 {PTP_DPC_CANON_SlowShutterSetting, PTP_VENDOR_CANON, 2, N_("On")},
5633 {PTP_DPC_CANON_SlowShutterSetting, PTP_VENDOR_CANON, 3, N_("Low-speed shutter function not available")},
5634
5635 {PTP_DPC_CANON_AFMode, PTP_VENDOR_CANON, 0, N_("Single Shot")},
5636 {PTP_DPC_CANON_AFMode, PTP_VENDOR_CANON, 1, N_("AI Servo")},
5637 {PTP_DPC_CANON_AFMode, PTP_VENDOR_CANON, 2, N_("AI Focus")},
5638 {PTP_DPC_CANON_AFMode, PTP_VENDOR_CANON, 3, N_("Manual")},
5639 {PTP_DPC_CANON_AFMode, PTP_VENDOR_CANON, 4, N_("Continuous")},
5640
5641 PTP_VENDOR_VAL_BOOL(PTP_DPC_CANON_ImageStabilization,PTP_VENDOR_CANON),
5642
5643 {PTP_DPC_CANON_Contrast, PTP_VENDOR_CANON, -2, N_("Low 2")},
5644 {PTP_DPC_CANON_Contrast, PTP_VENDOR_CANON, -1, N_("Low")},
5645 {PTP_DPC_CANON_Contrast, PTP_VENDOR_CANON, 0, N_("Standard")},
5646 {PTP_DPC_CANON_Contrast, PTP_VENDOR_CANON, 1, N_("High")},
5647 {PTP_DPC_CANON_Contrast, PTP_VENDOR_CANON, 2, N_("High 2")},
5648
5649 {PTP_DPC_CANON_ColorGain, PTP_VENDOR_CANON, -2, N_("Low 2")},
5650 {PTP_DPC_CANON_ColorGain, PTP_VENDOR_CANON, -1, N_("Low")},
5651 {PTP_DPC_CANON_ColorGain, PTP_VENDOR_CANON, 0, N_("Standard")},
5652 {PTP_DPC_CANON_ColorGain, PTP_VENDOR_CANON, 1, N_("High")},
5653 {PTP_DPC_CANON_ColorGain, PTP_VENDOR_CANON, 2, N_("High 2")},
5654
5655 {PTP_DPC_CANON_Sharpness, PTP_VENDOR_CANON, -2, N_("Low 2")},
5656 {PTP_DPC_CANON_Sharpness, PTP_VENDOR_CANON, -1, N_("Low")},
5657 {PTP_DPC_CANON_Sharpness, PTP_VENDOR_CANON, 0, N_("Standard")},
5658 {PTP_DPC_CANON_Sharpness, PTP_VENDOR_CANON, 1, N_("High")},
5659 {PTP_DPC_CANON_Sharpness, PTP_VENDOR_CANON, 2, N_("High 2")},
5660
5661 {PTP_DPC_CANON_Sensitivity, PTP_VENDOR_CANON, 0, N_("Standard")},
5662 {PTP_DPC_CANON_Sensitivity, PTP_VENDOR_CANON, 1, N_("Upper 1")},
5663 {PTP_DPC_CANON_Sensitivity, PTP_VENDOR_CANON, 2, N_("Upper 2")},
5664
5665 {PTP_DPC_CANON_ParameterSet, PTP_VENDOR_CANON, 0x08, N_("Standard Development Parameters")},
5666 {PTP_DPC_CANON_ParameterSet, PTP_VENDOR_CANON, 0x10, N_("Development Parameters 1")},
5667 {PTP_DPC_CANON_ParameterSet, PTP_VENDOR_CANON, 0x20, N_("Development Parameters 2")},
5668 {PTP_DPC_CANON_ParameterSet, PTP_VENDOR_CANON, 0x40, N_("Development Parameters 3")},
5669
5670 {PTP_DPC_CANON_ISOSpeed, PTP_VENDOR_CANON, 0x00, N_("Auto")},
5671 {PTP_DPC_CANON_ISOSpeed, PTP_VENDOR_CANON, 0x28, "6"},
5672 {PTP_DPC_CANON_ISOSpeed, PTP_VENDOR_CANON, 0x30, "12"},
5673 {PTP_DPC_CANON_ISOSpeed, PTP_VENDOR_CANON, 0x38, "25"},
5674 {PTP_DPC_CANON_ISOSpeed, PTP_VENDOR_CANON, 0x40, "50"},
5675 {PTP_DPC_CANON_ISOSpeed, PTP_VENDOR_CANON, 0x43, "64"},
5676 {PTP_DPC_CANON_ISOSpeed, PTP_VENDOR_CANON, 0x48, "100"},
5677 {PTP_DPC_CANON_ISOSpeed, PTP_VENDOR_CANON, 0x50, "200"},
5678 {PTP_DPC_CANON_ISOSpeed, PTP_VENDOR_CANON, 0x58, "400"},
5679 {PTP_DPC_CANON_ISOSpeed, PTP_VENDOR_CANON, 0x60, "800"},
5680 {PTP_DPC_CANON_ISOSpeed, PTP_VENDOR_CANON, 0x68, "1600"},
5681 {PTP_DPC_CANON_ISOSpeed, PTP_VENDOR_CANON, 0x70, "3200"},
5682 {PTP_DPC_CANON_ISOSpeed, PTP_VENDOR_CANON, 0x78, "6400"},
5683
5684 /* 0xd01d - PTP_DPC_CANON_Aperture */
5685 /* 0xd01e - PTP_DPC_CANON_ShutterSpeed */
5686 /* 0xd01f - PTP_DPC_CANON_ExpCompensation */
5687 /* 0xd020 - PTP_DPC_CANON_FlashCompensation */
5688 /* 0xd021 - PTP_DPC_CANON_AEBExposureCompensation */
5689 /* 0xd023 - PTP_DPC_CANON_AvOpen */
5690 /* 0xd024 - PTP_DPC_CANON_AvMax */
5691
5692 {PTP_DPC_CANON_CameraOutput, PTP_VENDOR_CANON, 0, N_("Undefined")},
5693 {PTP_DPC_CANON_CameraOutput, PTP_VENDOR_CANON, 1, N_("LCD")},
5694 {PTP_DPC_CANON_CameraOutput, PTP_VENDOR_CANON, 2, N_("Video OUT")},
5695 {PTP_DPC_CANON_CameraOutput, PTP_VENDOR_CANON, 3, N_("Off")},
5696
5697 {PTP_DPC_CANON_MlSpotPos, PTP_VENDOR_CANON, 0, N_("MlSpotPosCenter")},
5698 {PTP_DPC_CANON_MlSpotPos, PTP_VENDOR_CANON, 1, N_("MlSpotPosAfLink")},
5699
5700 {PTP_DPC_CANON_PhotoEffect, PTP_VENDOR_CANON, 0, N_("Off")},
5701 {PTP_DPC_CANON_PhotoEffect, PTP_VENDOR_CANON, 1, N_("Vivid")},
5702 {PTP_DPC_CANON_PhotoEffect, PTP_VENDOR_CANON, 2, N_("Neutral")},
5703 {PTP_DPC_CANON_PhotoEffect, PTP_VENDOR_CANON, 3, N_("Soft")},
5704 {PTP_DPC_CANON_PhotoEffect, PTP_VENDOR_CANON, 4, N_("Sepia")},
5705 {PTP_DPC_CANON_PhotoEffect, PTP_VENDOR_CANON, 5, N_("Monochrome")},
5706
Linus Walleijd49955b2008-11-09 17:20:00 +00005707 {0, 0, 0, NULL}
Linus Walleijb02a0662006-04-25 08:05:09 +00005708 };
Linus Walleijd49955b2008-11-09 17:20:00 +00005709 for (i=0; ptp_value_trans[i].dpc!=0; i++) {
5710 if ((ptp_value_trans[i].dpc == dpc) &&
5711 (((ptp_value_trans[i].dpc & 0xf000) == 0x5000) ||
5712 (ptp_value_trans[i].vendor == params->deviceinfo.VendorExtensionID))
5713 ) {
5714 double value = _value_to_num(&(dpd->CurrentValue), dpd->DataType);
Linus Walleijb02a0662006-04-25 08:05:09 +00005715
Linus Walleijd49955b2008-11-09 17:20:00 +00005716 return snprintf(out, length,
5717 _(ptp_value_trans[i].format),
5718 value * ptp_value_trans[i].coef +
5719 ptp_value_trans[i].bias);
5720 }
5721 }
Linus Walleijb02a0662006-04-25 08:05:09 +00005722
Linus Walleijd49955b2008-11-09 17:20:00 +00005723 kval = _value_to_num(&(dpd->CurrentValue), dpd->DataType);
5724 for (i=0; ptp_value_list[i].dpc!=0; i++) {
5725 if ((ptp_value_list[i].dpc == dpc) &&
5726 (((ptp_value_list[i].dpc & 0xf000) == 0x5000) ||
5727 (ptp_value_list[i].vendor == params->deviceinfo.VendorExtensionID)) &&
5728 (ptp_value_list[i].key==kval)
5729 ) {
5730 return snprintf(out, length, "%s", _(ptp_value_list[i].value));
5731 }
Linus Walleijb02a0662006-04-25 08:05:09 +00005732 }
Linus Walleij749282b2009-08-12 22:56:59 +00005733 if (params->deviceinfo.VendorExtensionID==PTP_VENDOR_MICROSOFT
5734 || params->deviceinfo.VendorExtensionID==PTP_VENDOR_MTP) {
Linus Walleijb02a0662006-04-25 08:05:09 +00005735 switch (dpc) {
Linus Walleij545c7792006-06-13 15:22:30 +00005736 case PTP_DPC_MTP_SynchronizationPartner:
5737 case PTP_DPC_MTP_DeviceFriendlyName:
Marcus Meissneraa7d91a2017-03-16 15:59:48 +01005738 if (dpd->DataType == PTP_DTC_STR)
5739 return snprintf(out, length, "%s", dpd->CurrentValue.str);
5740 else
5741 return snprintf(out, length, "invalid type, expected STR");
Linus Walleij545c7792006-06-13 15:22:30 +00005742 case PTP_DPC_MTP_SecureTime:
5743 case PTP_DPC_MTP_DeviceCertificate: {
Marcus Meissneraa7d91a2017-03-16 15:59:48 +01005744 if (dpd->DataType != PTP_DTC_AUINT16)
5745 return snprintf(out, length, "invalid type, expected AUINT16");
Linus Walleija823a702006-08-27 21:27:46 +00005746 /* FIXME: Convert to use unicode demux functions */
Linus Walleijb02a0662006-04-25 08:05:09 +00005747 for (i=0;(i<dpd->CurrentValue.a.count) && (i<length);i++)
5748 out[i] = dpd->CurrentValue.a.v[i].u16;
5749 if ( dpd->CurrentValue.a.count &&
5750 (dpd->CurrentValue.a.count < length)) {
5751 out[dpd->CurrentValue.a.count-1] = 0;
5752 return dpd->CurrentValue.a.count-1;
5753 } else {
5754 out[length-1] = 0;
5755 return length;
5756 }
5757 break;
5758 }
5759 default:
5760 break;
5761 }
5762 }
5763
5764 return 0;
5765}
5766
5767struct {
5768 uint16_t ofc;
5769 const char *format;
5770} ptp_ofc_trans[] = {
5771 {PTP_OFC_Undefined,"Undefined Type"},
Linus Walleij5fb47132006-12-30 15:35:48 +00005772 {PTP_OFC_Defined,"Defined Type"},
Linus Walleijb02a0662006-04-25 08:05:09 +00005773 {PTP_OFC_Association,"Association/Directory"},
5774 {PTP_OFC_Script,"Script"},
5775 {PTP_OFC_Executable,"Executable"},
5776 {PTP_OFC_Text,"Text"},
5777 {PTP_OFC_HTML,"HTML"},
5778 {PTP_OFC_DPOF,"DPOF"},
5779 {PTP_OFC_AIFF,"AIFF"},
5780 {PTP_OFC_WAV,"MS Wave"},
5781 {PTP_OFC_MP3,"MP3"},
5782 {PTP_OFC_AVI,"MS AVI"},
5783 {PTP_OFC_MPEG,"MPEG"},
5784 {PTP_OFC_ASF,"ASF"},
5785 {PTP_OFC_QT,"Apple Quicktime"},
5786 {PTP_OFC_EXIF_JPEG,"JPEG"},
5787 {PTP_OFC_TIFF_EP,"TIFF EP"},
5788 {PTP_OFC_FlashPix,"FlashPix"},
5789 {PTP_OFC_BMP,"BMP"},
5790 {PTP_OFC_CIFF,"CIFF"},
5791 {PTP_OFC_GIF,"GIF"},
5792 {PTP_OFC_JFIF,"JFIF"},
5793 {PTP_OFC_PCD,"PCD"},
5794 {PTP_OFC_PICT,"PICT"},
5795 {PTP_OFC_PNG,"PNG"},
5796 {PTP_OFC_TIFF,"TIFF"},
5797 {PTP_OFC_TIFF_IT,"TIFF_IT"},
5798 {PTP_OFC_JP2,"JP2"},
5799 {PTP_OFC_JPX,"JPX"},
Linus Walleij3bc0d7f2008-11-01 23:06:24 +00005800 {PTP_OFC_DNG,"DNG"},
Linus Walleijb02a0662006-04-25 08:05:09 +00005801};
5802
5803struct {
5804 uint16_t ofc;
5805 const char *format;
5806} ptp_ofc_mtp_trans[] = {
Linus Walleij53c5f4e2007-08-13 08:27:58 +00005807 {PTP_OFC_MTP_MediaCard,N_("Media Card")},
5808 {PTP_OFC_MTP_MediaCardGroup,N_("Media Card Group")},
Linus Walleij5fb47132006-12-30 15:35:48 +00005809 {PTP_OFC_MTP_Encounter,N_("Encounter")},
Linus Walleij53c5f4e2007-08-13 08:27:58 +00005810 {PTP_OFC_MTP_EncounterBox,N_("Encounter Box")},
Linus Walleij5fb47132006-12-30 15:35:48 +00005811 {PTP_OFC_MTP_M4A,N_("M4A")},
Linus Walleijb02a0662006-04-25 08:05:09 +00005812 {PTP_OFC_MTP_Firmware,N_("Firmware")},
Linus Walleij53c5f4e2007-08-13 08:27:58 +00005813 {PTP_OFC_MTP_WindowsImageFormat,N_("Windows Image Format")},
Linus Walleijb02a0662006-04-25 08:05:09 +00005814 {PTP_OFC_MTP_UndefinedAudio,N_("Undefined Audio")},
5815 {PTP_OFC_MTP_WMA,"WMA"},
5816 {PTP_OFC_MTP_OGG,"OGG"},
Linus Walleij5fb47132006-12-30 15:35:48 +00005817 {PTP_OFC_MTP_AAC,"AAC"},
Linus Walleijaa4b0752006-07-26 22:21:04 +00005818 {PTP_OFC_MTP_AudibleCodec,N_("Audible.com Codec")},
Linus Walleij5fb47132006-12-30 15:35:48 +00005819 {PTP_OFC_MTP_FLAC,"FLAC"},
Linus Walleij7f275362010-04-25 04:14:26 +00005820 {PTP_OFC_MTP_SamsungPlaylist,N_("Samsung Playlist")},
Linus Walleijb02a0662006-04-25 08:05:09 +00005821 {PTP_OFC_MTP_UndefinedVideo,N_("Undefined Video")},
5822 {PTP_OFC_MTP_WMV,"WMV"},
5823 {PTP_OFC_MTP_MP4,"MP4"},
Linus Walleij5fb47132006-12-30 15:35:48 +00005824 {PTP_OFC_MTP_MP2,"MP2"},
5825 {PTP_OFC_MTP_3GP,"3GP"},
Linus Walleijb02a0662006-04-25 08:05:09 +00005826 {PTP_OFC_MTP_UndefinedCollection,N_("Undefined Collection")},
5827 {PTP_OFC_MTP_AbstractMultimediaAlbum,N_("Abstract Multimedia Album")},
5828 {PTP_OFC_MTP_AbstractImageAlbum,N_("Abstract Image Album")},
5829 {PTP_OFC_MTP_AbstractAudioAlbum,N_("Abstract Audio Album")},
5830 {PTP_OFC_MTP_AbstractVideoAlbum,N_("Abstract Video Album")},
5831 {PTP_OFC_MTP_AbstractAudioVideoPlaylist,N_("Abstract Audio Video Playlist")},
5832 {PTP_OFC_MTP_AbstractContactGroup,N_("Abstract Contact Group")},
5833 {PTP_OFC_MTP_AbstractMessageFolder,N_("Abstract Message Folder")},
5834 {PTP_OFC_MTP_AbstractChapteredProduction,N_("Abstract Chaptered Production")},
Linus Walleij5fb47132006-12-30 15:35:48 +00005835 {PTP_OFC_MTP_AbstractAudioPlaylist,N_("Abstract Audio Playlist")},
5836 {PTP_OFC_MTP_AbstractVideoPlaylist,N_("Abstract Video Playlist")},
5837 {PTP_OFC_MTP_AbstractMediacast,N_("Abstract Mediacast")},
Linus Walleijb02a0662006-04-25 08:05:09 +00005838 {PTP_OFC_MTP_WPLPlaylist,N_("WPL Playlist")},
5839 {PTP_OFC_MTP_M3UPlaylist,N_("M3U Playlist")},
5840 {PTP_OFC_MTP_MPLPlaylist,N_("MPL Playlist")},
5841 {PTP_OFC_MTP_ASXPlaylist,N_("ASX Playlist")},
5842 {PTP_OFC_MTP_PLSPlaylist,N_("PLS Playlist")},
Linus Walleij53c5f4e2007-08-13 08:27:58 +00005843 {PTP_OFC_MTP_UndefinedDocument,N_("Undefined Document")},
5844 {PTP_OFC_MTP_AbstractDocument,N_("Abstract Document")},
Linus Walleij5fb47132006-12-30 15:35:48 +00005845 {PTP_OFC_MTP_XMLDocument,N_("XMLDocument")},
5846 {PTP_OFC_MTP_MSWordDocument,N_("Microsoft Word Document")},
5847 {PTP_OFC_MTP_MHTCompiledHTMLDocument,N_("MHT Compiled HTML Document")},
5848 {PTP_OFC_MTP_MSExcelSpreadsheetXLS,N_("Microsoft Excel Spreadsheet (.xls)")},
5849 {PTP_OFC_MTP_MSPowerpointPresentationPPT,N_("Microsoft Powerpoint (.ppt)")},
Linus Walleij53c5f4e2007-08-13 08:27:58 +00005850 {PTP_OFC_MTP_UndefinedMessage,N_("Undefined Message")},
5851 {PTP_OFC_MTP_AbstractMessage,N_("Abstract Message")},
5852 {PTP_OFC_MTP_UndefinedContact,N_("Undefined Contact")},
5853 {PTP_OFC_MTP_AbstractContact,N_("Abstract Contact")},
Linus Walleijb02a0662006-04-25 08:05:09 +00005854 {PTP_OFC_MTP_vCard2,N_("vCard2")},
5855 {PTP_OFC_MTP_vCard3,N_("vCard3")},
Linus Walleij53c5f4e2007-08-13 08:27:58 +00005856 {PTP_OFC_MTP_UndefinedCalendarItem,N_("Undefined Calendar Item")},
5857 {PTP_OFC_MTP_AbstractCalendarItem,N_("Abstract Calendar Item")},
Linus Walleijb02a0662006-04-25 08:05:09 +00005858 {PTP_OFC_MTP_vCalendar1,N_("vCalendar1")},
5859 {PTP_OFC_MTP_vCalendar2,N_("vCalendar2")},
5860 {PTP_OFC_MTP_UndefinedWindowsExecutable,N_("Undefined Windows Executable")},
Linus Walleij9d22ce02008-05-28 20:39:29 +00005861 {PTP_OFC_MTP_MediaCast,N_("Media Cast")},
5862 {PTP_OFC_MTP_Section,N_("Section")},
Linus Walleijb02a0662006-04-25 08:05:09 +00005863};
5864
5865int
5866ptp_render_ofc(PTPParams* params, uint16_t ofc, int spaceleft, char *txt)
5867{
Linus Walleij2ad5b722013-11-04 02:07:44 +01005868 unsigned int i;
5869
Linus Walleijb02a0662006-04-25 08:05:09 +00005870 if (!(ofc & 0x8000)) {
5871 for (i=0;i<sizeof(ptp_ofc_trans)/sizeof(ptp_ofc_trans[0]);i++)
5872 if (ofc == ptp_ofc_trans[i].ofc)
Linus Walleij1a0c3012009-07-23 23:06:58 +00005873 return snprintf(txt, spaceleft, "%s", _(ptp_ofc_trans[i].format));
Linus Walleijb02a0662006-04-25 08:05:09 +00005874 } else {
5875 switch (params->deviceinfo.VendorExtensionID) {
5876 case PTP_VENDOR_EASTMAN_KODAK:
5877 switch (ofc) {
5878 case PTP_OFC_EK_M3U:
Linus Walleijf0bf4372007-07-01 21:47:38 +00005879 return snprintf (txt, spaceleft,"M3U");
5880 default:
5881 break;
5882 }
5883 break;
5884 case PTP_VENDOR_CANON:
5885 switch (ofc) {
5886 case PTP_OFC_CANON_CRW:
5887 return snprintf (txt, spaceleft,"CRW");
Linus Walleijb02a0662006-04-25 08:05:09 +00005888 default:
5889 break;
5890 }
5891 break;
Marcus Meissneraa7d91a2017-03-16 15:59:48 +01005892 case PTP_VENDOR_SONY:
5893 switch (ofc) {
5894 case PTP_OFC_SONY_RAW:
5895 return snprintf (txt, spaceleft,"ARW");
5896 default:
5897 break;
5898 }
5899 break;
Linus Walleijb02a0662006-04-25 08:05:09 +00005900 case PTP_VENDOR_MICROSOFT:
Linus Walleij749282b2009-08-12 22:56:59 +00005901 case PTP_VENDOR_MTP:
Linus Walleijb02a0662006-04-25 08:05:09 +00005902 for (i=0;i<sizeof(ptp_ofc_mtp_trans)/sizeof(ptp_ofc_mtp_trans[0]);i++)
5903 if (ofc == ptp_ofc_mtp_trans[i].ofc)
Linus Walleij1a0c3012009-07-23 23:06:58 +00005904 return snprintf(txt, spaceleft, "%s", _(ptp_ofc_mtp_trans[i].format));
Linus Walleijb02a0662006-04-25 08:05:09 +00005905 break;
5906 default:break;
5907 }
5908 }
5909 return snprintf (txt, spaceleft,_("Unknown(%04x)"), ofc);
5910}
5911
Marcus Meissner3d692dc2016-02-21 12:34:06 +01005912typedef struct {
Linus Walleij7347d0f2006-10-23 07:23:39 +00005913 uint16_t opcode;
5914 const char *name;
Marcus Meissner3d692dc2016-02-21 12:34:06 +01005915} ptp_opcode_trans_t;
5916
5917ptp_opcode_trans_t ptp_opcode_trans[] = {
Linus Walleij7347d0f2006-10-23 07:23:39 +00005918 {PTP_OC_Undefined,N_("Undefined")},
Marcus Meissner3d692dc2016-02-21 12:34:06 +01005919 {PTP_OC_GetDeviceInfo,N_("Get device info")},
Linus Walleij7347d0f2006-10-23 07:23:39 +00005920 {PTP_OC_OpenSession,N_("Open session")},
5921 {PTP_OC_CloseSession,N_("Close session")},
5922 {PTP_OC_GetStorageIDs,N_("Get storage IDs")},
5923 {PTP_OC_GetStorageInfo,N_("Get storage info")},
5924 {PTP_OC_GetNumObjects,N_("Get number of objects")},
5925 {PTP_OC_GetObjectHandles,N_("Get object handles")},
5926 {PTP_OC_GetObjectInfo,N_("Get object info")},
5927 {PTP_OC_GetObject,N_("Get object")},
5928 {PTP_OC_GetThumb,N_("Get thumbnail")},
5929 {PTP_OC_DeleteObject,N_("Delete object")},
5930 {PTP_OC_SendObjectInfo,N_("Send object info")},
5931 {PTP_OC_SendObject,N_("Send object")},
5932 {PTP_OC_InitiateCapture,N_("Initiate capture")},
5933 {PTP_OC_FormatStore,N_("Format storage")},
5934 {PTP_OC_ResetDevice,N_("Reset device")},
5935 {PTP_OC_SelfTest,N_("Self test device")},
5936 {PTP_OC_SetObjectProtection,N_("Set object protection")},
5937 {PTP_OC_PowerDown,N_("Power down device")},
5938 {PTP_OC_GetDevicePropDesc,N_("Get device property description")},
5939 {PTP_OC_GetDevicePropValue,N_("Get device property value")},
5940 {PTP_OC_SetDevicePropValue,N_("Set device property value")},
5941 {PTP_OC_ResetDevicePropValue,N_("Reset device property value")},
5942 {PTP_OC_TerminateOpenCapture,N_("Terminate open capture")},
5943 {PTP_OC_MoveObject,N_("Move object")},
5944 {PTP_OC_CopyObject,N_("Copy object")},
5945 {PTP_OC_GetPartialObject,N_("Get partial object")},
Marcus Meissner3d692dc2016-02-21 12:34:06 +01005946 {PTP_OC_InitiateOpenCapture,N_("Initiate open capture")},
5947 /* PTP v1.1 operation codes */
5948 {PTP_OC_StartEnumHandles,N_("Start Enumerate Handles")},
5949 {PTP_OC_EnumHandles,N_("Enumerate Handles")},
5950 {PTP_OC_StopEnumHandles,N_("Stop Enumerate Handles")},
5951 {PTP_OC_GetVendorExtensionMaps,N_("Get Vendor Extension Maps")},
5952 {PTP_OC_GetVendorDeviceInfo,N_("Get Vendor Device Info")},
5953 {PTP_OC_GetResizedImageObject,N_("Get Resized Image Object")},
5954 {PTP_OC_GetFilesystemManifest,N_("Get Filesystem Manifest")},
5955 {PTP_OC_GetStreamInfo,N_("Get Stream Info")},
5956 {PTP_OC_GetStream,N_("Get Stream")},
Linus Walleij7347d0f2006-10-23 07:23:39 +00005957};
5958
Marcus Meissner3d692dc2016-02-21 12:34:06 +01005959ptp_opcode_trans_t ptp_opcode_mtp_trans[] = {
Linus Walleij7347d0f2006-10-23 07:23:39 +00005960 {PTP_OC_MTP_GetObjectPropsSupported,N_("Get object properties supported")},
5961 {PTP_OC_MTP_GetObjectPropDesc,N_("Get object property description")},
5962 {PTP_OC_MTP_GetObjectPropValue,N_("Get object property value")},
5963 {PTP_OC_MTP_SetObjectPropValue,N_("Set object property value")},
5964 {PTP_OC_MTP_GetObjPropList,N_("Get object property list")},
5965 {PTP_OC_MTP_SetObjPropList,N_("Set object property list")},
5966 {PTP_OC_MTP_GetInterdependendPropdesc,N_("Get interdependent property description")},
5967 {PTP_OC_MTP_SendObjectPropList,N_("Send object property list")},
5968 {PTP_OC_MTP_GetObjectReferences,N_("Get object references")},
5969 {PTP_OC_MTP_SetObjectReferences,N_("Set object references")},
5970 {PTP_OC_MTP_UpdateDeviceFirmware,N_("Update device firmware")},
Linus Walleij5fb47132006-12-30 15:35:48 +00005971 {PTP_OC_MTP_Skip,N_("Skip to next position in playlist")},
5972
5973 /* WMDRMPD Extensions */
5974 {PTP_OC_MTP_WMDRMPD_GetSecureTimeChallenge,N_("Get secure time challenge")},
5975 {PTP_OC_MTP_WMDRMPD_GetSecureTimeResponse,N_("Get secure time response")},
5976 {PTP_OC_MTP_WMDRMPD_SetLicenseResponse,N_("Set license response")},
5977 {PTP_OC_MTP_WMDRMPD_GetSyncList,N_("Get sync list")},
5978 {PTP_OC_MTP_WMDRMPD_SendMeterChallengeQuery,N_("Send meter challenge query")},
5979 {PTP_OC_MTP_WMDRMPD_GetMeterChallenge,N_("Get meter challenge")},
5980 {PTP_OC_MTP_WMDRMPD_SetMeterResponse,N_("Get meter response")},
5981 {PTP_OC_MTP_WMDRMPD_CleanDataStore,N_("Clean data store")},
5982 {PTP_OC_MTP_WMDRMPD_GetLicenseState,N_("Get license state")},
5983 {PTP_OC_MTP_WMDRMPD_SendWMDRMPDCommand,N_("Send WMDRM-PD Command")},
5984 {PTP_OC_MTP_WMDRMPD_SendWMDRMPDRequest,N_("Send WMDRM-PD Request")},
5985
5986 /* WMPPD Extensions */
5987 {PTP_OC_MTP_WMPPD_ReportAddedDeletedItems,N_("Report Added/Deleted Items")},
5988 {PTP_OC_MTP_WMPPD_ReportAcquiredItems,N_("Report Acquired Items")},
Linus Walleij53c5f4e2007-08-13 08:27:58 +00005989 {PTP_OC_MTP_WMPPD_PlaylistObjectPref,N_("Get transferable playlist types")},
Linus Walleij5fb47132006-12-30 15:35:48 +00005990
5991 /* WMDRMPD Extensions... these have no identifiers associated with them */
5992 {PTP_OC_MTP_WMDRMPD_SendWMDRMPDAppRequest,N_("Send WMDRM-PD Application Request")},
5993 {PTP_OC_MTP_WMDRMPD_GetWMDRMPDAppResponse,N_("Get WMDRM-PD Application Response")},
5994 {PTP_OC_MTP_WMDRMPD_EnableTrustedFilesOperations,N_("Enable trusted file operations")},
5995 {PTP_OC_MTP_WMDRMPD_DisableTrustedFilesOperations,N_("Disable trusted file operations")},
5996 {PTP_OC_MTP_WMDRMPD_EndTrustedAppSession,N_("End trusted application session")},
5997
Linus Walleijfa2d1d12007-01-01 17:08:13 +00005998 /* AAVT Extensions */
5999 {PTP_OC_MTP_AAVT_OpenMediaSession,N_("Open Media Session")},
6000 {PTP_OC_MTP_AAVT_CloseMediaSession,N_("Close Media Session")},
6001 {PTP_OC_MTP_AAVT_GetNextDataBlock,N_("Get Next Data Block")},
6002 {PTP_OC_MTP_AAVT_SetCurrentTimePosition,N_("Set Current Time Position")},
6003
Linus Walleij5fb47132006-12-30 15:35:48 +00006004 /* WMDRMND Extensions */
Linus Walleij5fb47132006-12-30 15:35:48 +00006005 {PTP_OC_MTP_WMDRMND_SendRegistrationRequest,N_("Send Registration Request")},
6006 {PTP_OC_MTP_WMDRMND_GetRegistrationResponse,N_("Get Registration Response")},
6007 {PTP_OC_MTP_WMDRMND_GetProximityChallenge,N_("Get Proximity Challenge")},
6008 {PTP_OC_MTP_WMDRMND_SendProximityResponse,N_("Send Proximity Response")},
6009 {PTP_OC_MTP_WMDRMND_SendWMDRMNDLicenseRequest,N_("Send WMDRM-ND License Request")},
6010 {PTP_OC_MTP_WMDRMND_GetWMDRMNDLicenseResponse,N_("Get WMDRM-ND License Response")},
6011
6012 /* WiFi Provisioning MTP Extension Codes (microsoft.com/WPDWCN: 1.0) */
Linus Walleija381e8a2013-03-05 21:00:06 +01006013 {PTP_OC_MTP_WPDWCN_ProcessWFCObject,N_("Process WFC Object")},
6014
6015 /* Android Direct I/O Extensions */
6016 {PTP_OC_ANDROID_GetPartialObject64,N_("Get Partial Object (64bit Offset)")},
6017 {PTP_OC_ANDROID_SendPartialObject,N_("Send Partial Object")},
6018 {PTP_OC_ANDROID_TruncateObject,N_("Truncate Object")},
6019 {PTP_OC_ANDROID_BeginEditObject,N_("Begin Edit Object")},
6020 {PTP_OC_ANDROID_EndEditObject,N_("End Edit Object")},
Linus Walleij7347d0f2006-10-23 07:23:39 +00006021};
6022
Marcus Meissner3d692dc2016-02-21 12:34:06 +01006023ptp_opcode_trans_t ptp_opcode_nikon_trans[] = {
6024 {PTP_OC_NIKON_GetProfileAllData,"PTP_OC_NIKON_GetProfileAllData"},
6025 {PTP_OC_NIKON_SendProfileData,"PTP_OC_NIKON_SendProfileData"},
6026 {PTP_OC_NIKON_DeleteProfile,"PTP_OC_NIKON_DeleteProfile"},
6027 {PTP_OC_NIKON_SetProfileData,"PTP_OC_NIKON_SetProfileData"},
6028 {PTP_OC_NIKON_AdvancedTransfer,"PTP_OC_NIKON_AdvancedTransfer"},
6029 {PTP_OC_NIKON_GetFileInfoInBlock,"PTP_OC_NIKON_GetFileInfoInBlock"},
6030 {PTP_OC_NIKON_Capture,"PTP_OC_NIKON_Capture"},
6031 {PTP_OC_NIKON_AfDrive,"PTP_OC_NIKON_AfDrive"},
6032 {PTP_OC_NIKON_SetControlMode,"PTP_OC_NIKON_SetControlMode"},
6033 {PTP_OC_NIKON_DelImageSDRAM,"PTP_OC_NIKON_DelImageSDRAM"},
6034 {PTP_OC_NIKON_GetLargeThumb,"PTP_OC_NIKON_GetLargeThumb"},
6035 {PTP_OC_NIKON_CurveDownload,"PTP_OC_NIKON_CurveDownload"},
6036 {PTP_OC_NIKON_CurveUpload,"PTP_OC_NIKON_CurveUpload"},
6037 {PTP_OC_NIKON_CheckEvent,"PTP_OC_NIKON_CheckEvent"},
6038 {PTP_OC_NIKON_DeviceReady,"PTP_OC_NIKON_DeviceReady"},
6039 {PTP_OC_NIKON_SetPreWBData,"PTP_OC_NIKON_SetPreWBData"},
6040 {PTP_OC_NIKON_GetVendorPropCodes,"PTP_OC_NIKON_GetVendorPropCodes"},
6041 {PTP_OC_NIKON_AfCaptureSDRAM,"PTP_OC_NIKON_AfCaptureSDRAM"},
6042 {PTP_OC_NIKON_GetPictCtrlData,"PTP_OC_NIKON_GetPictCtrlData"},
6043 {PTP_OC_NIKON_SetPictCtrlData,"PTP_OC_NIKON_SetPictCtrlData"},
6044 {PTP_OC_NIKON_DelCstPicCtrl,"PTP_OC_NIKON_DelCstPicCtrl"},
6045 {PTP_OC_NIKON_GetPicCtrlCapability,"PTP_OC_NIKON_GetPicCtrlCapability"},
6046 {PTP_OC_NIKON_GetPreviewImg,"PTP_OC_NIKON_GetPreviewImg"},
6047 {PTP_OC_NIKON_StartLiveView,"PTP_OC_NIKON_StartLiveView"},
6048 {PTP_OC_NIKON_EndLiveView,"PTP_OC_NIKON_EndLiveView"},
6049 {PTP_OC_NIKON_GetLiveViewImg,"PTP_OC_NIKON_GetLiveViewImg"},
6050 {PTP_OC_NIKON_MfDrive,"PTP_OC_NIKON_MfDrive"},
6051 {PTP_OC_NIKON_ChangeAfArea,"PTP_OC_NIKON_ChangeAfArea"},
6052 {PTP_OC_NIKON_AfDriveCancel,"PTP_OC_NIKON_AfDriveCancel"},
6053 {PTP_OC_NIKON_InitiateCaptureRecInMedia,"PTP_OC_NIKON_InitiateCaptureRecInMedia"},
6054 {PTP_OC_NIKON_GetVendorStorageIDs,"PTP_OC_NIKON_GetVendorStorageIDs"},
6055 {PTP_OC_NIKON_StartMovieRecInCard,"PTP_OC_NIKON_StartMovieRecInCard"},
6056 {PTP_OC_NIKON_EndMovieRec,"PTP_OC_NIKON_EndMovieRec"},
6057 {PTP_OC_NIKON_TerminateCapture,"PTP_OC_NIKON_TerminateCapture"},
6058 {PTP_OC_NIKON_GetDevicePTPIPInfo,"PTP_OC_NIKON_GetDevicePTPIPInfo"},
6059 {PTP_OC_NIKON_GetPartialObjectHiSpeed,"PTP_OC_NIKON_GetPartialObjectHiSpeed"},
6060 {PTP_OC_NIKON_GetDevicePropEx,"PTP_OC_NIKON_GetDevicePropEx"},
6061};
Linus Walleij7347d0f2006-10-23 07:23:39 +00006062
Marcus Meissner3d692dc2016-02-21 12:34:06 +01006063ptp_opcode_trans_t ptp_opcode_canon_trans[] = {
6064 {PTP_OC_CANON_GetPartialObjectInfo,"PTP_OC_CANON_GetPartialObjectInfo"},
6065 {PTP_OC_CANON_SetObjectArchive,"PTP_OC_CANON_SetObjectArchive"},
6066 {PTP_OC_CANON_KeepDeviceOn,"PTP_OC_CANON_KeepDeviceOn"},
6067 {PTP_OC_CANON_LockDeviceUI,"PTP_OC_CANON_LockDeviceUI"},
6068 {PTP_OC_CANON_UnlockDeviceUI,"PTP_OC_CANON_UnlockDeviceUI"},
6069 {PTP_OC_CANON_GetObjectHandleByName,"PTP_OC_CANON_GetObjectHandleByName"},
6070 {PTP_OC_CANON_InitiateReleaseControl,"PTP_OC_CANON_InitiateReleaseControl"},
6071 {PTP_OC_CANON_TerminateReleaseControl,"PTP_OC_CANON_TerminateReleaseControl"},
6072 {PTP_OC_CANON_TerminatePlaybackMode,"PTP_OC_CANON_TerminatePlaybackMode"},
6073 {PTP_OC_CANON_ViewfinderOn,"PTP_OC_CANON_ViewfinderOn"},
6074 {PTP_OC_CANON_ViewfinderOff,"PTP_OC_CANON_ViewfinderOff"},
6075 {PTP_OC_CANON_DoAeAfAwb,"PTP_OC_CANON_DoAeAfAwb"},
6076 {PTP_OC_CANON_GetCustomizeSpec,"PTP_OC_CANON_GetCustomizeSpec"},
6077 {PTP_OC_CANON_GetCustomizeItemInfo,"PTP_OC_CANON_GetCustomizeItemInfo"},
6078 {PTP_OC_CANON_GetCustomizeData,"PTP_OC_CANON_GetCustomizeData"},
6079 {PTP_OC_CANON_SetCustomizeData,"PTP_OC_CANON_SetCustomizeData"},
6080 {PTP_OC_CANON_GetCaptureStatus,"PTP_OC_CANON_GetCaptureStatus"},
6081 {PTP_OC_CANON_CheckEvent,"PTP_OC_CANON_CheckEvent"},
6082 {PTP_OC_CANON_FocusLock,"PTP_OC_CANON_FocusLock"},
6083 {PTP_OC_CANON_FocusUnlock,"PTP_OC_CANON_FocusUnlock"},
6084 {PTP_OC_CANON_GetLocalReleaseParam,"PTP_OC_CANON_GetLocalReleaseParam"},
6085 {PTP_OC_CANON_SetLocalReleaseParam,"PTP_OC_CANON_SetLocalReleaseParam"},
6086 {PTP_OC_CANON_AskAboutPcEvf,"PTP_OC_CANON_AskAboutPcEvf"},
6087 {PTP_OC_CANON_SendPartialObject,"PTP_OC_CANON_SendPartialObject"},
6088 {PTP_OC_CANON_InitiateCaptureInMemory,"PTP_OC_CANON_InitiateCaptureInMemory"},
6089 {PTP_OC_CANON_GetPartialObjectEx,"PTP_OC_CANON_GetPartialObjectEx"},
6090 {PTP_OC_CANON_SetObjectTime,"PTP_OC_CANON_SetObjectTime"},
6091 {PTP_OC_CANON_GetViewfinderImage,"PTP_OC_CANON_GetViewfinderImage"},
6092 {PTP_OC_CANON_GetObjectAttributes,"PTP_OC_CANON_GetObjectAttributes"},
6093 {PTP_OC_CANON_ChangeUSBProtocol,"PTP_OC_CANON_ChangeUSBProtocol"},
6094 {PTP_OC_CANON_GetChanges,"PTP_OC_CANON_GetChanges"},
6095 {PTP_OC_CANON_GetObjectInfoEx,"PTP_OC_CANON_GetObjectInfoEx"},
6096 {PTP_OC_CANON_InitiateDirectTransfer,"PTP_OC_CANON_InitiateDirectTransfer"},
6097 {PTP_OC_CANON_TerminateDirectTransfer ,"PTP_OC_CANON_TerminateDirectTransfer "},
6098 {PTP_OC_CANON_SendObjectInfoByPath ,"PTP_OC_CANON_SendObjectInfoByPath "},
6099 {PTP_OC_CANON_SendObjectByPath ,"PTP_OC_CANON_SendObjectByPath "},
6100 {PTP_OC_CANON_InitiateDirectTansferEx,"PTP_OC_CANON_InitiateDirectTansferEx"},
6101 {PTP_OC_CANON_GetAncillaryObjectHandles,"PTP_OC_CANON_GetAncillaryObjectHandles"},
6102 {PTP_OC_CANON_GetTreeInfo ,"PTP_OC_CANON_GetTreeInfo "},
6103 {PTP_OC_CANON_GetTreeSize ,"PTP_OC_CANON_GetTreeSize "},
6104 {PTP_OC_CANON_NotifyProgress ,"PTP_OC_CANON_NotifyProgress "},
6105 {PTP_OC_CANON_NotifyCancelAccepted,"PTP_OC_CANON_NotifyCancelAccepted"},
6106 {PTP_OC_CANON_902C,"PTP_OC_CANON_902C"},
6107 {PTP_OC_CANON_GetDirectory,"PTP_OC_CANON_GetDirectory"},
6108 {PTP_OC_CANON_SetPairingInfo,"PTP_OC_CANON_SetPairingInfo"},
6109 {PTP_OC_CANON_GetPairingInfo,"PTP_OC_CANON_GetPairingInfo"},
6110 {PTP_OC_CANON_DeletePairingInfo,"PTP_OC_CANON_DeletePairingInfo"},
6111 {PTP_OC_CANON_GetMACAddress,"PTP_OC_CANON_GetMACAddress"},
6112 {PTP_OC_CANON_SetDisplayMonitor,"PTP_OC_CANON_SetDisplayMonitor"},
6113 {PTP_OC_CANON_PairingComplete,"PTP_OC_CANON_PairingComplete"},
6114 {PTP_OC_CANON_GetWirelessMAXChannel,"PTP_OC_CANON_GetWirelessMAXChannel"},
6115 {PTP_OC_CANON_GetWebServiceSpec,"PTP_OC_CANON_GetWebServiceSpec"},
6116 {PTP_OC_CANON_GetWebServiceData,"PTP_OC_CANON_GetWebServiceData"},
6117 {PTP_OC_CANON_SetWebServiceData,"PTP_OC_CANON_SetWebServiceData"},
6118 {PTP_OC_CANON_GetRootCertificateSpec,"PTP_OC_CANON_GetRootCertificateSpec"},
6119 {PTP_OC_CANON_GetRootCertificateData,"PTP_OC_CANON_GetRootCertificateData"},
6120 {PTP_OC_CANON_SetRootCertificateData,"PTP_OC_CANON_SetRootCertificateData"},
6121 {PTP_OC_CANON_EOS_GetStorageIDs,"PTP_OC_CANON_EOS_GetStorageIDs"},
6122 {PTP_OC_CANON_EOS_GetStorageInfo,"PTP_OC_CANON_EOS_GetStorageInfo"},
6123 {PTP_OC_CANON_EOS_GetObjectInfo,"PTP_OC_CANON_EOS_GetObjectInfo"},
6124 {PTP_OC_CANON_EOS_GetObject,"PTP_OC_CANON_EOS_GetObject"},
6125 {PTP_OC_CANON_EOS_DeleteObject,"PTP_OC_CANON_EOS_DeleteObject"},
6126 {PTP_OC_CANON_EOS_FormatStore,"PTP_OC_CANON_EOS_FormatStore"},
6127 {PTP_OC_CANON_EOS_GetPartialObject,"PTP_OC_CANON_EOS_GetPartialObject"},
6128 {PTP_OC_CANON_EOS_GetDeviceInfoEx,"PTP_OC_CANON_EOS_GetDeviceInfoEx"},
6129 {PTP_OC_CANON_EOS_GetObjectInfoEx,"PTP_OC_CANON_EOS_GetObjectInfoEx"},
6130 {PTP_OC_CANON_EOS_GetThumbEx,"PTP_OC_CANON_EOS_GetThumbEx"},
6131 {PTP_OC_CANON_EOS_SendPartialObject,"PTP_OC_CANON_EOS_SendPartialObject"},
6132 {PTP_OC_CANON_EOS_SetObjectAttributes,"PTP_OC_CANON_EOS_SetObjectAttributes"},
6133 {PTP_OC_CANON_EOS_GetObjectTime,"PTP_OC_CANON_EOS_GetObjectTime"},
6134 {PTP_OC_CANON_EOS_SetObjectTime,"PTP_OC_CANON_EOS_SetObjectTime"},
6135 {PTP_OC_CANON_EOS_RemoteRelease,"PTP_OC_CANON_EOS_RemoteRelease"},
6136 {PTP_OC_CANON_EOS_SetDevicePropValueEx,"PTP_OC_CANON_EOS_SetDevicePropValueEx"},
6137 {PTP_OC_CANON_EOS_GetRemoteMode,"PTP_OC_CANON_EOS_GetRemoteMode"},
6138 {PTP_OC_CANON_EOS_SetRemoteMode,"PTP_OC_CANON_EOS_SetRemoteMode"},
6139 {PTP_OC_CANON_EOS_SetEventMode,"PTP_OC_CANON_EOS_SetEventMode"},
6140 {PTP_OC_CANON_EOS_GetEvent,"PTP_OC_CANON_EOS_GetEvent"},
6141 {PTP_OC_CANON_EOS_TransferComplete,"PTP_OC_CANON_EOS_TransferComplete"},
6142 {PTP_OC_CANON_EOS_CancelTransfer,"PTP_OC_CANON_EOS_CancelTransfer"},
6143 {PTP_OC_CANON_EOS_ResetTransfer,"PTP_OC_CANON_EOS_ResetTransfer"},
6144 {PTP_OC_CANON_EOS_PCHDDCapacity,"PTP_OC_CANON_EOS_PCHDDCapacity"},
6145 {PTP_OC_CANON_EOS_SetUILock,"PTP_OC_CANON_EOS_SetUILock"},
6146 {PTP_OC_CANON_EOS_ResetUILock,"PTP_OC_CANON_EOS_ResetUILock"},
6147 {PTP_OC_CANON_EOS_KeepDeviceOn,"PTP_OC_CANON_EOS_KeepDeviceOn"},
6148 {PTP_OC_CANON_EOS_SetNullPacketMode,"PTP_OC_CANON_EOS_SetNullPacketMode"},
6149 {PTP_OC_CANON_EOS_UpdateFirmware,"PTP_OC_CANON_EOS_UpdateFirmware"},
6150 {PTP_OC_CANON_EOS_TransferCompleteDT,"PTP_OC_CANON_EOS_TransferCompleteDT"},
6151 {PTP_OC_CANON_EOS_CancelTransferDT,"PTP_OC_CANON_EOS_CancelTransferDT"},
6152 {PTP_OC_CANON_EOS_SetWftProfile,"PTP_OC_CANON_EOS_SetWftProfile"},
6153 {PTP_OC_CANON_EOS_GetWftProfile,"PTP_OC_CANON_EOS_GetWftProfile"},
6154 {PTP_OC_CANON_EOS_SetProfileToWft,"PTP_OC_CANON_EOS_SetProfileToWft"},
6155 {PTP_OC_CANON_EOS_BulbStart,"PTP_OC_CANON_EOS_BulbStart"},
6156 {PTP_OC_CANON_EOS_BulbEnd,"PTP_OC_CANON_EOS_BulbEnd"},
6157 {PTP_OC_CANON_EOS_RequestDevicePropValue,"PTP_OC_CANON_EOS_RequestDevicePropValue"},
6158 {PTP_OC_CANON_EOS_RemoteReleaseOn,"PTP_OC_CANON_EOS_RemoteReleaseOn"},
6159 {PTP_OC_CANON_EOS_RemoteReleaseOff,"PTP_OC_CANON_EOS_RemoteReleaseOff"},
6160 {PTP_OC_CANON_EOS_RegistBackgroundImage,"PTP_OC_CANON_EOS_RegistBackgroundImage"},
6161 {PTP_OC_CANON_EOS_ChangePhotoStudioMode,"PTP_OC_CANON_EOS_ChangePhotoStudioMode"},
6162 {PTP_OC_CANON_EOS_GetPartialObjectEx,"PTP_OC_CANON_EOS_GetPartialObjectEx"},
6163 {PTP_OC_CANON_EOS_ResetMirrorLockupState,"PTP_OC_CANON_EOS_ResetMirrorLockupState"},
6164 {PTP_OC_CANON_EOS_PopupBuiltinFlash,"PTP_OC_CANON_EOS_PopupBuiltinFlash"},
6165 {PTP_OC_CANON_EOS_EndGetPartialObjectEx,"PTP_OC_CANON_EOS_EndGetPartialObjectEx"},
6166 {PTP_OC_CANON_EOS_MovieSelectSWOn,"PTP_OC_CANON_EOS_MovieSelectSWOn"},
6167 {PTP_OC_CANON_EOS_MovieSelectSWOff,"PTP_OC_CANON_EOS_MovieSelectSWOff"},
6168 {PTP_OC_CANON_EOS_GetCTGInfo,"PTP_OC_CANON_EOS_GetCTGInfo"},
6169 {PTP_OC_CANON_EOS_GetLensAdjust,"PTP_OC_CANON_EOS_GetLensAdjust"},
6170 {PTP_OC_CANON_EOS_SetLensAdjust,"PTP_OC_CANON_EOS_SetLensAdjust"},
6171 {PTP_OC_CANON_EOS_GetMusicInfo,"PTP_OC_CANON_EOS_GetMusicInfo"},
6172 {PTP_OC_CANON_EOS_CreateHandle,"PTP_OC_CANON_EOS_CreateHandle"},
6173 {PTP_OC_CANON_EOS_SendPartialObjectEx,"PTP_OC_CANON_EOS_SendPartialObjectEx"},
6174 {PTP_OC_CANON_EOS_EndSendPartialObjectEx,"PTP_OC_CANON_EOS_EndSendPartialObjectEx"},
6175 {PTP_OC_CANON_EOS_SetCTGInfo,"PTP_OC_CANON_EOS_SetCTGInfo"},
6176 {PTP_OC_CANON_EOS_SetRequestOLCInfoGroup,"PTP_OC_CANON_EOS_SetRequestOLCInfoGroup"},
6177 {PTP_OC_CANON_EOS_SetRequestRollingPitchingLevel,"PTP_OC_CANON_EOS_SetRequestRollingPitchingLevel"},
6178 {PTP_OC_CANON_EOS_GetCameraSupport,"PTP_OC_CANON_EOS_GetCameraSupport"},
6179 {PTP_OC_CANON_EOS_SetRating,"PTP_OC_CANON_EOS_SetRating"},
6180 {PTP_OC_CANON_EOS_RequestInnerDevelopStart,"PTP_OC_CANON_EOS_RequestInnerDevelopStart"},
6181 {PTP_OC_CANON_EOS_RequestInnerDevelopParamChange,"PTP_OC_CANON_EOS_RequestInnerDevelopParamChange"},
6182 {PTP_OC_CANON_EOS_RequestInnerDevelopEnd,"PTP_OC_CANON_EOS_RequestInnerDevelopEnd"},
6183 {PTP_OC_CANON_EOS_GpsLoggingDataMode,"PTP_OC_CANON_EOS_GpsLoggingDataMode"},
6184 {PTP_OC_CANON_EOS_GetGpsLogCurrentHandle,"PTP_OC_CANON_EOS_GetGpsLogCurrentHandle"},
6185 {PTP_OC_CANON_EOS_InitiateViewfinder,"PTP_OC_CANON_EOS_InitiateViewfinder"},
6186 {PTP_OC_CANON_EOS_TerminateViewfinder,"PTP_OC_CANON_EOS_TerminateViewfinder"},
6187 {PTP_OC_CANON_EOS_GetViewFinderData,"PTP_OC_CANON_EOS_GetViewFinderData"},
6188 {PTP_OC_CANON_EOS_DoAf,"PTP_OC_CANON_EOS_DoAf"},
6189 {PTP_OC_CANON_EOS_DriveLens,"PTP_OC_CANON_EOS_DriveLens"},
6190 {PTP_OC_CANON_EOS_DepthOfFieldPreview,"PTP_OC_CANON_EOS_DepthOfFieldPreview"},
6191 {PTP_OC_CANON_EOS_ClickWB,"PTP_OC_CANON_EOS_ClickWB"},
6192 {PTP_OC_CANON_EOS_Zoom,"PTP_OC_CANON_EOS_Zoom"},
6193 {PTP_OC_CANON_EOS_ZoomPosition,"PTP_OC_CANON_EOS_ZoomPosition"},
6194 {PTP_OC_CANON_EOS_SetLiveAfFrame,"PTP_OC_CANON_EOS_SetLiveAfFrame"},
6195 {PTP_OC_CANON_EOS_TouchAfPosition,"PTP_OC_CANON_EOS_TouchAfPosition"},
6196 {PTP_OC_CANON_EOS_SetLvPcFlavoreditMode,"PTP_OC_CANON_EOS_SetLvPcFlavoreditMode"},
6197 {PTP_OC_CANON_EOS_SetLvPcFlavoreditParam,"PTP_OC_CANON_EOS_SetLvPcFlavoreditParam"},
6198 {PTP_OC_CANON_EOS_AfCancel,"PTP_OC_CANON_EOS_AfCancel"},
6199 {PTP_OC_CANON_EOS_SetDefaultCameraSetting,"PTP_OC_CANON_EOS_SetDefaultCameraSetting"},
6200 {PTP_OC_CANON_EOS_GetAEData,"PTP_OC_CANON_EOS_GetAEData"},
6201 {PTP_OC_CANON_EOS_NotifyNetworkError,"PTP_OC_CANON_EOS_NotifyNetworkError"},
6202 {PTP_OC_CANON_EOS_AdapterTransferProgress,"PTP_OC_CANON_EOS_AdapterTransferProgress"},
6203 {PTP_OC_CANON_EOS_TransferComplete2,"PTP_OC_CANON_EOS_TransferComplete2"},
6204 {PTP_OC_CANON_EOS_CancelTransfer2,"PTP_OC_CANON_EOS_CancelTransfer2"},
6205 {PTP_OC_CANON_EOS_FAPIMessageTX,"PTP_OC_CANON_EOS_FAPIMessageTX"},
6206 {PTP_OC_CANON_EOS_FAPIMessageRX,"PTP_OC_CANON_EOS_FAPIMessageRX"},
6207};
6208
6209ptp_opcode_trans_t ptp_opcode_sony_trans[] = {
6210 {PTP_OC_SONY_SDIOConnect,"PTP_OC_SONY_SDIOConnect"},
6211 {PTP_OC_SONY_GetSDIOGetExtDeviceInfo,"PTP_OC_SONY_GetSDIOGetExtDeviceInfo"},
6212 {PTP_OC_SONY_GetDevicePropdesc,"PTP_OC_SONY_GetDevicePropdesc"},
6213 {PTP_OC_SONY_GetDevicePropertyValue,"PTP_OC_SONY_GetDevicePropertyValue"},
6214 {PTP_OC_SONY_SetControlDeviceA,"PTP_OC_SONY_SetControlDeviceA"},
6215 {PTP_OC_SONY_GetControlDeviceDesc,"PTP_OC_SONY_GetControlDeviceDesc"},
6216 {PTP_OC_SONY_SetControlDeviceB,"PTP_OC_SONY_SetControlDeviceB"},
6217 {PTP_OC_SONY_GetAllDevicePropData,"PTP_OC_SONY_GetAllDevicePropData"},
6218};
6219
Marcus Meissneraa7d91a2017-03-16 15:59:48 +01006220ptp_opcode_trans_t ptp_opcode_parrot_trans[] = {
6221 {PTP_OC_PARROT_GetSunshineValues,"PTP_OC_PARROT_GetSunshineValues"},
6222 {PTP_OC_PARROT_GetTemperatureValues,"PTP_OC_PARROT_GetTemperatureValues"},
6223 {PTP_OC_PARROT_GetAngleValues,"PTP_OC_PARROT_GetAngleValues"},
6224 {PTP_OC_PARROT_GetGpsValues,"PTP_OC_PARROT_GetGpsValues"},
6225 {PTP_OC_PARROT_GetGyroscopeValues,"PTP_OC_PARROT_GetGyroscopeValues"},
6226 {PTP_OC_PARROT_GetAccelerometerValues,"PTP_OC_PARROT_GetAccelerometerValues"},
6227 {PTP_OC_PARROT_GetMagnetometerValues,"PTP_OC_PARROT_GetMagnetometerValues"},
6228 {PTP_OC_PARROT_GetImuValues,"PTP_OC_PARROT_GetImuValues"},
6229 {PTP_OC_PARROT_GetStatusMask,"PTP_OC_PARROT_GetStatusMask"},
6230 {PTP_OC_PARROT_EjectStorage,"PTP_OC_PARROT_EjectStorage"},
6231 {PTP_OC_PARROT_StartMagnetoCalib,"PTP_OC_PARROT_StartMagnetoCalib"},
6232 {PTP_OC_PARROT_StopMagnetoCalib,"PTP_OC_PARROT_StopMagnetoCalib"},
6233 {PTP_OC_PARROT_MagnetoCalibStatus,"PTP_OC_PARROT_MagnetoCalibStatus"},
6234 {PTP_OC_PARROT_SendFirmwareUpdate,"PTP_OC_PARROT_SendFirmwareUpdate"},
6235};
6236
Marcus Meissner3d692dc2016-02-21 12:34:06 +01006237const char*
6238ptp_get_opcode_name(PTPParams* params, uint16_t opcode)
6239{
6240#define RETURN_NAME_FROM_TABLE(TABLE, OPCODE) \
6241{ \
6242 unsigned int i; \
6243 for (i=0; i<sizeof(TABLE)/sizeof(TABLE[0]); i++) \
6244 if (OPCODE == TABLE[i].opcode) \
6245 return _(TABLE[i].name); \
6246 return _("Unknown PTP_OC"); \
6247}
6248
6249 if (!(opcode & 0x8000))
6250 RETURN_NAME_FROM_TABLE(ptp_opcode_trans, opcode);
6251
6252 switch (params->deviceinfo.VendorExtensionID) {
6253 case PTP_VENDOR_MICROSOFT:
6254 case PTP_VENDOR_MTP: RETURN_NAME_FROM_TABLE(ptp_opcode_mtp_trans, opcode);
6255 case PTP_VENDOR_NIKON: RETURN_NAME_FROM_TABLE(ptp_opcode_nikon_trans, opcode);
6256 case PTP_VENDOR_CANON: RETURN_NAME_FROM_TABLE(ptp_opcode_canon_trans, opcode);
6257 case PTP_VENDOR_SONY: RETURN_NAME_FROM_TABLE(ptp_opcode_sony_trans, opcode);
Marcus Meissneraa7d91a2017-03-16 15:59:48 +01006258 case PTP_VENDOR_PARROT: RETURN_NAME_FROM_TABLE(ptp_opcode_parrot_trans, opcode);
Marcus Meissner3d692dc2016-02-21 12:34:06 +01006259 default:
6260 break;
Linus Walleij7347d0f2006-10-23 07:23:39 +00006261 }
Marcus Meissner3d692dc2016-02-21 12:34:06 +01006262#undef RETURN_NAME_FROM_TABLE
6263
6264 return _("Unknown VendorExtensionID");
Linus Walleij7347d0f2006-10-23 07:23:39 +00006265}
6266
6267
6268struct {
Linus Walleijb02a0662006-04-25 08:05:09 +00006269 uint16_t id;
6270 const char *name;
6271} ptp_opc_trans[] = {
6272 {PTP_OPC_StorageID,"StorageID"},
6273 {PTP_OPC_ObjectFormat,"ObjectFormat"},
6274 {PTP_OPC_ProtectionStatus,"ProtectionStatus"},
6275 {PTP_OPC_ObjectSize,"ObjectSize"},
6276 {PTP_OPC_AssociationType,"AssociationType"},
6277 {PTP_OPC_AssociationDesc,"AssociationDesc"},
6278 {PTP_OPC_ObjectFileName,"ObjectFileName"},
6279 {PTP_OPC_DateCreated,"DateCreated"},
6280 {PTP_OPC_DateModified,"DateModified"},
6281 {PTP_OPC_Keywords,"Keywords"},
6282 {PTP_OPC_ParentObject,"ParentObject"},
Linus Walleij5fb47132006-12-30 15:35:48 +00006283 {PTP_OPC_AllowedFolderContents,"AllowedFolderContents"},
6284 {PTP_OPC_Hidden,"Hidden"},
6285 {PTP_OPC_SystemObject,"SystemObject"},
Linus Walleijb02a0662006-04-25 08:05:09 +00006286 {PTP_OPC_PersistantUniqueObjectIdentifier,"PersistantUniqueObjectIdentifier"},
6287 {PTP_OPC_SyncID,"SyncID"},
6288 {PTP_OPC_PropertyBag,"PropertyBag"},
6289 {PTP_OPC_Name,"Name"},
6290 {PTP_OPC_CreatedBy,"CreatedBy"},
6291 {PTP_OPC_Artist,"Artist"},
6292 {PTP_OPC_DateAuthored,"DateAuthored"},
6293 {PTP_OPC_Description,"Description"},
6294 {PTP_OPC_URLReference,"URLReference"},
6295 {PTP_OPC_LanguageLocale,"LanguageLocale"},
6296 {PTP_OPC_CopyrightInformation,"CopyrightInformation"},
6297 {PTP_OPC_Source,"Source"},
6298 {PTP_OPC_OriginLocation,"OriginLocation"},
6299 {PTP_OPC_DateAdded,"DateAdded"},
6300 {PTP_OPC_NonConsumable,"NonConsumable"},
6301 {PTP_OPC_CorruptOrUnplayable,"CorruptOrUnplayable"},
Linus Walleij5fb47132006-12-30 15:35:48 +00006302 {PTP_OPC_ProducerSerialNumber,"ProducerSerialNumber"},
Linus Walleijb02a0662006-04-25 08:05:09 +00006303 {PTP_OPC_RepresentativeSampleFormat,"RepresentativeSampleFormat"},
6304 {PTP_OPC_RepresentativeSampleSize,"RepresentativeSampleSize"},
6305 {PTP_OPC_RepresentativeSampleHeight,"RepresentativeSampleHeight"},
6306 {PTP_OPC_RepresentativeSampleWidth,"RepresentativeSampleWidth"},
6307 {PTP_OPC_RepresentativeSampleDuration,"RepresentativeSampleDuration"},
6308 {PTP_OPC_RepresentativeSampleData,"RepresentativeSampleData"},
6309 {PTP_OPC_Width,"Width"},
6310 {PTP_OPC_Height,"Height"},
6311 {PTP_OPC_Duration,"Duration"},
6312 {PTP_OPC_Rating,"Rating"},
6313 {PTP_OPC_Track,"Track"},
6314 {PTP_OPC_Genre,"Genre"},
6315 {PTP_OPC_Credits,"Credits"},
6316 {PTP_OPC_Lyrics,"Lyrics"},
6317 {PTP_OPC_SubscriptionContentID,"SubscriptionContentID"},
6318 {PTP_OPC_ProducedBy,"ProducedBy"},
6319 {PTP_OPC_UseCount,"UseCount"},
6320 {PTP_OPC_SkipCount,"SkipCount"},
6321 {PTP_OPC_LastAccessed,"LastAccessed"},
6322 {PTP_OPC_ParentalRating,"ParentalRating"},
6323 {PTP_OPC_MetaGenre,"MetaGenre"},
6324 {PTP_OPC_Composer,"Composer"},
6325 {PTP_OPC_EffectiveRating,"EffectiveRating"},
6326 {PTP_OPC_Subtitle,"Subtitle"},
6327 {PTP_OPC_OriginalReleaseDate,"OriginalReleaseDate"},
6328 {PTP_OPC_AlbumName,"AlbumName"},
6329 {PTP_OPC_AlbumArtist,"AlbumArtist"},
6330 {PTP_OPC_Mood,"Mood"},
6331 {PTP_OPC_DRMStatus,"DRMStatus"},
6332 {PTP_OPC_SubDescription,"SubDescription"},
6333 {PTP_OPC_IsCropped,"IsCropped"},
6334 {PTP_OPC_IsColorCorrected,"IsColorCorrected"},
Linus Walleij5fb47132006-12-30 15:35:48 +00006335 {PTP_OPC_ImageBitDepth,"ImageBitDepth"},
6336 {PTP_OPC_Fnumber,"Fnumber"},
6337 {PTP_OPC_ExposureTime,"ExposureTime"},
6338 {PTP_OPC_ExposureIndex,"ExposureIndex"},
6339 {PTP_OPC_DisplayName,"DisplayName"},
6340 {PTP_OPC_BodyText,"BodyText"},
6341 {PTP_OPC_Subject,"Subject"},
Linus Walleij0b89a7e2007-10-30 22:21:15 +00006342 {PTP_OPC_Priority,"Priority"},
Linus Walleij5fb47132006-12-30 15:35:48 +00006343 {PTP_OPC_GivenName,"GivenName"},
6344 {PTP_OPC_MiddleNames,"MiddleNames"},
6345 {PTP_OPC_FamilyName,"FamilyName"},
6346
6347 {PTP_OPC_Prefix,"Prefix"},
6348 {PTP_OPC_Suffix,"Suffix"},
6349 {PTP_OPC_PhoneticGivenName,"PhoneticGivenName"},
6350 {PTP_OPC_PhoneticFamilyName,"PhoneticFamilyName"},
6351 {PTP_OPC_EmailPrimary,"EmailPrimary"},
6352 {PTP_OPC_EmailPersonal1,"EmailPersonal1"},
6353 {PTP_OPC_EmailPersonal2,"EmailPersonal2"},
6354 {PTP_OPC_EmailBusiness1,"EmailBusiness1"},
6355 {PTP_OPC_EmailBusiness2,"EmailBusiness2"},
6356 {PTP_OPC_EmailOthers,"EmailOthers"},
6357 {PTP_OPC_PhoneNumberPrimary,"PhoneNumberPrimary"},
6358 {PTP_OPC_PhoneNumberPersonal,"PhoneNumberPersonal"},
6359 {PTP_OPC_PhoneNumberPersonal2,"PhoneNumberPersonal2"},
6360 {PTP_OPC_PhoneNumberBusiness,"PhoneNumberBusiness"},
6361 {PTP_OPC_PhoneNumberBusiness2,"PhoneNumberBusiness2"},
6362 {PTP_OPC_PhoneNumberMobile,"PhoneNumberMobile"},
6363 {PTP_OPC_PhoneNumberMobile2,"PhoneNumberMobile2"},
6364 {PTP_OPC_FaxNumberPrimary,"FaxNumberPrimary"},
6365 {PTP_OPC_FaxNumberPersonal,"FaxNumberPersonal"},
6366 {PTP_OPC_FaxNumberBusiness,"FaxNumberBusiness"},
6367 {PTP_OPC_PagerNumber,"PagerNumber"},
6368 {PTP_OPC_PhoneNumberOthers,"PhoneNumberOthers"},
6369 {PTP_OPC_PrimaryWebAddress,"PrimaryWebAddress"},
6370 {PTP_OPC_PersonalWebAddress,"PersonalWebAddress"},
6371 {PTP_OPC_BusinessWebAddress,"BusinessWebAddress"},
6372 {PTP_OPC_InstantMessengerAddress,"InstantMessengerAddress"},
6373 {PTP_OPC_InstantMessengerAddress2,"InstantMessengerAddress2"},
6374 {PTP_OPC_InstantMessengerAddress3,"InstantMessengerAddress3"},
6375 {PTP_OPC_PostalAddressPersonalFull,"PostalAddressPersonalFull"},
6376 {PTP_OPC_PostalAddressPersonalFullLine1,"PostalAddressPersonalFullLine1"},
6377 {PTP_OPC_PostalAddressPersonalFullLine2,"PostalAddressPersonalFullLine2"},
6378 {PTP_OPC_PostalAddressPersonalFullCity,"PostalAddressPersonalFullCity"},
6379 {PTP_OPC_PostalAddressPersonalFullRegion,"PostalAddressPersonalFullRegion"},
6380 {PTP_OPC_PostalAddressPersonalFullPostalCode,"PostalAddressPersonalFullPostalCode"},
6381 {PTP_OPC_PostalAddressPersonalFullCountry,"PostalAddressPersonalFullCountry"},
6382 {PTP_OPC_PostalAddressBusinessFull,"PostalAddressBusinessFull"},
6383 {PTP_OPC_PostalAddressBusinessLine1,"PostalAddressBusinessLine1"},
6384 {PTP_OPC_PostalAddressBusinessLine2,"PostalAddressBusinessLine2"},
6385 {PTP_OPC_PostalAddressBusinessCity,"PostalAddressBusinessCity"},
6386 {PTP_OPC_PostalAddressBusinessRegion,"PostalAddressBusinessRegion"},
6387 {PTP_OPC_PostalAddressBusinessPostalCode,"PostalAddressBusinessPostalCode"},
6388 {PTP_OPC_PostalAddressBusinessCountry,"PostalAddressBusinessCountry"},
6389 {PTP_OPC_PostalAddressOtherFull,"PostalAddressOtherFull"},
6390 {PTP_OPC_PostalAddressOtherLine1,"PostalAddressOtherLine1"},
6391 {PTP_OPC_PostalAddressOtherLine2,"PostalAddressOtherLine2"},
6392 {PTP_OPC_PostalAddressOtherCity,"PostalAddressOtherCity"},
6393 {PTP_OPC_PostalAddressOtherRegion,"PostalAddressOtherRegion"},
6394 {PTP_OPC_PostalAddressOtherPostalCode,"PostalAddressOtherPostalCode"},
6395 {PTP_OPC_PostalAddressOtherCountry,"PostalAddressOtherCountry"},
6396 {PTP_OPC_OrganizationName,"OrganizationName"},
6397 {PTP_OPC_PhoneticOrganizationName,"PhoneticOrganizationName"},
6398 {PTP_OPC_Role,"Role"},
6399 {PTP_OPC_Birthdate,"Birthdate"},
6400 {PTP_OPC_MessageTo,"MessageTo"},
6401 {PTP_OPC_MessageCC,"MessageCC"},
6402 {PTP_OPC_MessageBCC,"MessageBCC"},
6403 {PTP_OPC_MessageRead,"MessageRead"},
6404 {PTP_OPC_MessageReceivedTime,"MessageReceivedTime"},
6405 {PTP_OPC_MessageSender,"MessageSender"},
6406 {PTP_OPC_ActivityBeginTime,"ActivityBeginTime"},
6407 {PTP_OPC_ActivityEndTime,"ActivityEndTime"},
6408 {PTP_OPC_ActivityLocation,"ActivityLocation"},
6409 {PTP_OPC_ActivityRequiredAttendees,"ActivityRequiredAttendees"},
6410 {PTP_OPC_ActivityOptionalAttendees,"ActivityOptionalAttendees"},
6411 {PTP_OPC_ActivityResources,"ActivityResources"},
6412 {PTP_OPC_ActivityAccepted,"ActivityAccepted"},
6413 {PTP_OPC_Owner,"Owner"},
6414 {PTP_OPC_Editor,"Editor"},
6415 {PTP_OPC_Webmaster,"Webmaster"},
6416 {PTP_OPC_URLSource,"URLSource"},
6417 {PTP_OPC_URLDestination,"URLDestination"},
6418 {PTP_OPC_TimeBookmark,"TimeBookmark"},
6419 {PTP_OPC_ObjectBookmark,"ObjectBookmark"},
6420 {PTP_OPC_ByteBookmark,"ByteBookmark"},
6421 {PTP_OPC_LastBuildDate,"LastBuildDate"},
6422 {PTP_OPC_TimetoLive,"TimetoLive"},
6423 {PTP_OPC_MediaGUID,"MediaGUID"},
Linus Walleijb02a0662006-04-25 08:05:09 +00006424 {PTP_OPC_TotalBitRate,"TotalBitRate"},
6425 {PTP_OPC_BitRateType,"BitRateType"},
6426 {PTP_OPC_SampleRate,"SampleRate"},
6427 {PTP_OPC_NumberOfChannels,"NumberOfChannels"},
6428 {PTP_OPC_AudioBitDepth,"AudioBitDepth"},
6429 {PTP_OPC_ScanDepth,"ScanDepth"},
6430 {PTP_OPC_AudioWAVECodec,"AudioWAVECodec"},
6431 {PTP_OPC_AudioBitRate,"AudioBitRate"},
6432 {PTP_OPC_VideoFourCCCodec,"VideoFourCCCodec"},
6433 {PTP_OPC_VideoBitRate,"VideoBitRate"},
6434 {PTP_OPC_FramesPerThousandSeconds,"FramesPerThousandSeconds"},
6435 {PTP_OPC_KeyFrameDistance,"KeyFrameDistance"},
6436 {PTP_OPC_BufferSize,"BufferSize"},
6437 {PTP_OPC_EncodingQuality,"EncodingQuality"},
Linus Walleij15af8532007-01-07 12:45:20 +00006438 {PTP_OPC_EncodingProfile,"EncodingProfile"},
rreardon32b33052006-12-13 10:57:48 +00006439 {PTP_OPC_BuyFlag,"BuyFlag"},
Linus Walleijb02a0662006-04-25 08:05:09 +00006440};
6441
6442int
Marcus Meissner3d692dc2016-02-21 12:34:06 +01006443ptp_render_mtp_propname(uint16_t propid, int spaceleft, char *txt)
6444{
Linus Walleij2ad5b722013-11-04 02:07:44 +01006445 unsigned int i;
Linus Walleijb02a0662006-04-25 08:05:09 +00006446 for (i=0;i<sizeof(ptp_opc_trans)/sizeof(ptp_opc_trans[0]);i++)
6447 if (propid == ptp_opc_trans[i].id)
Linus Walleij1a0c3012009-07-23 23:06:58 +00006448 return snprintf(txt, spaceleft, "%s", ptp_opc_trans[i].name);
Linus Walleijb02a0662006-04-25 08:05:09 +00006449 return snprintf (txt, spaceleft,"unknown(%04x)", propid);
6450}
Linus Walleija6d0d482007-10-31 08:54:56 +00006451
6452/*
6453 * Allocate and default-initialize a few object properties.
6454 */
6455MTPProperties *
Marcus Meissner3d692dc2016-02-21 12:34:06 +01006456ptp_get_new_object_prop_entry(MTPProperties **props, int *nrofprops)
6457{
Linus Walleija6d0d482007-10-31 08:54:56 +00006458 MTPProperties *newprops;
6459 MTPProperties *prop;
6460
Marcus Meissner3d692dc2016-02-21 12:34:06 +01006461 newprops = realloc(*props,sizeof(MTPProperties)*(*nrofprops+1));
Linus Walleija6d0d482007-10-31 08:54:56 +00006462 if (newprops == NULL)
6463 return NULL;
6464 prop = &newprops[*nrofprops];
6465 prop->property = PTP_OPC_StorageID; /* Should be "unknown" */
6466 prop->datatype = PTP_DTC_UNDEF;
6467 prop->ObjectHandle = 0x00000000U;
6468 prop->propval.str = NULL;
6469
6470 (*props) = newprops;
6471 (*nrofprops)++;
6472 return prop;
6473}
6474
6475void
6476ptp_destroy_object_prop(MTPProperties *prop)
6477{
6478 if (!prop)
6479 return;
6480
6481 if (prop->datatype == PTP_DTC_STR && prop->propval.str != NULL)
6482 free(prop->propval.str);
6483 else if ((prop->datatype == PTP_DTC_AINT8 || prop->datatype == PTP_DTC_AINT16 ||
6484 prop->datatype == PTP_DTC_AINT32 || prop->datatype == PTP_DTC_AINT64 || prop->datatype == PTP_DTC_AINT128 ||
6485 prop->datatype == PTP_DTC_AUINT8 || prop->datatype == PTP_DTC_AUINT16 ||
6486 prop->datatype == PTP_DTC_AUINT32 || prop->datatype == PTP_DTC_AUINT64 || prop->datatype == PTP_DTC_AUINT128)
6487 && prop->propval.a.v != NULL)
6488 free(prop->propval.a.v);
6489}
6490
6491void
6492ptp_destroy_object_prop_list(MTPProperties *props, int nrofprops)
6493{
6494 int i;
6495 MTPProperties *prop = props;
6496
6497 for (i=0;i<nrofprops;i++,prop++)
6498 ptp_destroy_object_prop(prop);
6499 free(props);
6500}
6501
6502/*
6503 * Find a certain object property in the cache, i.e. a certain metadata
6504 * item for a certain object handle.
6505 */
6506MTPProperties *
6507ptp_find_object_prop_in_cache(PTPParams *params, uint32_t const handle, uint32_t const attribute_id)
6508{
Linus Walleij2ad5b722013-11-04 02:07:44 +01006509 unsigned int i;
Linus Walleijd4637502009-06-14 23:03:33 +00006510 MTPProperties *prop;
6511 PTPObject *ob;
6512 uint16_t ret;
6513
6514 ret = ptp_object_find (params, handle, &ob);
6515 if (ret != PTP_RC_OK)
Linus Walleija6d0d482007-10-31 08:54:56 +00006516 return NULL;
Linus Walleijd4637502009-06-14 23:03:33 +00006517 prop = ob->mtpprops;
6518 for (i=0;i<ob->nrofmtpprops;i++) {
6519 if (attribute_id == prop->property)
Linus Walleija6d0d482007-10-31 08:54:56 +00006520 return prop;
Linus Walleijd4637502009-06-14 23:03:33 +00006521 prop++;
Linus Walleija6d0d482007-10-31 08:54:56 +00006522 }
6523 return NULL;
6524}
6525
Marcus Meissner3d692dc2016-02-21 12:34:06 +01006526uint16_t
Linus Walleija6d0d482007-10-31 08:54:56 +00006527ptp_remove_object_from_cache(PTPParams *params, uint32_t handle)
6528{
Linus Walleij2ad5b722013-11-04 02:07:44 +01006529 unsigned int i;
Linus Walleijd4637502009-06-14 23:03:33 +00006530 PTPObject *ob;
Linus Walleija6d0d482007-10-31 08:54:56 +00006531
Marcus Meissner3d692dc2016-02-21 12:34:06 +01006532 CHECK_PTP_RC(ptp_object_find (params, handle, &ob));
Linus Walleijd4637502009-06-14 23:03:33 +00006533 i = ob-params->objects;
Linus Walleija6d0d482007-10-31 08:54:56 +00006534 /* remove object from object info cache */
Linus Walleijd4637502009-06-14 23:03:33 +00006535 ptp_free_object (ob);
Linus Walleij7e3b3072009-01-19 22:51:17 +00006536
Linus Walleijd4637502009-06-14 23:03:33 +00006537 if (i < params->nrofobjects-1)
Linus Walleijd1238682009-06-15 19:43:49 +00006538 memmove (ob,ob+1,(params->nrofobjects-1-i)*sizeof(PTPObject));
Linus Walleijd4637502009-06-14 23:03:33 +00006539 params->nrofobjects--;
6540 /* We use less memory than before so this shouldn't fail */
6541 params->objects = realloc(params->objects, sizeof(PTPObject)*params->nrofobjects);
Marcus Meissner3d692dc2016-02-21 12:34:06 +01006542 return PTP_RC_OK;
Linus Walleija6d0d482007-10-31 08:54:56 +00006543}
6544
Marcus Meissner3d692dc2016-02-21 12:34:06 +01006545static int _cmp_ob (const void *a, const void *b)
6546{
Linus Walleijd4637502009-06-14 23:03:33 +00006547 PTPObject *oa = (PTPObject*)a;
6548 PTPObject *ob = (PTPObject*)b;
6549
Marcus Meissneraa7d91a2017-03-16 15:59:48 +01006550 /* Do not subtract the oids and return ...
6551 * the unsigned int -> int conversion will overflow in cases
6552 * like 0xfffc0000 vs 0x0004000. */
6553 if (oa->oid > ob->oid) return 1;
6554 if (oa->oid < ob->oid) return -1;
6555 return 0;
Linus Walleijd4637502009-06-14 23:03:33 +00006556}
6557
6558void
Marcus Meissner3d692dc2016-02-21 12:34:06 +01006559ptp_objects_sort (PTPParams *params)
6560{
Linus Walleijd4637502009-06-14 23:03:33 +00006561 qsort (params->objects, params->nrofobjects, sizeof(PTPObject), _cmp_ob);
6562}
6563
6564/* Binary search in objects. Needs "objects" to be a sorted by objectid list! */
6565uint16_t
Marcus Meissner3d692dc2016-02-21 12:34:06 +01006566ptp_object_find (PTPParams *params, uint32_t handle, PTPObject **retob)
6567{
Linus Walleijd4637502009-06-14 23:03:33 +00006568 PTPObject tmpob;
6569
6570 tmpob.oid = handle;
6571 *retob = bsearch (&tmpob, params->objects, params->nrofobjects, sizeof(tmpob), _cmp_ob);
6572 if (!*retob)
6573 return PTP_RC_GeneralError;
6574 return PTP_RC_OK;
6575}
6576
6577/* Binary search in objects + insert of not found. Needs "objects" to be a sorted by objectid list! */
6578uint16_t
Marcus Meissner3d692dc2016-02-21 12:34:06 +01006579ptp_object_find_or_insert (PTPParams *params, uint32_t handle, PTPObject **retob)
6580{
Linus Walleij2ad5b722013-11-04 02:07:44 +01006581 unsigned int begin, end, cursor;
6582 unsigned int insertat;
Linus Walleijd4637502009-06-14 23:03:33 +00006583 PTPObject *newobs;
6584
6585 if (!handle) return PTP_RC_GeneralError;
6586 *retob = NULL;
6587 if (!params->nrofobjects) {
6588 params->objects = calloc(1,sizeof(PTPObject));
6589 params->nrofobjects = 1;
6590 params->objects[0].oid = handle;
6591 *retob = &params->objects[0];
6592 return PTP_RC_OK;
6593 }
6594 begin = 0;
6595 end = params->nrofobjects-1;
Linus Walleij1a0c3012009-07-23 23:06:58 +00006596 /*ptp_debug (params, "searching %08x, total=%d", handle, params->nrofobjects);*/
Linus Walleijd4637502009-06-14 23:03:33 +00006597 while (1) {
6598 cursor = (end-begin)/2+begin;
Linus Walleij1a0c3012009-07-23 23:06:58 +00006599 /*ptp_debug (params, "ob %d: %08x [%d-%d]", cursor, params->objects[cursor].oid, begin, end);*/
Linus Walleijd4637502009-06-14 23:03:33 +00006600 if (params->objects[cursor].oid == handle) {
6601 *retob = &params->objects[cursor];
6602 return PTP_RC_OK;
6603 }
6604 if (params->objects[cursor].oid < handle)
6605 begin = cursor;
6606 else
6607 end = cursor;
6608 if ((end - begin) <= 1)
6609 break;
6610 }
6611 if (params->objects[begin].oid == handle) {
6612 *retob = &params->objects[begin];
6613 return PTP_RC_OK;
6614 }
6615 if (params->objects[end].oid == handle) {
6616 *retob = &params->objects[end];
6617 return PTP_RC_OK;
6618 }
Linus Walleij1a0c3012009-07-23 23:06:58 +00006619 if ((begin == 0) && (handle < params->objects[0].oid)) {
Linus Walleijd4637502009-06-14 23:03:33 +00006620 insertat=begin;
Linus Walleij1a0c3012009-07-23 23:06:58 +00006621 } else {
6622 if ((end == params->nrofobjects-1) && (handle > params->objects[end].oid))
6623 insertat=end+1;
6624 else
6625 insertat=begin+1;
6626 }
6627 /*ptp_debug (params, "inserting oid %x at [%x,%x], begin=%d, end=%d, insertat=%d\n", handle, params->objects[begin].oid, params->objects[end].oid, begin, end, insertat);*/
Linus Walleijd4637502009-06-14 23:03:33 +00006628 newobs = realloc (params->objects, sizeof(PTPObject)*(params->nrofobjects+1));
6629 if (!newobs) return PTP_RC_GeneralError;
6630 params->objects = newobs;
Linus Walleij2ad5b722013-11-04 02:07:44 +01006631 if (insertat<params->nrofobjects)
Linus Walleijd4637502009-06-14 23:03:33 +00006632 memmove (&params->objects[insertat+1],&params->objects[insertat],(params->nrofobjects-insertat)*sizeof(PTPObject));
6633 memset(&params->objects[insertat],0,sizeof(PTPObject));
6634 params->objects[insertat].oid = handle;
6635 *retob = &params->objects[insertat];
6636 params->nrofobjects++;
6637 return PTP_RC_OK;
6638}
6639
6640uint16_t
Marcus Meissner3d692dc2016-02-21 12:34:06 +01006641ptp_object_want (PTPParams *params, uint32_t handle, unsigned int want, PTPObject **retob)
6642{
Linus Walleijd4637502009-06-14 23:03:33 +00006643 uint16_t ret;
6644 PTPObject *ob;
Linus Walleijd7072c32010-12-07 20:43:00 +00006645 /*Camera *camera = ((PTPData *)params->data)->camera;*/
Linus Walleijd4637502009-06-14 23:03:33 +00006646
Ignacio Martinez4950c022012-03-22 21:55:14 +01006647 /* If GetObjectInfo is broken, force GetPropList */
Linus Walleij6d7ea632012-04-12 08:49:33 +02006648 if (params->device_flags & DEVICE_FLAG_PROPLIST_OVERRIDES_OI)
Ignacio Martinez4950c022012-03-22 21:55:14 +01006649 want |= PTPOBJECT_MTPPROPLIST_LOADED;
6650
Linus Walleijd4637502009-06-14 23:03:33 +00006651 *retob = NULL;
6652 if (!handle) {
6653 ptp_debug (params, "ptp_object_want: querying handle 0?\n");
6654 return PTP_RC_GeneralError;
6655 }
Marcus Meissner3d692dc2016-02-21 12:34:06 +01006656 CHECK_PTP_RC(ptp_object_find_or_insert (params, handle, &ob));
Linus Walleijd4637502009-06-14 23:03:33 +00006657 *retob = ob;
6658 /* Do we have all of it already? */
6659 if ((ob->flags & want) == want)
6660 return PTP_RC_OK;
6661
Linus Walleij1a0c3012009-07-23 23:06:58 +00006662#define X (PTPOBJECT_OBJECTINFO_LOADED|PTPOBJECT_STORAGEID_LOADED|PTPOBJECT_PARENTOBJECT_LOADED)
6663 if ((want & X) && ((ob->flags & X) != X)) {
Linus Walleij749282b2009-08-12 22:56:59 +00006664 uint32_t saveparent = 0;
Linus Walleij1a0c3012009-07-23 23:06:58 +00006665
6666 /* One EOS issue, where getobjecthandles(root) returns obs without root flag. */
6667 if (ob->flags & PTPOBJECT_PARENTOBJECT_LOADED)
6668 saveparent = ob->oi.ParentObject;
6669
Linus Walleijd4637502009-06-14 23:03:33 +00006670 ret = ptp_getobjectinfo (params, handle, &ob->oi);
Linus Walleij7f275362010-04-25 04:14:26 +00006671 if (ret != PTP_RC_OK) {
6672 /* kill it from the internal list ... */
6673 ptp_remove_object_from_cache(params, handle);
Linus Walleijd4637502009-06-14 23:03:33 +00006674 return ret;
Linus Walleij7f275362010-04-25 04:14:26 +00006675 }
Linus Walleij1a0c3012009-07-23 23:06:58 +00006676 if (!ob->oi.Filename) ob->oi.Filename=strdup("<none>");
6677 if (ob->flags & PTPOBJECT_PARENTOBJECT_LOADED)
6678 ob->oi.ParentObject = saveparent;
6679
6680 /* Second EOS issue, 0x20000000 has 0x20000000 as parent */
6681 if (ob->oi.ParentObject == handle)
6682 ob->oi.ParentObject = 0;
Linus Walleij1a0c3012009-07-23 23:06:58 +00006683
Linus Walleija381e8a2013-03-05 21:00:06 +01006684 /* Read out the canon special flags */
6685 if ((params->deviceinfo.VendorExtensionID == PTP_VENDOR_CANON) &&
6686 ptp_operation_issupported(params,PTP_OC_CANON_GetObjectInfoEx)) {
6687 PTPCANONFolderEntry *ents = NULL;
6688 uint32_t numents = 0;
6689
6690 ret = ptp_canon_getobjectinfo(params,
6691 ob->oi.StorageID,0,
6692 ob->oi.ParentObject,handle,
6693 &ents,&numents
6694 );
6695 if ((ret == PTP_RC_OK) && (numents >= 1))
6696 ob->canon_flags = ents[0].Flags;
Linus Walleijd9ee8cd2013-11-04 01:54:35 +01006697 free (ents);
Linus Walleija381e8a2013-03-05 21:00:06 +01006698 }
6699
6700 ob->flags |= X;
Linus Walleijd4637502009-06-14 23:03:33 +00006701 }
Linus Walleij1a0c3012009-07-23 23:06:58 +00006702#undef X
Linus Walleijd4637502009-06-14 23:03:33 +00006703 if ( (want & PTPOBJECT_MTPPROPLIST_LOADED) &&
6704 (!(ob->flags & PTPOBJECT_MTPPROPLIST_LOADED))
6705 ) {
6706 int nrofprops = 0;
6707 MTPProperties *props = NULL;
6708
6709 if (params->device_flags & DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST) {
6710 want &= ~PTPOBJECT_MTPPROPLIST_LOADED;
6711 goto fallback;
6712 }
6713 /* Microsoft/MTP has fast directory retrieval. */
6714 if (!ptp_operation_issupported(params,PTP_OC_MTP_GetObjPropList)) {
6715 want &= ~PTPOBJECT_MTPPROPLIST_LOADED;
6716 goto fallback;
6717 }
6718
6719 ptp_debug (params, "ptp2/mtpfast: reading mtp proplist of %08x", handle);
Linus Walleij720c5482012-05-02 19:01:17 +02006720 /* We just want this one object, not all at once. */
6721 ret = ptp_mtp_getobjectproplist_single (params, handle, &props, &nrofprops);
Linus Walleijd4637502009-06-14 23:03:33 +00006722 if (ret != PTP_RC_OK)
6723 goto fallback;
6724 ob->mtpprops = props;
6725 ob->nrofmtpprops = nrofprops;
6726
Ignacio Martinez4950c022012-03-22 21:55:14 +01006727 /* Override the ObjectInfo data with data from properties */
Linus Walleij6d7ea632012-04-12 08:49:33 +02006728 if (params->device_flags & DEVICE_FLAG_PROPLIST_OVERRIDES_OI) {
Linus Walleij2ad5b722013-11-04 02:07:44 +01006729 unsigned int i;
Ignacio Martinez4950c022012-03-22 21:55:14 +01006730 MTPProperties *prop = ob->mtpprops;
6731
6732 for (i=0;i<ob->nrofmtpprops;i++,prop++) {
Linus Walleij720c5482012-05-02 19:01:17 +02006733 /* in case we got all subtree objects */
6734 if (prop->ObjectHandle != handle) continue;
6735
Ignacio Martinez4950c022012-03-22 21:55:14 +01006736 switch (prop->property) {
6737 case PTP_OPC_StorageID:
Linus Walleij96aa0e32012-03-25 12:25:25 +02006738 ob->oi.StorageID = prop->propval.u32;
6739 break;
Ignacio Martinez4950c022012-03-22 21:55:14 +01006740 case PTP_OPC_ObjectFormat:
Linus Walleij96aa0e32012-03-25 12:25:25 +02006741 ob->oi.ObjectFormat = prop->propval.u16;
6742 break;
Ignacio Martinez4950c022012-03-22 21:55:14 +01006743 case PTP_OPC_ProtectionStatus:
Linus Walleij96aa0e32012-03-25 12:25:25 +02006744 ob->oi.ProtectionStatus = prop->propval.u16;
6745 break;
Ignacio Martinez4950c022012-03-22 21:55:14 +01006746 case PTP_OPC_ObjectSize:
Linus Walleij96aa0e32012-03-25 12:25:25 +02006747 if (prop->datatype == PTP_DTC_UINT64) {
6748 if (prop->propval.u64 > 0xFFFFFFFFU)
6749 ob->oi.ObjectCompressedSize = 0xFFFFFFFFU;
6750 else
6751 ob->oi.ObjectCompressedSize = (uint32_t)prop->propval.u64;
6752 } else if (prop->datatype == PTP_DTC_UINT32) {
6753 ob->oi.ObjectCompressedSize = prop->propval.u32;
6754 }
6755 break;
Ignacio Martinez4950c022012-03-22 21:55:14 +01006756 case PTP_OPC_AssociationType:
Linus Walleij96aa0e32012-03-25 12:25:25 +02006757 ob->oi.AssociationType = prop->propval.u16;
6758 break;
Ignacio Martinez4950c022012-03-22 21:55:14 +01006759 case PTP_OPC_AssociationDesc:
Linus Walleij96aa0e32012-03-25 12:25:25 +02006760 ob->oi.AssociationDesc = prop->propval.u32;
6761 break;
Ignacio Martinez4950c022012-03-22 21:55:14 +01006762 case PTP_OPC_ObjectFileName:
Linus Walleij96aa0e32012-03-25 12:25:25 +02006763 if (prop->propval.str) {
6764 free(ob->oi.Filename);
6765 ob->oi.Filename = strdup(prop->propval.str);
6766 }
6767 break;
Ignacio Martinez4950c022012-03-22 21:55:14 +01006768 case PTP_OPC_DateCreated:
Linus Walleij96aa0e32012-03-25 12:25:25 +02006769 ob->oi.CaptureDate = ptp_unpack_PTPTIME(prop->propval.str);
6770 break;
Ignacio Martinez4950c022012-03-22 21:55:14 +01006771 case PTP_OPC_DateModified:
Linus Walleij96aa0e32012-03-25 12:25:25 +02006772 ob->oi.ModificationDate = ptp_unpack_PTPTIME(prop->propval.str);
6773 break;
Ignacio Martinez4950c022012-03-22 21:55:14 +01006774 case PTP_OPC_Keywords:
Linus Walleij96aa0e32012-03-25 12:25:25 +02006775 if (prop->propval.str) {
6776 free(ob->oi.Keywords);
6777 ob->oi.Keywords = strdup(prop->propval.str);
6778 }
6779 break;
Ignacio Martinez4950c022012-03-22 21:55:14 +01006780 case PTP_OPC_ParentObject:
Linus Walleij96aa0e32012-03-25 12:25:25 +02006781 ob->oi.ParentObject = prop->propval.u32;
6782 break;
Ignacio Martinez4950c022012-03-22 21:55:14 +01006783 }
6784 }
6785 }
6786
Linus Walleijd4637502009-06-14 23:03:33 +00006787#if 0
6788 MTPProperties *xpl;
6789 int j;
6790 PTPObjectInfo oinfo;
6791
6792 memset (&oinfo,0,sizeof(oinfo));
6793 /* hmm, not necessary ... only if we would use it */
6794 for (j=0;j<nrofprops;j++) {
6795 xpl = &props[j];
6796 switch (xpl->property) {
6797 case PTP_OPC_ParentObject:
6798 if (xpl->datatype != PTP_DTC_UINT32) {
6799 ptp_debug (params, "ptp2/mtpfast: parentobject has type 0x%x???", xpl->datatype);
6800 break;
6801 }
6802 oinfo.ParentObject = xpl->propval.u32;
6803 ptp_debug (params, "ptp2/mtpfast: parent 0x%x", xpl->propval.u32);
6804 break;
6805 case PTP_OPC_ObjectFormat:
6806 if (xpl->datatype != PTP_DTC_UINT16) {
6807 ptp_debug (params, "ptp2/mtpfast: objectformat has type 0x%x???", xpl->datatype);
6808 break;
6809 }
6810 oinfo.ObjectFormat = xpl->propval.u16;
6811 ptp_debug (params, "ptp2/mtpfast: ofc 0x%x", xpl->propval.u16);
6812 break;
6813 case PTP_OPC_ObjectSize:
6814 switch (xpl->datatype) {
6815 case PTP_DTC_UINT32:
6816 oinfo.ObjectCompressedSize = xpl->propval.u32;
6817 break;
6818 case PTP_DTC_UINT64:
6819 oinfo.ObjectCompressedSize = xpl->propval.u64;
6820 break;
6821 default:
6822 ptp_debug (params, "ptp2/mtpfast: objectsize has type 0x%x???", xpl->datatype);
6823 break;
6824 }
6825 ptp_debug (params, "ptp2/mtpfast: objectsize %u", xpl->propval.u32);
6826 break;
6827 case PTP_OPC_StorageID:
6828 if (xpl->datatype != PTP_DTC_UINT32) {
6829 ptp_debug (params, "ptp2/mtpfast: storageid has type 0x%x???", xpl->datatype);
6830 break;
6831 }
6832 oinfo.StorageID = xpl->propval.u32;
6833 ptp_debug (params, "ptp2/mtpfast: storageid 0x%x", xpl->propval.u32);
6834 break;
6835 case PTP_OPC_ProtectionStatus:/*UINT16*/
6836 if (xpl->datatype != PTP_DTC_UINT16) {
6837 ptp_debug (params, "ptp2/mtpfast: protectionstatus has type 0x%x???", xpl->datatype);
6838 break;
6839 }
6840 oinfo.ProtectionStatus = xpl->propval.u16;
6841 ptp_debug (params, "ptp2/mtpfast: protection 0x%x", xpl->propval.u16);
6842 break;
6843 case PTP_OPC_ObjectFileName:
6844 if (xpl->datatype != PTP_DTC_STR) {
6845 ptp_debug (params, "ptp2/mtpfast: filename has type 0x%x???", xpl->datatype);
6846 break;
6847 }
6848 if (xpl->propval.str) {
6849 ptp_debug (params, "ptp2/mtpfast: filename %s", xpl->propval.str);
6850 oinfo.Filename = strdup(xpl->propval.str);
6851 } else {
6852 oinfo.Filename = NULL;
6853 }
6854 break;
6855 case PTP_OPC_DateCreated:
6856 if (xpl->datatype != PTP_DTC_STR) {
6857 ptp_debug (params, "ptp2/mtpfast: datecreated has type 0x%x???", xpl->datatype);
6858 break;
6859 }
6860 ptp_debug (params, "ptp2/mtpfast: capturedate %s", xpl->propval.str);
6861 oinfo.CaptureDate = ptp_unpack_PTPTIME (xpl->propval.str);
6862 break;
6863 case PTP_OPC_DateModified:
6864 if (xpl->datatype != PTP_DTC_STR) {
6865 ptp_debug (params, "ptp2/mtpfast: datemodified has type 0x%x???", xpl->datatype);
6866 break;
6867 }
6868 ptp_debug (params, "ptp2/mtpfast: moddate %s", xpl->propval.str);
6869 oinfo.ModificationDate = ptp_unpack_PTPTIME (xpl->propval.str);
6870 break;
6871 default:
6872 if ((xpl->property & 0xfff0) == 0xdc00)
6873 ptp_debug (params, "ptp2/mtpfast:case %x type %x unhandled", xpl->property, xpl->datatype);
6874 break;
6875 }
6876 }
6877 if (!oinfo.Filename)
6878 /* i have one such file on my Creative */
6879 oinfo.Filename = strdup("<null>");
6880#endif
6881 ob->flags |= PTPOBJECT_MTPPROPLIST_LOADED;
6882fallback: ;
6883 }
6884 if ((ob->flags & want) == want)
6885 return PTP_RC_OK;
6886 ptp_debug (params, "ptp_object_want: oid 0x%08x, want flags %x, have only %x?", handle, want, ob->flags);
6887 return PTP_RC_GeneralError;
6888}
6889
6890
Linus Walleija6d0d482007-10-31 08:54:56 +00006891uint16_t
6892ptp_add_object_to_cache(PTPParams *params, uint32_t handle)
6893{
Linus Walleijd4637502009-06-14 23:03:33 +00006894 PTPObject *ob;
6895 return ptp_object_want (params, handle, PTPOBJECT_OBJECTINFO_LOADED|PTPOBJECT_MTPPROPLIST_LOADED, &ob);
Linus Walleija6d0d482007-10-31 08:54:56 +00006896}