"Fossies" - the Fresh Open Source Software Archive 
Member "libgphoto2-2.5.27/camlibs/ptp2/ptp.c" (14 Feb 2021, 341425 Bytes) of package /linux/privat/libgphoto2-2.5.27.tar.bz2:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "ptp.c" see the
Fossies "Dox" file reference documentation and the latest
Fossies "Diffs" side-by-side code changes report:
2.5.26_vs_2.5.27.
1 /* ptp.c
2 *
3 * Copyright (C) 2001-2004 Mariusz Woloszyn <emsi@ipartners.pl>
4 * Copyright (C) 2003-2019 Marcus Meissner <marcus@jet.franken.de>
5 * Copyright (C) 2006-2008 Linus Walleij <triad@df.lth.se>
6 * Copyright (C) 2007 Tero Saarni <tero.saarni@gmail.com>
7 * Copyright (C) 2009 Axel Waggershauser <awagger@web.de>
8 *
9 * 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.
13 *
14 * 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.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the
21 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 * Boston, MA 02110-1301 USA
23 */
24
25 #define _DEFAULT_SOURCE
26 #include "config.h"
27 #include "ptp.h"
28
29 #ifdef HAVE_LIBXML2
30 # include <libxml/parser.h>
31 #endif
32
33 #include <stdlib.h>
34 #include <stdarg.h>
35 #include <stdio.h>
36 #include <string.h>
37 #ifdef HAVE_UNISTD_H
38 # include <unistd.h>
39 #endif
40
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
60 #define CHECK_PTP_RC(RESULT) do { uint16_t r = (RESULT); if (r != PTP_RC_OK) return r; } while(0)
61
62 static inline void
63 ptp_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__)
83
84 static uint16_t ptp_exit_recv_memory_handler (PTPDataHandler*,unsigned char**,unsigned long*);
85 static uint16_t ptp_init_recv_memory_handler(PTPDataHandler*);
86 static uint16_t ptp_init_send_memory_handler(PTPDataHandler*,unsigned char*,unsigned long len);
87 static uint16_t ptp_exit_send_memory_handler (PTPDataHandler *handler);
88
89 void
90 ptp_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
106 void
107 ptp_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
123 /* Pack / unpack functions */
124
125 #include "ptp-pack.c"
126
127 /* 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
136 * int* recvlen - receive data length
137 *
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 being ignored (no
148 * dataphase).
149 * The memory for a pointer should be preserved by the caller, if data are
150 * being retreived the appropriate amount of memory is being 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 **/
157 uint16_t
158 ptp_transaction_new (PTPParams* params, PTPContainer* ptp,
159 uint16_t flags, uint64_t sendlen,
160 PTPDataHandler *handler
161 ) {
162 int tries;
163 uint16_t cmd;
164
165 if ((params==NULL) || (ptp==NULL))
166 return PTP_ERROR_BADPARAM;
167
168 cmd = ptp->Code;
169 ptp->Transaction_ID=params->transaction_id++;
170 ptp->SessionID=params->session_id;
171 /* send request */
172 CHECK_PTP_RC(params->sendreq_func (params, ptp, flags));
173 /* is there a dataphase? */
174 switch (flags&PTP_DP_DATA_MASK) {
175 case PTP_DP_SENDDATA:
176 {
177 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);
181 }
182 break;
183 case PTP_DP_GETDATA:
184 {
185 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);
189 }
190 break;
191 case PTP_DP_NODATA:
192 break;
193 default:
194 return PTP_ERROR_BADPARAM;
195 }
196 tries = 3;
197 while (tries--) {
198 uint16_t ret;
199 /* get response */
200 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 }
206 CHECK_PTP_RC(ret);
207
208 if (ptp->Transaction_ID < params->transaction_id-1) {
209 /* The Leica uses Transaction ID 0 on result from CloseSession. */
210 if (cmd == PTP_OC_CloseSession)
211 break;
212 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 }
219 if (ptp->Transaction_ID != params->transaction_id-1) {
220 /* try to clean up potential left overs from previous session */
221 if ((cmd == PTP_OC_OpenSession) && tries)
222 continue;
223 ptp_error (params,
224 "PTP: Sequence number mismatch %d vs expected %d.",
225 ptp->Transaction_ID, params->transaction_id-1
226 );
227 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
228 return PTP_ERROR_BADPARAM;
229 #endif
230 }
231 break;
232 }
233 return ptp->Code;
234 }
235
236 /* memory data get/put handler */
237 typedef struct {
238 unsigned char *data;
239 unsigned long size, curoff;
240 } PTPMemHandlerPrivate;
241
242 static uint16_t
243 memory_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
258 static uint16_t
259 memory_putfunc(PTPParams* params, void* private,
260 unsigned long sendlen, unsigned char *data
261 ) {
262 PTPMemHandlerPrivate* priv = (PTPMemHandlerPrivate*)private;
263
264 if (priv->curoff + sendlen > priv->size) {
265 priv->data = realloc (priv->data, priv->curoff+sendlen);
266 if (!priv->data)
267 return PTP_RC_GeneralError;
268 priv->size = priv->curoff + sendlen;
269 }
270 memcpy (priv->data + priv->curoff, data, sendlen);
271 priv->curoff += sendlen;
272 return PTP_RC_OK;
273 }
274
275 /* init private struct for receiving data. */
276 static uint16_t
277 ptp_init_recv_memory_handler(PTPDataHandler *handler)
278 {
279 PTPMemHandlerPrivate* priv;
280 priv = malloc (sizeof(PTPMemHandlerPrivate));
281 if (!priv)
282 return PTP_RC_GeneralError;
283 handler->priv = priv;
284 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 */
295 static uint16_t
296 ptp_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;
303 handler->priv = priv;
304 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 */
313 static uint16_t
314 ptp_exit_send_memory_handler (PTPDataHandler *handler)
315 {
316 PTPMemHandlerPrivate* priv = (PTPMemHandlerPrivate*)handler->priv;
317 /* data is owned by caller */
318 free (priv);
319 return PTP_RC_OK;
320 }
321
322 /* hand over our internal data to caller */
323 static uint16_t
324 ptp_exit_recv_memory_handler (PTPDataHandler *handler,
325 unsigned char **data, unsigned long *size
326 ) {
327 PTPMemHandlerPrivate* priv = (PTPMemHandlerPrivate*)handler->priv;
328 *data = priv->data;
329 *size = priv->size;
330 free (priv);
331 return PTP_RC_OK;
332 }
333
334 /* fd data get/put handler */
335 typedef struct {
336 int fd;
337 } PTPFDHandlerPrivate;
338
339 static uint16_t
340 fd_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
355 static uint16_t
356 fd_putfunc(PTPParams* params, void* private,
357 unsigned long sendlen, unsigned char *data
358 ) {
359 ssize_t written;
360 PTPFDHandlerPrivate* priv = (PTPFDHandlerPrivate*)private;
361
362 written = write (priv->fd, data, sendlen);
363 if (written != sendlen)
364 return PTP_ERROR_IO;
365 return PTP_RC_OK;
366 }
367
368 static uint16_t
369 ptp_init_fd_handler(PTPDataHandler *handler, int fd)
370 {
371 PTPFDHandlerPrivate* priv;
372 priv = malloc (sizeof(PTPFDHandlerPrivate));
373 if (!priv)
374 return PTP_RC_GeneralError;
375 handler->priv = priv;
376 handler->getfunc = fd_getfunc;
377 handler->putfunc = fd_putfunc;
378 priv->fd = fd;
379 return PTP_RC_OK;
380 }
381
382 static uint16_t
383 ptp_exit_fd_handler (PTPDataHandler *handler)
384 {
385 PTPFDHandlerPrivate* priv = (PTPFDHandlerPrivate*)handler->priv;
386 free (priv);
387 return PTP_RC_OK;
388 }
389
390 /* Old style transaction, based on memory */
391 /* 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 */
399 uint16_t
400 ptp_transaction (PTPParams* params, PTPContainer* ptp,
401 uint16_t flags, uint64_t sendlen,
402 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:
409 if (!data)
410 return PTP_ERROR_BADPARAM;
411 CHECK_PTP_RC(ptp_init_send_memory_handler (&handler, *data, sendlen));
412 break;
413 case PTP_DP_GETDATA:
414 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));
420 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);
431 if (ret != PTP_RC_OK) {
432 len = 0;
433 free(*data);
434 *data = NULL;
435 }
436 if (recvlen)
437 *recvlen = len;
438 break;
439 }
440 default:break;
441 }
442 return ret;
443 }
444
445
446 /**
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 **/
462 uint16_t
463 ptp_getdeviceinfo (PTPParams* params, PTPDeviceInfo* deviceinfo)
464 {
465 PTPContainer ptp;
466 unsigned char *data = NULL;
467 unsigned int size;
468 int ret;
469
470 PTP_CNT_INIT(ptp, PTP_OC_GetDeviceInfo);
471 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size));
472 ret = ptp_unpack_DI(params, data, deviceinfo, size);
473 free(data);
474 if (ret)
475 return PTP_RC_OK;
476 else
477 return PTP_ERROR_IO;
478 }
479
480 uint16_t
481 ptp_canon_eos_getdeviceinfo (PTPParams* params, PTPCanonEOSDeviceInfo*di)
482 {
483 PTPContainer ptp;
484 unsigned char *data = NULL;
485 unsigned int size;
486 int ret;
487
488 PTP_CNT_INIT(ptp, PTP_OC_CANON_EOS_GetDeviceInfoEx);
489 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size));
490 ret = ptp_unpack_EOS_DI(params, data, di, size);
491 free (data);
492 if (ret)
493 return PTP_RC_OK;
494 else
495 return PTP_ERROR_IO;
496 }
497
498 uint16_t
499 ptp_getstreaminfo (PTPParams *params, uint32_t streamid, PTPStreamInfo *si)
500 {
501 PTPContainer ptp;
502 unsigned char *data = NULL;
503 unsigned int size;
504 int ret;
505
506 PTP_CNT_INIT(ptp, PTP_OC_GetStreamInfo, streamid);
507 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size));
508 ret = ptp_unpack_StreamInfo(params, data, si, size);
509 free (data);
510 if (ret)
511 return PTP_RC_OK;
512 else
513 return PTP_ERROR_IO;
514 }
515
516 uint16_t
517 ptp_getstream (PTPParams *params, unsigned char **data, unsigned int *size)
518 {
519 PTPContainer ptp;
520
521 PTP_CNT_INIT(ptp, PTP_OC_GetStream);
522 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, data, size));
523 return PTP_RC_OK;
524 }
525
526 uint16_t
527 ptp_leica_getstreamdata (PTPParams *params, unsigned char **data, unsigned int *size)
528 {
529 PTPContainer ptp;
530
531 PTP_CNT_INIT(ptp, PTP_OC_LEICA_LEGetStreamData);
532 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, data, size));
533 return PTP_RC_OK;
534 }
535
536 uint16_t
537 ptp_canon_eos_905f (PTPParams* params, uint32_t x)
538 {
539 PTPContainer ptp;
540 unsigned char *data = NULL;
541 unsigned int size;
542
543 PTP_CNT_INIT(ptp, 0x905f, x);
544 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size));
545 free (data);
546 return PTP_RC_OK;
547 }
548
549 #ifdef HAVE_LIBXML2
550 static int
551 traverse_tree (PTPParams *params, int depth, xmlNodePtr node)
552 {
553 xmlNodePtr next;
554 xmlChar *xchar;
555 int n;
556 char *xx;
557
558
559 if (!node) return 0;
560 xx = malloc (depth * 4 + 1);
561 memset (xx, ' ', depth*4);
562 xx[depth*4] = 0;
563
564 n = xmlChildElementCount (node);
565
566 next = node;
567 do {
568 fprintf(stderr,"%snode %s\n", xx,next->name);
569 fprintf(stderr,"%selements %d\n", xx,n);
570 xchar = xmlNodeGetContent (next);
571 fprintf(stderr,"%scontent %s\n", xx,xchar);
572 traverse_tree (params, depth+1,xmlFirstElementChild (next));
573 } while ((next = xmlNextElementSibling (next)));
574 free (xx);
575 return PTP_RC_OK;
576 }
577
578 static int
579 parse_9301_cmd_tree (PTPParams *params, xmlNodePtr node, PTPDeviceInfo *di)
580 {
581 xmlNodePtr next;
582 int cnt;
583
584 cnt = 0;
585 next = xmlFirstElementChild (node);
586 while (next) {
587 cnt++;
588 next = xmlNextElementSibling (next);
589 }
590 di->OperationsSupported_len = cnt;
591 di->OperationsSupported = calloc (cnt,sizeof(di->OperationsSupported[0]));
592 cnt = 0;
593 next = xmlFirstElementChild (node);
594 while (next) {
595 unsigned int p;
596
597 sscanf((char*)next->name, "c%04x", &p);
598 ptp_debug( params, "cmd %s / 0x%04x", next->name, p);
599 di->OperationsSupported[cnt++] = p;
600 next = xmlNextElementSibling (next);
601 }
602 return PTP_RC_OK;
603 }
604
605 static int
606 parse_9301_value (PTPParams *params, const char *str, uint16_t type, PTPPropertyValue *propval)
607 {
608 switch (type) {
609 case 6: { /*UINT32*/
610 unsigned int x;
611 if (!sscanf(str,"%08x", &x)) {
612 ptp_debug( params, "could not parse uint32 %s", str);
613 return PTP_RC_GeneralError;
614 }
615 ptp_debug( params, "\t%d", x);
616 propval->u32 = x;
617 break;
618 }
619 case 5: { /*INT32*/
620 int x;
621 if (!sscanf(str,"%08x", &x)) {
622 ptp_debug( params, "could not parse int32 %s", str);
623 return PTP_RC_GeneralError;
624 }
625 ptp_debug( params, "\t%d", x);
626 propval->i32 = x;
627 break;
628 }
629 case 4: { /*UINT16*/
630 unsigned int x;
631 if (!sscanf(str,"%04x", &x)) {
632 ptp_debug( params, "could not parse uint16 %s", str);
633 return PTP_RC_GeneralError;
634 }
635 ptp_debug( params, "\t%d", x);
636 propval->u16 = x;
637 break;
638 }
639 case 3: { /*INT16*/
640 int x;
641 if (!sscanf(str,"%04x", &x)) {
642 ptp_debug( params, "could not parse int16 %s", str);
643 return PTP_RC_GeneralError;
644 }
645 ptp_debug( params, "\t%d", x);
646 propval->i16 = x;
647 break;
648 }
649 case 2: { /*UINT8*/
650 unsigned int x;
651 if (!sscanf(str,"%02x", &x)) {
652 ptp_debug( params, "could not parse uint8 %s", str);
653 return PTP_RC_GeneralError;
654 }
655 ptp_debug( params, "\t%d", x);
656 propval->u8 = x;
657 break;
658 }
659 case 1: { /*INT8*/
660 int x;
661 if (!sscanf(str,"%02x", &x)) {
662 ptp_debug( params, "could not parse int8 %s", str);
663 return PTP_RC_GeneralError;
664 }
665 ptp_debug( params, "\t%d", x);
666 propval->i8 = x;
667 break;
668 }
669 case 65535: { /* string */
670 int len;
671
672 /* ascii ptp string, 1 byte length, little endian 16 bit chars */
673 if (sscanf(str,"%02x", &len)) {
674 int i;
675 char *xstr = malloc(len+1);
676 for (i=0;i<len;i++) {
677 int xc;
678 if (sscanf(str+2+i*4,"%04x", &xc)) {
679 int cx;
680
681 cx = ((xc>>8) & 0xff) | ((xc & 0xff) << 8);
682 xstr[i] = cx;
683 }
684 xstr[len] = 0;
685 }
686 ptp_debug( params, "\t%s", xstr);
687 propval->str = xstr;
688 break;
689 }
690 ptp_debug( params, "string %s not parseable!", str);
691 return PTP_RC_GeneralError;
692 }
693 case 7: /*INT64*/
694 case 8: /*UINT64*/
695 case 9: /*INT128*/
696 case 10: /*UINT128*/
697 default:
698 ptp_debug( params, "unhandled data type %d!", type);
699 return PTP_RC_GeneralError;
700 }
701 return PTP_RC_OK;
702 }
703
704 static int
705 parse_9301_propdesc (PTPParams *params, xmlNodePtr next, PTPDevicePropDesc *dpd)
706 {
707 int type = -1;
708
709 if (!next)
710 return PTP_RC_GeneralError;
711
712 ptp_debug (params, "parse_9301_propdesc");
713 dpd->FormFlag = PTP_DPFF_None;
714 dpd->GetSet = PTP_DPGS_Get;
715 do {
716 if (!strcmp((char*)next->name,"type")) { /* propdesc.DataType */
717 if (!sscanf((char*)xmlNodeGetContent (next), "%04x", &type)) {
718 ptp_debug( params, "\ttype %s not parseable?",xmlNodeGetContent (next));
719 return 0;
720 }
721 ptp_debug( params, "type 0x%x", type);
722 dpd->DataType = type;
723 continue;
724 }
725 if (!strcmp((char*)next->name,"attribute")) { /* propdesc.GetSet */
726 int attr;
727
728 if (!sscanf((char*)xmlNodeGetContent (next), "%02x", &attr)) {
729 ptp_debug( params, "\tattr %s not parseable",xmlNodeGetContent (next));
730 return 0;
731 }
732 ptp_debug( params, "attribute 0x%x", attr);
733 dpd->GetSet = attr;
734 continue;
735 }
736 if (!strcmp((char*)next->name,"default")) { /* propdesc.FactoryDefaultValue */
737 ptp_debug( params, "default value");
738 parse_9301_value (params, (char*)xmlNodeGetContent (next), type, &dpd->FactoryDefaultValue);
739 continue;
740 }
741 if (!strcmp((char*)next->name,"value")) { /* propdesc.CurrentValue */
742 ptp_debug( params, "current value");
743 parse_9301_value (params, (char*)xmlNodeGetContent (next), type, &dpd->CurrentValue);
744 continue;
745 }
746 if (!strcmp((char*)next->name,"enum")) { /* propdesc.FORM.Enum */
747 int n,i;
748 char *s;
749
750 ptp_debug( params, "enum");
751 dpd->FormFlag = PTP_DPFF_Enumeration;
752 s = (char*)xmlNodeGetContent (next);
753 n = 0;
754 do {
755 s = strchr(s,' ');
756 if (s) s++;
757 n++;
758 } while (s);
759 dpd->FORM.Enum.NumberOfValues = n;
760 dpd->FORM.Enum.SupportedValue = calloc (n , sizeof(PTPPropertyValue));
761 s = (char*)xmlNodeGetContent (next);
762 i = 0;
763 do {
764 parse_9301_value (params, s, type, &dpd->FORM.Enum.SupportedValue[i]); /* should turn ' ' into \0? */
765 i++;
766 s = strchr(s,' ');
767 if (s) s++;
768 } while (s && (i<n));
769 continue;
770 }
771 if (!strcmp((char*)next->name,"range")) { /* propdesc.FORM.Enum */
772 char *s = (char*)xmlNodeGetContent (next);
773 dpd->FormFlag = PTP_DPFF_Range;
774 ptp_debug( params, "range");
775 parse_9301_value (params, s, type, &dpd->FORM.Range.MinimumValue); /* should turn ' ' into \0? */
776 s = strchr(s,' ');
777 if (!s) continue;
778 s++;
779 parse_9301_value (params, s, type, &dpd->FORM.Range.MaximumValue); /* should turn ' ' into \0? */
780 s = strchr(s,' ');
781 if (!s) continue;
782 s++;
783 parse_9301_value (params, s, type, &dpd->FORM.Range.StepSize); /* should turn ' ' into \0? */
784
785 continue;
786 }
787 ptp_debug (params, "\tpropdescvar: %s", next->name);
788 traverse_tree (params, 3, next);
789 } while ((next = xmlNextElementSibling (next)));
790 return PTP_RC_OK;
791 }
792
793 static int
794 parse_9301_prop_tree (PTPParams *params, xmlNodePtr node, PTPDeviceInfo *di)
795 {
796 xmlNodePtr next;
797 int cnt;
798 unsigned int i;
799
800 cnt = 0;
801 next = xmlFirstElementChild (node);
802 while (next) {
803 cnt++;
804 next = xmlNextElementSibling (next);
805 }
806
807 di->DevicePropertiesSupported_len = cnt;
808 di->DevicePropertiesSupported = calloc (cnt,sizeof(di->DevicePropertiesSupported[0]));
809 cnt = 0;
810 next = xmlFirstElementChild (node);
811 while (next) {
812 unsigned int p;
813 PTPDevicePropDesc dpd;
814
815 sscanf((char*)next->name, "p%04x", &p);
816 ptp_debug( params, "prop %s / 0x%04x", next->name, p);
817 parse_9301_propdesc (params, xmlFirstElementChild (next), &dpd);
818 dpd.DevicePropertyCode = p;
819 di->DevicePropertiesSupported[cnt++] = p;
820
821 /* add to cache of device propdesc */
822 for (i=0;i<params->nrofdeviceproperties;i++)
823 if (params->deviceproperties[i].desc.DevicePropertyCode == p)
824 break;
825 if (i == params->nrofdeviceproperties) {
826 params->deviceproperties = realloc(params->deviceproperties,(i+1)*sizeof(params->deviceproperties[0]));
827 memset(¶ms->deviceproperties[i],0,sizeof(params->deviceproperties[0]));
828 params->nrofdeviceproperties++;
829 } else {
830 ptp_free_devicepropdesc (¶ms->deviceproperties[i].desc);
831 }
832 /* FIXME: free old entry */
833 /* we are not using dpd, so copy it directly to the cache */
834 time( ¶ms->deviceproperties[i].timestamp);
835 params->deviceproperties[i].desc = dpd;
836
837 next = xmlNextElementSibling (next);
838 }
839 return PTP_RC_OK;
840 }
841
842 static int
843 parse_9301_event_tree (PTPParams *params, xmlNodePtr node, PTPDeviceInfo *di)
844 {
845 xmlNodePtr next;
846 int cnt;
847
848 cnt = 0;
849 next = xmlFirstElementChild (node);
850 while (next) {
851 cnt++;
852 next = xmlNextElementSibling (next);
853 }
854 di->EventsSupported_len = cnt;
855 di->EventsSupported = calloc (cnt,sizeof(di->EventsSupported[0]));
856 cnt = 0;
857 next = xmlFirstElementChild (node);
858 while (next) {
859 unsigned int p;
860
861 sscanf((char*)next->name, "e%04x", &p);
862 ptp_debug( params, "event %s / 0x%04x", next->name, p);
863 di->EventsSupported[cnt++] = p;
864 next = xmlNextElementSibling (next);
865 }
866 return PTP_RC_OK;
867 }
868
869 static int
870 parse_9301_tree (PTPParams *params, xmlNodePtr node, PTPDeviceInfo *di)
871 {
872 xmlNodePtr next;
873
874 next = xmlFirstElementChild (node);
875 while (next) {
876 if (!strcmp ((char*)next->name, "cmd")) {
877 parse_9301_cmd_tree (params, next, di);
878 next = xmlNextElementSibling (next);
879 continue;
880 }
881 if (!strcmp ((char*)next->name, "prop")) {
882 parse_9301_prop_tree (params, next, di);
883 next = xmlNextElementSibling (next);
884 continue;
885 }
886 if (!strcmp ((char*)next->name, "event")) {
887 parse_9301_event_tree (params, next, di);
888 next = xmlNextElementSibling (next);
889 continue;
890 }
891 fprintf (stderr,"9301: unhandled type %s\n", next->name);
892 next = xmlNextElementSibling (next);
893 }
894 /*traverse_tree (0, node);*/
895 return PTP_RC_OK;
896 }
897 #endif
898
899 uint16_t
900 ptp_olympus_omd_capture (PTPParams* params)
901 {
902 PTPContainer ptp;
903 uint16_t ret;
904 unsigned int size = 0;
905 unsigned char *buffer = NULL;
906
907 /* these two trigger the capture ... one might be "shutter down", the other "shutter up"? */
908 PTP_CNT_INIT(ptp, PTP_OC_OLYMPUS_OMD_Capture, 0x3); // initiate capture
909 ret = ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL);
910 PTP_CNT_INIT(ptp, PTP_OC_OLYMPUS_OMD_Capture, 0x6); // initiate capture
911 ret = ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL);
912
913 usleep(500);
914
915 /* this only fetches changed props */
916 PTP_CNT_INIT(ptp, 0x9486); /* query changed properties */
917 ret = ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &buffer, &size);
918 free (buffer);
919 return ret;
920 }
921 /**
922 * ptp_olympus_bulbstart:
923 * params: PTPParams*
924 *
925 * Starts Olympus Bulb capture.
926 *
927 * Return values: Some PTP_RC_* code.
928 **/
929 uint16_t
930 ptp_olympus_omd_bulbstart (PTPParams* params)
931 {
932 PTPContainer ptp;
933
934 PTP_CNT_INIT(ptp, PTP_OC_OLYMPUS_OMD_Capture, 0x3); // initiate capture
935 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL));
936 if ((ptp.Nparam >= 1) && ((ptp.Param1 & 0x7000) == 0x2000))
937 return ptp.Param1;
938 return PTP_RC_OK;
939 }
940
941
942 /**
943 * ptp_olympus_bulbend:
944 * params: PTPParams*
945 *
946 * Stops Olympus Bulb capture.
947 *
948 * Return values: Some PTP_RC_* code.
949 **/
950 uint16_t
951 ptp_olympus_omd_bulbend (PTPParams* params)
952 {
953 PTPContainer ptp;
954
955 PTP_CNT_INIT(ptp, PTP_OC_OLYMPUS_OMD_Capture, 0x6); // initiate capture
956 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL));
957 if ((ptp.Nparam >= 1) && ((ptp.Param1 & 0x7000) == 0x2000))
958 return ptp.Param1;
959 return PTP_RC_OK;
960 }
961
962 uint16_t
963 ptp_panasonic_liveview_image (PTPParams* params, unsigned char **data, unsigned int *size)
964 {
965 PTPContainer ptp;
966
967 PTP_CNT_INIT(ptp, PTP_OC_PANASONIC_LiveviewImage);
968 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, data, size);
969 }
970
971 uint16_t
972 ptp_olympus_init_pc_mode (PTPParams* params)
973 {
974 uint16_t ret;
975 PTPPropertyValue propval;
976 PTPContainer event;
977 int i;
978
979 ptp_debug (params,"PTP: (Olympus Init) switching to PC mode...");
980
981 propval.u16 = 1;
982 ret = ptp_setdevicepropvalue (params, 0xD052, &propval, PTP_DTC_UINT16);
983 usleep(100000);
984
985 for(i = 0; i < 2; i++) {
986 ptp_debug (params,"PTP: (Olympus Init) checking events...");
987 /* Just busy loop until the camera is ready again. */
988 ptp_check_event (params);
989 if (ptp_get_one_event(params, &event)) break;
990 usleep(100000);
991 }
992
993 /*
994 * 9489 code: sends a list of PTP device properties supported apparently? on E-M1.
995 * F4 00 00 00 count
996 02 D0 03 D0 04 D0 05 D0 06 D0 07 D0 08 D0 09 D0 0C D0 0D D0 0E D0 0F D0 10 D0 11 D0 13 D0 14 D0 18 D0 1A D0 1B D0 1C D0 1D D0 1E D0 1F D0 20 D0 21 D0 22 D0 23 D0 24 D0 25 D0 26 D0 27 D0 28 D0 29 D0 2A D0 2B D0 2C D0 2D D0 2E D0 2F D0 30 D0 31 D0 32 D0 33 D0 34 D0 35 D0 36 D0 37 D0 38 D0 39 D0 3A D0 3B D0 3C D0 3D D0 3E D0 3F D0 40 D0 41 D0 42 D0 43 D0 44 D0 45 D0 46 D0 47 D0 48 D0 49 D0 4A D0 4B D0 4C D0 4D D0 4E D0 4F D0 50 D0 51 D0 52 D0 58 D0 59 D0 5F D0 60 D0 61 D0 62 D0 64 D0 65 D0 66 D0 68 D0 69 D0 70 D0 73 D0 67 D0 5A D0 5B D0 63 D0 6A D0 6B D0 6C D0 71 D0 72 D0 7A D0 7B D0 7C D0 7D D0 7F D0 80 D0 81 D0 82 D0 86 D0 87 D0 8B D0 8C D0 8E D0 8F D0 97 D0 9F D0 C4 D0 C5 D0 A2 D0 A3 D0 A4 D0 A6 D0 A7 D0 A8 D0 A9 D0 AA D0 AB D0 AC D0 AD D0 AE D0 B2 D0 B3 D0 B4 D0 B5 D0 B6 D0 B7 D0 B8 D0 B9 D0 BA D0 BC D0 BD D0 BE D0 BF D0 C0 D0 C6 D0 C7 D0 C8 D0 C9 D0 CB D0 CC D0 CD D0 CE D0 CF D0 D0 D0 D1 D0 D2 D0 D3 D0 D4 D0 D5 D0 D6 D0 D7 D0 D8 D0 D9 D0 DA D0 DB D0 DC D0 DD D0 DE D0 E2 D0 E3 D0 E4 D0 E5 D0 E6 D0 E7 D0 E8 D0 E9 D0 EA D0 EC D0 EF D0 F0 D0 F1 D0 F2 D0 F3 D0 F4 D0 F5 D0 F6 D0 F7 D0 F8 D0 F9 D0 FA D0 FB D0 FC D0 FD D0 FE D0 FF D0 00 D1 01 D1 02 D1 03 D1 04 D1 05 D1 06 D1 07 D1 08 D1 09 D1 0A D1 0B D1 0C D1 0D D1 0E D1 0F D1 10 D1 11 D1 12 D1 13 D1 14 D1 15 D1 16 D1 17 D1 18 D1 19 D1 1A D1 1B D1 1C D1 1D D1 1E D1 1F D1 20 D1 51 D1 52 D1 5A D1 24 D1 25 D1 26 D1 27 D1 28 D1 2D D1 2E D1 2F D1 30 D1 31 D1 34 D1 35 D1 36 D1 37 D1 38 D1 39 D1 3A D1
997 *
998 * 9486: queries something. gets 00 00 00 00 ... or list of devicepropdesc in standard ptp propdesc format.
999 * could be some form of "properties changed" query perhaps? (32bit count in front)
1000 * might only monitor/return properties set by 9489?
1001 *
1002 * 948a: seems also be some kind of polling function, returns 32bit 0 if nothing is there. similar to above?
1003 * returns properties sent by 94b8.
1004 *
1005 * 948b: also sends a list of ptp devprops:
1006 * 11 00 00 00 53 D0 54 D0 55 D0 56 D0 57 D0 6D D0 5C D0 5D D0 5E D0 74 D0 75 D0 83 D0 84 D0 85 D0 ED D0 79 D0 E1 D0
1007 * Events: c008: 21 D1 00 00 0F 00 00 00 01 00 00 00
1008 */
1009 //ptp_debug (params,"PTP: (Olympus Init) getting response...");
1010 //gp_port_set_timeout (camera->port, timeout);
1011 //ret=ptp_transaction(params, &ptp, PTP_DP_RESPONSEONLY, size, &data, NULL);
1012 //if(data) free(data);
1013 return ret;
1014 }
1015
1016 uint16_t
1017 ptp_olympus_liveview_image (PTPParams* params, unsigned char **data, unsigned int *size)
1018 {
1019 PTPContainer ptp;
1020 uint32_t param1 = 1;
1021
1022 PTP_CNT_INIT(ptp, PTP_OC_OLYMPUS_GetLiveViewImage, param1);
1023 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, data, size);
1024 }
1025
1026 uint16_t
1027 ptp_olympus_sdram_image (PTPParams* params, unsigned char **data, unsigned int *size)
1028 {
1029 PTPContainer ptp;
1030
1031 PTP_CNT_INIT(ptp, PTP_OC_OLYMPUS_OMD_GetImage);
1032 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, data, size);
1033 }
1034
1035 uint16_t
1036 ptp_panasonic_9401 (PTPParams* params, uint32_t param1)
1037 {
1038 PTPContainer ptp;
1039 uint16_t ret;
1040 unsigned int *size = 0;
1041 unsigned char *data = NULL;
1042
1043 PTP_CNT_INIT(ptp, PTP_OC_PANASONIC_9401, param1);
1044 ret = ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, size);
1045 free(data);
1046 return ret;
1047 }
1048
1049 /* liveview format query
1050 * 0d800012 - get imageformats
1051 * 0d800011 - get current imageformat ?
1052 */
1053 uint16_t
1054 ptp_panasonic_9414_0d800012 (PTPParams* params, PanasonicLiveViewSize **liveviewsizes, unsigned int *nrofliveviewsizes)
1055 {
1056 PTPContainer ptp;
1057 unsigned int i;
1058 unsigned int size = 0;
1059 unsigned char *data = NULL;
1060 uint32_t blobsize;
1061 uint16_t count;
1062 uint16_t structsize;
1063
1064 *nrofliveviewsizes = 0;
1065 *liveviewsizes = NULL;
1066
1067 PTP_CNT_INIT(ptp, PTP_OC_PANASONIC_GetLiveViewParameters, 0x0d800012);
1068 CHECK_PTP_RC (ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size));
1069 /* return data with the GC9 is:
1070
1071 12 00 80 0d
1072 1c 00 00 00
1073 03 00 count
1074 08 00 structsize
1075 e0 01 80 02 20 00 1e 00
1076 d0 02 c0 03 5e 01 1e 00
1077 c0 03 00 05 bc 02 1e 00
1078
1079 */
1080 if (size < 8) return PTP_RC_GeneralError;
1081
1082 blobsize = dtoh32a(data+4);
1083 if (size - 8 < blobsize) {
1084 ptp_debug (params, "blobsize expected %d, but size is only %d", blobsize, size - 8);
1085 return PTP_RC_GeneralError;
1086 }
1087 if (blobsize < 4) {
1088 ptp_debug (params, "blobsize expected at least 4, but is only %d", blobsize);
1089 return PTP_RC_GeneralError;
1090 }
1091 count = dtoh16a (data+8);
1092 structsize = dtoh16a (data+10);
1093 if (structsize != 8) {
1094 ptp_debug (params, "structsize expected 8, but is %d", structsize);
1095 return PTP_RC_GeneralError;
1096 }
1097 if (count * structsize > blobsize) {
1098 ptp_debug (params, "%d * %d = %d is larger than %d", count, structsize, count * structsize, blobsize);
1099 return PTP_RC_GeneralError;
1100 }
1101
1102 *liveviewsizes = calloc (sizeof(PanasonicLiveViewSize),count);
1103 for (i = 0;i < count; i++) {
1104 (*liveviewsizes)[i].height = dtoh16a (data + 12 + i*structsize);
1105 (*liveviewsizes)[i].width = dtoh16a (data + 12 + 2 + i*structsize);
1106 (*liveviewsizes)[i].x = dtoh16a (data + 12 + 4 + i*structsize);
1107 (*liveviewsizes)[i].freq = dtoh16a (data + 12 + 6 + i*structsize);
1108 }
1109 *nrofliveviewsizes = count;
1110 free(data);
1111 return PTP_RC_OK;
1112 }
1113
1114 uint16_t
1115 ptp_panasonic_9414_0d800011 (PTPParams* params, PanasonicLiveViewSize *liveviewsize)
1116 {
1117 PTPContainer ptp;
1118 unsigned int size = 0;
1119 unsigned char *data = NULL;
1120 uint32_t blobsize;
1121
1122 PTP_CNT_INIT(ptp, PTP_OC_PANASONIC_GetLiveViewParameters, 0x0d800011);
1123 CHECK_PTP_RC (ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size));
1124 /* data is:
1125
1126 11 00 80 0d
1127 08 00 00 00
1128
1129 e0 01 80 02
1130 00 00
1131 1e 00
1132
1133 */
1134 if (size < 8) return PTP_RC_GeneralError;
1135
1136 blobsize = dtoh32a(data+4);
1137 if (size - 8 < blobsize) {
1138 ptp_debug (params, "blobsize expected %d, but size is only %d", blobsize, size - 8);
1139 return PTP_RC_GeneralError;
1140 }
1141 if (blobsize < 8) {
1142 ptp_debug (params, "blobsize expected at least 8, but is only %d", blobsize);
1143 return PTP_RC_GeneralError;
1144 }
1145 liveviewsize->height = dtoh16a (data + 8 + 0);
1146 liveviewsize->width = dtoh16a (data + 8 + 2);
1147 liveviewsize->x = dtoh16a (data + 8 + 4);
1148 liveviewsize->freq = dtoh16a (data + 8 + 6);
1149 free(data);
1150 return PTP_RC_OK;
1151 }
1152
1153 uint16_t
1154 ptp_panasonic_9415 (PTPParams* params, PanasonicLiveViewSize *liveviewsize)
1155 {
1156 PTPContainer ptp;
1157 unsigned char *data;
1158 uint16_t ret;
1159
1160 PTP_CNT_INIT(ptp, PTP_OC_PANASONIC_SetLiveViewParameters, 0x0d800011);
1161
1162 data = malloc(16);
1163 htod32a(data+0 , 0x0d800011);
1164 htod32a(data+4 , 8);
1165 htod16a(data+8 , liveviewsize->height);
1166 htod16a(data+10, liveviewsize->width);
1167 htod16a(data+12, liveviewsize->x);
1168 htod16a(data+14, liveviewsize->freq);
1169
1170 ret = ptp_transaction(params, &ptp, PTP_DP_SENDDATA, 16, (unsigned char**)&data, 0);
1171 free (data);
1172 return ret;
1173 }
1174
1175 uint16_t
1176 ptp_panasonic_setdeviceproperty (PTPParams* params, uint32_t propcode,
1177 unsigned char *value, uint16_t valuesize)
1178 {
1179 PTPContainer ptp;
1180 uint16_t ret;
1181 unsigned char *data;
1182 uint32_t size = 4 + 4 + valuesize;
1183
1184 data = calloc(size, sizeof(unsigned char));
1185
1186 htod32a(data, propcode); /* memcpy(data, &propcode, 4); */
1187 htod16a(&data[4], valuesize); /* memcpy(&data[4], &valuesize, 2); */
1188
1189 memcpy(&data[8], value, valuesize); /* perhaps check if one of the DPV packagers work? */
1190
1191 PTP_CNT_INIT(ptp, PTP_OC_PANASONIC_SetProperty, propcode);
1192 ret = ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, &data, NULL);
1193 free(data);
1194 return ret;
1195 }
1196
1197 uint16_t
1198 ptp_panasonic_getdevicepropertysize (PTPParams *params, uint32_t propcode)
1199 {
1200 PTPContainer ptp;
1201 unsigned char *data = NULL;
1202 unsigned int size = 0;
1203
1204 PTP_CNT_INIT(ptp, PTP_OC_PANASONIC_9107, propcode, 0, 0);
1205 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size));
1206 if (!data) return PTP_RC_GeneralError;
1207
1208 if (size < 4) return PTP_RC_GeneralError;
1209 uint32_t headerLength = dtoh32a( (data) + 4 );
1210 if (size < 4 + 6 * 4) return PTP_RC_GeneralError;
1211 uint32_t propertyCode = dtoh32a( (data) + 4 + 6 * 4 );
1212 if (size < headerLength * 4 + 2 * 4) return PTP_RC_GeneralError;
1213
1214 ptp_debug(params, "header: %lu, code: %lu\n", headerLength, propertyCode);
1215
1216 return PTP_RC_OK;
1217 }
1218
1219 uint16_t
1220 ptp_panasonic_manualfocusdrive (PTPParams* params, uint16_t mode)
1221 {
1222 PTPContainer ptp;
1223 unsigned char data[10];
1224 unsigned char *xdata = data;
1225 uint32_t propcode = 0x03010011;
1226 uint32_t type = 2;
1227
1228 htod32a(data, propcode); /* memcpy(data, &propcode, 4); */
1229 htod32a(&data[4], type); /* memcpy(&data[4], &type, 4); */
1230 htod16a(&data[8], mode); /* memcpy(&data[8], &mode, 2); */
1231
1232 PTP_CNT_INIT(ptp, PTP_OC_PANASONIC_ManualFocusDrive, propcode);
1233 return ptp_transaction(params, &ptp, PTP_DP_SENDDATA, sizeof(data), &xdata, NULL);
1234 }
1235
1236 uint16_t
1237 ptp_panasonic_getcapturetarget (PTPParams* params, uint16_t *target)
1238 {
1239 PTPContainer ptp;
1240 unsigned char *data;
1241 unsigned int size;
1242
1243 *target = 0;
1244
1245 PTP_CNT_INIT(ptp, PTP_OC_PANASONIC_GetCaptureTarget, 0x08000090);
1246 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size));
1247 if (!data) return PTP_RC_GeneralError;
1248 if (size < 10) return PTP_RC_GeneralError;
1249 if (dtoh32a(data) != 0x08000091) return PTP_RC_GeneralError;
1250 if (dtoh32a(data+4) != 2) return PTP_RC_GeneralError;
1251 *target = dtoh16a(data+8);
1252 free (data);
1253 return PTP_RC_OK;
1254 }
1255
1256 uint16_t
1257 ptp_panasonic_setcapturetarget (PTPParams* params, uint16_t mode) // mode == 1 == RAM, mode == 0 == SD, 2 = BOTH
1258 {
1259 PTPContainer ptp;
1260 unsigned char data[10];
1261 unsigned char *xdata = (unsigned char*)data;
1262
1263 htod32a(data, 0x08000091); /* capturetarget */
1264 htod32a(&data[4], 2); /* size */
1265 htod16a(&data[8], mode);
1266
1267 PTP_CNT_INIT(ptp, PTP_OC_PANASONIC_SetCaptureTarget, 0);
1268 return ptp_transaction(params, &ptp, PTP_DP_SENDDATA, sizeof(data), &xdata, NULL);
1269 }
1270
1271 uint16_t
1272 ptp_panasonic_getdevicepropertydesc (PTPParams *params, uint32_t propcode, uint16_t valuesize, uint32_t *currentValue, uint32_t **propertyValueList, uint32_t *propertyValueListLength)
1273 {
1274 PTPContainer ptp;
1275 unsigned char *data = NULL;
1276 unsigned int size = 0;
1277 uint16_t ret = PTP_RC_OK;
1278 uint32_t headerLength;
1279 uint32_t propertyCode;
1280 unsigned int off = 0;
1281
1282 PTP_CNT_INIT(ptp, PTP_OC_PANASONIC_ListProperty, propcode, 0, 0);
1283 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size));
1284 if (!data) return PTP_RC_GeneralError;
1285 if (size < 8)
1286 return PTP_RC_GeneralError;
1287
1288 ptp_debug (params, "ptp_panasonic_getdevicepropertydesc 0x%08x", propcode);
1289 while (off < size) {
1290 if (off >= size-8) break;
1291 ptp_debug (params, "propcode 0x%08lx, size %d", dtoh32a(data+off), dtoh32a(data+off+4));
1292 off += dtoh32a(data+off+4)+8;
1293 }
1294
1295 headerLength = dtoh32a( (data) + 4 );
1296 if (size < 4 + 6 * 4)
1297 return PTP_RC_GeneralError;
1298
1299 propertyCode = dtoh32a( (data) + 4 + 6 * 4 );
1300 if (size < headerLength * 4 + 2 * 4)
1301 return PTP_RC_GeneralError;
1302
1303 if(valuesize == 2) {
1304 *currentValue = (uint32_t) dtoh16a( (data) + headerLength * 4 + 2 * 4 );
1305 } else if(valuesize == 4) {
1306 *currentValue = dtoh32a( (data) + headerLength * 4 + 2 * 4 );
1307 } else {
1308 ptp_debug (params, "unexpected valuesize %d", valuesize);
1309 return PTP_RC_GeneralError;
1310 }
1311 /* Marcus: where is 4*headerLenght coming from ? */
1312 if (size < headerLength * 4 + 2 * 4 + valuesize) return PTP_RC_GeneralError;
1313 *propertyValueListLength = dtoh32a( (data) + headerLength * 4 + 2 * 4 + valuesize);
1314
1315 ptp_debug(params, "header: %lu, code: 0x%lx, value: %lu, count: %lu", headerLength, propertyCode, *currentValue, *propertyValueListLength);
1316
1317 if (size < headerLength * 4 + 3 * 4 + valuesize + (*propertyValueListLength) * valuesize) {
1318 ptp_debug (params, "size %d vs expected size %d", size, headerLength * 4 + 3 * 4 + valuesize + (*propertyValueListLength) * valuesize);
1319 return PTP_RC_GeneralError;
1320 }
1321
1322 *propertyValueList = calloc(*propertyValueListLength, sizeof(uint32_t));
1323
1324 uint16_t i;
1325 for(i = 0; i < *propertyValueListLength; i++) {
1326 if(valuesize == 2) {
1327 (*propertyValueList)[i] = (uint32_t) dtoh16a( (data) + headerLength * 4 + 3 * 4 + valuesize + i * valuesize);
1328 } else if(valuesize == 4) {
1329 (*propertyValueList)[i] = dtoh32a( (data) + headerLength * 4 + 3 * 4 + valuesize + i * valuesize);
1330 }
1331 //printf("Property: %lu\n", (*propertyValueList)[i]);
1332 }
1333
1334 free (data);
1335 return ret;
1336 }
1337
1338
1339 uint16_t
1340 ptp_panasonic_getdeviceproperty (PTPParams *params, uint32_t propcode, uint16_t *valuesize, uint32_t *currentValue)
1341 {
1342 PTPContainer ptp;
1343 unsigned char *data = NULL;
1344 unsigned int size = 0;
1345 uint16_t ret = PTP_RC_OK;
1346
1347 PTP_CNT_INIT(ptp, PTP_OC_PANASONIC_GetProperty, propcode);
1348 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size));
1349 if (!data) return PTP_RC_GeneralError;
1350
1351 if(size < 8) return PTP_RC_GeneralError;
1352 *valuesize = dtoh32a( (data + 4) );
1353
1354 if(size < 8u + (*valuesize)) return PTP_RC_GeneralError;
1355 if(*valuesize == 4) {
1356 *currentValue = dtoh32a( (data + 8) );
1357 } else if(*valuesize == 2) {
1358 *currentValue = (uint32_t) dtoh16a( (data + 8) );
1359 } else {
1360 return PTP_RC_GeneralError;
1361 }
1362 //printf("ptp_panasonic_getdeviceproperty: size: %lu, valuesize: %d, currentValue: %lu\n", size, *valuesize, *currentValue);
1363
1364 free (data);
1365 return ret;
1366 }
1367
1368 #ifdef HAVE_LIBXML2
1369 static uint16_t
1370 ptp_olympus_parse_output_xml(PTPParams* params, char*data, int len, xmlNodePtr *code)
1371 {
1372 xmlDocPtr docin;
1373 xmlNodePtr docroot, output, next;
1374 int result, xcode;
1375
1376 *code = NULL;
1377
1378 docin = xmlReadMemory ((char*)data, len, "http://gphoto.org/", "utf-8", 0);
1379 if (!docin) return PTP_RC_GeneralError;
1380 docroot = xmlDocGetRootElement (docin);
1381 if (!docroot) {
1382 xmlFreeDoc (docin);
1383 return PTP_RC_GeneralError;
1384 }
1385
1386 if (strcmp((char*)docroot->name,"x3c")) {
1387 ptp_debug (params, "olympus: docroot is not x3c, but %s", docroot->name);
1388 xmlFreeDoc (docin);
1389 return PTP_RC_GeneralError;
1390 }
1391 if (xmlChildElementCount(docroot) != 1) {
1392 ptp_debug (params, "olympus: x3c: expected 1 child, got %ld", xmlChildElementCount(docroot));
1393 xmlFreeDoc (docin);
1394 return PTP_RC_GeneralError;
1395 }
1396 output = xmlFirstElementChild (docroot);
1397 if (strcmp((char*)output->name, "output") != 0) {
1398 ptp_debug (params, "olympus: x3c node: expected child 'output', but got %s", (char*)output->name);
1399 xmlFreeDoc (docin);
1400 return PTP_RC_GeneralError;
1401 }
1402 next = xmlFirstElementChild (output);
1403
1404 result = PTP_RC_GeneralError;
1405
1406 while (next) {
1407 if (!strcmp((char*)next->name,"result")) {
1408 xmlChar *xchar;
1409
1410 xchar = xmlNodeGetContent (next);
1411 if (!sscanf((char*)xchar,"%04x",&result))
1412 ptp_debug (params, "failed scanning result from %s", xchar);
1413 ptp_debug (params, "ptp result is 0x%04x", result);
1414 next = xmlNextElementSibling (next);
1415 continue;
1416 }
1417 if (sscanf((char*)next->name,"c%x", &xcode)) {
1418 ptp_debug (params, "ptp code node found %s", (char*)next->name);
1419 *code = next;
1420 next = xmlNextElementSibling (next);
1421 continue;
1422 }
1423 ptp_debug (params, "unhandled node %s", (char*)next->name);
1424 next = xmlNextElementSibling (next);
1425 }
1426
1427 if (result != PTP_RC_OK) {
1428 *code = NULL;
1429 xmlFreeDoc (docin);
1430 }
1431 return result;
1432 }
1433 #endif
1434
1435 uint16_t
1436 ptp_olympus_getdeviceinfo (PTPParams* params, PTPDeviceInfo *di)
1437 {
1438 #ifdef HAVE_LIBXML2
1439 PTPContainer ptp;
1440 uint16_t ret;
1441 unsigned char *data = NULL;
1442 unsigned int size;
1443 xmlNodePtr code;
1444
1445 memset (di, 0, sizeof(PTPDeviceInfo));
1446
1447 PTP_CNT_INIT(ptp, PTP_OC_OLYMPUS_GetDeviceInfo);
1448 ret=ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size);
1449 /* TODO: check for error, only parse_output_xml if ret == PTP_RC_OK?
1450 * where is 'data' going to be deallocated? */
1451 ret = ptp_olympus_parse_output_xml(params,(char*)data,size,&code);
1452 if (ret != PTP_RC_OK)
1453 return ret;
1454
1455 ret = parse_9301_tree (params, code, di);
1456
1457 xmlFreeDoc(code->doc);
1458 return ret;
1459 #else
1460 return PTP_RC_GeneralError;
1461 #endif
1462 }
1463
1464 uint16_t
1465 ptp_olympus_opensession (PTPParams* params, unsigned char**data, unsigned int *len)
1466 {
1467 PTPContainer ptp;
1468
1469 PTP_CNT_INIT(ptp, PTP_OC_OLYMPUS_OpenSession);
1470 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, data, len);
1471 }
1472
1473 uint16_t
1474 ptp_olympus_getcameraid (PTPParams* params, unsigned char**data, unsigned int *len)
1475 {
1476 PTPContainer ptp;
1477
1478 PTP_CNT_INIT(ptp, PTP_OC_OLYMPUS_GetCameraID);
1479 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, data, len);
1480 }
1481
1482 /**
1483 * ptp_generic_no_data:
1484 * params: PTPParams*
1485 * code PTP OP Code
1486 * n_param count of parameters
1487 * ... variable argument list ...
1488 *
1489 * Emits a generic PTP command without any data transfer.
1490 *
1491 * Return values: Some PTP_RC_* code.
1492 **/
1493 uint16_t
1494 ptp_generic_no_data (PTPParams* params, uint16_t code, unsigned int n_param, ...)
1495 {
1496 PTPContainer ptp;
1497 va_list args;
1498 unsigned int i;
1499
1500 if( n_param > 5 )
1501 return PTP_ERROR_BADPARAM;
1502
1503 memset(&ptp, 0, sizeof(ptp));
1504 ptp.Code=code;
1505 ptp.Nparam=n_param;
1506
1507 va_start(args, n_param);
1508 for( i=0; i<n_param; ++i )
1509 (&ptp.Param1)[i] = va_arg(args, uint32_t);
1510 va_end(args);
1511
1512 return ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL);
1513 }
1514
1515 /**
1516 * ptp_opensession:
1517 * params: PTPParams*
1518 * session - session number
1519 *
1520 * Establishes a new session.
1521 *
1522 * Return values: Some PTP_RC_* code.
1523 **/
1524 uint16_t
1525 ptp_opensession (PTPParams* params, uint32_t session)
1526 {
1527 PTPContainer ptp;
1528 uint16_t ret;
1529
1530 ptp_debug(params,"PTP: Opening session");
1531
1532 /* SessonID field of the operation dataset should always
1533 be set to 0 for OpenSession request! */
1534 params->session_id=0x00000000;
1535 /* TransactionID should be set to 0 also! */
1536 params->transaction_id=0x0000000;
1537 /* zero out response packet buffer */
1538 params->response_packet = NULL;
1539 params->response_packet_size = 0;
1540 /* no split headers */
1541 params->split_header_data = 0;
1542
1543 PTP_CNT_INIT(ptp, PTP_OC_OpenSession, session);
1544 ret=ptp_transaction_new(params, &ptp, PTP_DP_NODATA, 0, NULL);
1545 /* TODO: check for error */
1546 /* now set the global session id to current session number */
1547 params->session_id=session;
1548 return ret;
1549 }
1550
1551 void
1552 ptp_free_devicepropvalue(uint16_t dt, PTPPropertyValue* dpd)
1553 {
1554 switch (dt) {
1555 case PTP_DTC_INT8: case PTP_DTC_UINT8:
1556 case PTP_DTC_UINT16: case PTP_DTC_INT16:
1557 case PTP_DTC_UINT32: case PTP_DTC_INT32:
1558 case PTP_DTC_UINT64: case PTP_DTC_INT64:
1559 case PTP_DTC_UINT128: case PTP_DTC_INT128:
1560 /* Nothing to free */
1561 break;
1562 case PTP_DTC_AINT8: case PTP_DTC_AUINT8:
1563 case PTP_DTC_AUINT16: case PTP_DTC_AINT16:
1564 case PTP_DTC_AUINT32: case PTP_DTC_AINT32:
1565 case PTP_DTC_AUINT64: case PTP_DTC_AINT64:
1566 case PTP_DTC_AUINT128: case PTP_DTC_AINT128:
1567 free(dpd->a.v);
1568 break;
1569 case PTP_DTC_STR:
1570 free(dpd->str);
1571 break;
1572 }
1573 }
1574
1575 void
1576 ptp_free_devicepropdesc(PTPDevicePropDesc* dpd)
1577 {
1578 uint16_t i;
1579
1580 ptp_free_devicepropvalue (dpd->DataType, &dpd->FactoryDefaultValue);
1581 ptp_free_devicepropvalue (dpd->DataType, &dpd->CurrentValue);
1582 switch (dpd->FormFlag) {
1583 case PTP_DPFF_Range:
1584 ptp_free_devicepropvalue (dpd->DataType, &dpd->FORM.Range.MinimumValue);
1585 ptp_free_devicepropvalue (dpd->DataType, &dpd->FORM.Range.MaximumValue);
1586 ptp_free_devicepropvalue (dpd->DataType, &dpd->FORM.Range.StepSize);
1587 break;
1588 case PTP_DPFF_Enumeration:
1589 if (dpd->FORM.Enum.SupportedValue) {
1590 for (i=0;i<dpd->FORM.Enum.NumberOfValues;i++)
1591 ptp_free_devicepropvalue (dpd->DataType, dpd->FORM.Enum.SupportedValue+i);
1592 free (dpd->FORM.Enum.SupportedValue);
1593 }
1594 }
1595 dpd->DataType = PTP_DTC_UNDEF;
1596 dpd->FormFlag = PTP_DPFF_None;
1597 }
1598
1599
1600 void
1601 ptp_free_objectpropdesc(PTPObjectPropDesc* opd)
1602 {
1603 uint16_t i;
1604
1605 ptp_free_devicepropvalue (opd->DataType, &opd->FactoryDefaultValue);
1606 switch (opd->FormFlag) {
1607 case PTP_OPFF_None:
1608 break;
1609 case PTP_OPFF_Range:
1610 ptp_free_devicepropvalue (opd->DataType, &opd->FORM.Range.MinimumValue);
1611 ptp_free_devicepropvalue (opd->DataType, &opd->FORM.Range.MaximumValue);
1612 ptp_free_devicepropvalue (opd->DataType, &opd->FORM.Range.StepSize);
1613 break;
1614 case PTP_OPFF_Enumeration:
1615 if (opd->FORM.Enum.SupportedValue) {
1616 for (i=0;i<opd->FORM.Enum.NumberOfValues;i++)
1617 ptp_free_devicepropvalue (opd->DataType, opd->FORM.Enum.SupportedValue+i);
1618 free (opd->FORM.Enum.SupportedValue);
1619 }
1620 break;
1621 case PTP_OPFF_DateTime:
1622 free(opd->FORM.DateTime.String);
1623 break;
1624 case PTP_OPFF_RegularExpression:
1625 free(opd->FORM.RegularExpression.String);
1626 break;
1627 case PTP_OPFF_FixedLengthArray: /* nothing to free */ /* fallthrough */
1628 case PTP_OPFF_ByteArray: /* nothing to free */ /* fallthrough */
1629 case PTP_OPFF_LongString:
1630 /* Ignore these presently, we cannot unpack them, so there is nothing to be freed. */
1631 break;
1632 default:
1633 fprintf (stderr, "Unknown OPFF type %d\n", opd->FormFlag);
1634 break;
1635 }
1636 }
1637
1638
1639 /**
1640 * ptp_free_params:
1641 * params: PTPParams*
1642 *
1643 * Frees all data within the PTPParams struct.
1644 *
1645 * Return values: Some PTP_RC_* code.
1646 **/
1647 void
1648 ptp_free_params (PTPParams *params)
1649 {
1650 unsigned int i;
1651
1652 free (params->cameraname);
1653 free (params->wifi_profiles);
1654 for (i=0;i<params->nrofobjects;i++)
1655 ptp_free_object (¶ms->objects[i]);
1656 free (params->objects);
1657 free (params->storageids.Storage);
1658 free (params->events);
1659 for (i=0;i<params->nrofcanon_props;i++) {
1660 free (params->canon_props[i].data);
1661 ptp_free_devicepropdesc (¶ms->canon_props[i].dpd);
1662 }
1663 free (params->canon_props);
1664 free (params->backlogentries);
1665
1666 for (i=0;i<params->nrofdeviceproperties;i++)
1667 ptp_free_devicepropdesc (¶ms->deviceproperties[i].desc);
1668 free (params->deviceproperties);
1669
1670 ptp_free_DI (¶ms->deviceinfo);
1671 }
1672
1673 /**
1674 * ptp_getststorageids:
1675 * params: PTPParams*
1676 *
1677 * Gets array of StorageIDs and fills the storageids structure.
1678 *
1679 * Return values: Some PTP_RC_* code.
1680 **/
1681 uint16_t
1682 ptp_getstorageids (PTPParams* params, PTPStorageIDs* storageids)
1683 {
1684 PTPContainer ptp;
1685 unsigned char *data = NULL;
1686 unsigned int size;
1687
1688 PTP_CNT_INIT(ptp, PTP_OC_GetStorageIDs);
1689 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size));
1690 ptp_unpack_SIDs(params, data, storageids, size);
1691 free(data);
1692 return PTP_RC_OK;
1693 }
1694
1695 /**
1696 * ptp_getststorageinfo:
1697 * params: PTPParams*
1698 * storageid - StorageID
1699 *
1700 * Gets StorageInfo dataset of desired storage and fills storageinfo
1701 * structure.
1702 *
1703 * Return values: Some PTP_RC_* code.
1704 **/
1705 uint16_t
1706 ptp_getstorageinfo (PTPParams* params, uint32_t storageid,
1707 PTPStorageInfo* storageinfo)
1708 {
1709 PTPContainer ptp;
1710 unsigned char *data = NULL;
1711 unsigned int size;
1712
1713 PTP_CNT_INIT(ptp, PTP_OC_GetStorageInfo, storageid);
1714 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size));
1715 if (!data || !size)
1716 return PTP_RC_GeneralError;
1717 memset(storageinfo, 0, sizeof(*storageinfo));
1718 if (!ptp_unpack_SI(params, data, storageinfo, size)) {
1719 free(data);
1720 return PTP_RC_GeneralError;
1721 }
1722 free(data);
1723 return PTP_RC_OK;
1724 }
1725
1726 /**
1727 * ptp_getobjecthandles:
1728 * params: PTPParams*
1729 * storage - StorageID
1730 * objectformatcode - ObjectFormatCode (optional)
1731 * associationOH - ObjectHandle of Association for
1732 * which a list of children is desired
1733 * (optional)
1734 * objecthandles - pointer to structute
1735 *
1736 * Fills objecthandles with structure returned by device.
1737 *
1738 * Return values: Some PTP_RC_* code.
1739 **/
1740 uint16_t
1741 ptp_getobjecthandles (PTPParams* params, uint32_t storage,
1742 uint32_t objectformatcode, uint32_t associationOH,
1743 PTPObjectHandles* objecthandles)
1744 {
1745 PTPContainer ptp;
1746 uint16_t ret;
1747 unsigned char *data = NULL;
1748 unsigned int size;
1749
1750 objecthandles->Handler = NULL;
1751 objecthandles->n = 0;
1752
1753 PTP_CNT_INIT(ptp, PTP_OC_GetObjectHandles, storage, objectformatcode, associationOH);
1754 ret=ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size);
1755 if (ret == PTP_RC_OK) {
1756 ptp_unpack_OH(params, data, objecthandles, size);
1757 } else {
1758 if ( (storage == 0xffffffff) &&
1759 (objectformatcode == 0) &&
1760 (associationOH == 0)
1761 ) {
1762 /* When we query all object handles on all stores and
1763 * get an error -> just handle it as "0 handles".
1764 */
1765 objecthandles->Handler = NULL;
1766 objecthandles->n = 0;
1767 ret = PTP_RC_OK;
1768 }
1769 }
1770 free(data);
1771 return ret;
1772 }
1773
1774 uint16_t
1775 ptp_getfilesystemmanifest (PTPParams* params, uint32_t storage,
1776 uint32_t objectformatcode, uint32_t associationOH,
1777 uint64_t *numoifs, PTPObjectFilesystemInfo **oifs
1778 ) {
1779 PTPContainer ptp;
1780 unsigned int size = 0;
1781 unsigned char *data = NULL;
1782
1783 *oifs = NULL;
1784 *numoifs = 0;
1785 PTP_CNT_INIT(ptp, PTP_OC_GetFilesystemManifest, storage, objectformatcode, associationOH);
1786 CHECK_PTP_RC (ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size));
1787 ptp_unpack_ptp11_manifest (params, data, size, numoifs, oifs);
1788 return PTP_RC_OK;
1789 }
1790
1791 /**
1792 * ptp_getnumobjects:
1793 * params: PTPParams*
1794 * storage - StorageID
1795 * objectformatcode - ObjectFormatCode (optional)
1796 * associationOH - ObjectHandle of Association for
1797 * which a list of children is desired
1798 * (optional)
1799 * numobs - pointer to uint32_t that takes number of objects
1800 *
1801 * Fills numobs with number of objects on device.
1802 *
1803 * Return values: Some PTP_RC_* code.
1804 **/
1805 uint16_t
1806 ptp_getnumobjects (PTPParams* params, uint32_t storage,
1807 uint32_t objectformatcode, uint32_t associationOH,
1808 uint32_t* numobs)
1809 {
1810 PTPContainer ptp;
1811
1812 PTP_CNT_INIT(ptp, PTP_OC_GetNumObjects, storage, objectformatcode, associationOH);
1813 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL));
1814 if (ptp.Nparam >= 1)
1815 *numobs = ptp.Param1;
1816 else
1817 return PTP_RC_GeneralError;
1818 return PTP_RC_OK;
1819 }
1820
1821 /**
1822 * ptp_eos_bulbstart:
1823 * params: PTPParams*
1824 *
1825 * Starts EOS Bulb capture.
1826 *
1827 * Return values: Some PTP_RC_* code.
1828 **/
1829 uint16_t
1830 ptp_canon_eos_bulbstart (PTPParams* params)
1831 {
1832 PTPContainer ptp;
1833
1834 PTP_CNT_INIT(ptp, PTP_OC_CANON_EOS_BulbStart);
1835 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL));
1836 if ((ptp.Nparam >= 1) && ((ptp.Param1 & 0x7000) == 0x2000))
1837 return ptp.Param1;
1838 return PTP_RC_OK;
1839 }
1840
1841 /**
1842 * ptp_eos_capture:
1843 * params: PTPParams*
1844 * uint32_t* result
1845 *
1846 * This starts a EOS400D style capture. You have to use the
1847 * get_eos_events to find out what resulted.
1848 * The return value is "0" for all OK, and "1" for capture failed. (not fully confirmed)
1849 *
1850 * Return values: Some PTP_RC_* code.
1851 **/
1852 uint16_t
1853 ptp_canon_eos_capture (PTPParams* params, uint32_t *result)
1854 {
1855 PTPContainer ptp;
1856
1857 PTP_CNT_INIT(ptp, PTP_OC_CANON_EOS_RemoteRelease);
1858 *result = 0;
1859 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL));
1860 if (ptp.Nparam >= 1)
1861 *result = ptp.Param1;
1862 return PTP_RC_OK;
1863 }
1864
1865 /**
1866 * ptp_canon_eos_bulbend:
1867 * params: PTPParams*
1868 *
1869 * Starts EOS Bulb capture.
1870 *
1871 * Return values: Some PTP_RC_* code.
1872 **/
1873 uint16_t
1874 ptp_canon_eos_bulbend (PTPParams* params)
1875 {
1876 PTPContainer ptp;
1877
1878 PTP_CNT_INIT(ptp, PTP_OC_CANON_EOS_BulbEnd);
1879 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL));
1880 if ((ptp.Nparam >= 1) && ((ptp.Param1 & 0x7000) == 0x2000))
1881 return ptp.Param1;
1882 return PTP_RC_OK;
1883 }
1884
1885 /**
1886 * ptp_getobjectinfo:
1887 * params: PTPParams*
1888 * handle - Object handle
1889 * objectinfo - pointer to objectinfo that is returned
1890 *
1891 * Get objectinfo structure for handle from device.
1892 *
1893 * Return values: Some PTP_RC_* code.
1894 **/
1895 uint16_t
1896 ptp_getobjectinfo (PTPParams* params, uint32_t handle,
1897 PTPObjectInfo* objectinfo)
1898 {
1899 PTPContainer ptp;
1900 unsigned char *data = NULL;
1901 unsigned int size;
1902
1903 PTP_CNT_INIT(ptp, PTP_OC_GetObjectInfo, handle);
1904 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size));
1905 ptp_unpack_OI(params, data, objectinfo, size);
1906 free(data);
1907 return PTP_RC_OK;
1908 }
1909
1910 /**
1911 * ptp_getobject:
1912 * params: PTPParams*
1913 * handle - Object handle
1914 * object - pointer to data area
1915 *
1916 * Get object 'handle' from device and store the data in newly
1917 * allocated 'object'.
1918 *
1919 * Return values: Some PTP_RC_* code.
1920 **/
1921 uint16_t
1922 ptp_getobject (PTPParams* params, uint32_t handle, unsigned char** object)
1923 {
1924 PTPContainer ptp;
1925
1926 PTP_CNT_INIT(ptp, PTP_OC_GetObject, handle);
1927 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, object, NULL);
1928 }
1929
1930 /**
1931 * ptp_getobject_with_size:
1932 * params: PTPParams*
1933 * handle - Object handle
1934 * object - pointer to data area
1935 * size - pointer to uint, returns size of object
1936 *
1937 * Get object 'handle' from device and store the data in newly
1938 * allocated 'object'.
1939 *
1940 * Return values: Some PTP_RC_* code.
1941 **/
1942 uint16_t
1943 ptp_getobject_with_size (PTPParams* params, uint32_t handle, unsigned char** object, unsigned int *size)
1944 {
1945 PTPContainer ptp;
1946
1947 PTP_CNT_INIT(ptp, PTP_OC_GetObject, handle);
1948 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, object, size);
1949 }
1950
1951 /**
1952 * ptp_getobject_to_handler:
1953 * params: PTPParams*
1954 * handle - Object handle
1955 * PTPDataHandler* - pointer datahandler
1956 *
1957 * Get object 'handle' from device and store the data in newly
1958 * allocated 'object'.
1959 *
1960 * Return values: Some PTP_RC_* code.
1961 **/
1962 uint16_t
1963 ptp_getobject_to_handler (PTPParams* params, uint32_t handle, PTPDataHandler *handler)
1964 {
1965 PTPContainer ptp;
1966
1967 PTP_CNT_INIT(ptp, PTP_OC_GetObject, handle);
1968 return ptp_transaction_new(params, &ptp, PTP_DP_GETDATA, 0, handler);
1969 }
1970
1971 /**
1972 * ptp_getobject_tofd:
1973 * params: PTPParams*
1974 * handle - Object handle
1975 * fd - File descriptor to write() to
1976 *
1977 * Get object 'handle' from device and write the data to the
1978 * given file descriptor.
1979 *
1980 * Return values: Some PTP_RC_* code.
1981 **/
1982 uint16_t
1983 ptp_getobject_tofd (PTPParams* params, uint32_t handle, int fd)
1984 {
1985 PTPContainer ptp;
1986 PTPDataHandler handler;
1987 uint16_t ret;
1988
1989 PTP_CNT_INIT(ptp, PTP_OC_GetObject, handle);
1990 ptp_init_fd_handler (&handler, fd);
1991 ret = ptp_transaction_new(params, &ptp, PTP_DP_GETDATA, 0, &handler);
1992 ptp_exit_fd_handler (&handler);
1993 return ret;
1994 }
1995
1996 /**
1997 * ptp_getpartialobject:
1998 * params: PTPParams*
1999 * handle - Object handle
2000 * offset - Offset into object
2001 * maxbytes - Maximum of bytes to read
2002 * object - pointer to data area
2003 * len - pointer to returned length
2004 *
2005 * Get object 'handle' from device and store the data in newly
2006 * allocated 'object'. Start from offset and read at most maxbytes.
2007 *
2008 * Return values: Some PTP_RC_* code.
2009 **/
2010 uint16_t
2011 ptp_getpartialobject (PTPParams* params, uint32_t handle, uint32_t offset,
2012 uint32_t maxbytes, unsigned char** object,
2013 uint32_t *len)
2014 {
2015 PTPContainer ptp;
2016
2017 PTP_CNT_INIT(ptp, PTP_OC_GetPartialObject, handle, offset, maxbytes);
2018 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, object, len);
2019 }
2020
2021 /**
2022 * ptp_getpartialobject_to_handler:
2023 * params: PTPParams*
2024 * handle - Object handle
2025 * offset - Offset into object
2026 * maxbytes - Maximum of bytes to read
2027 * handler - a ptp data handler
2028 *
2029 * Get object 'handle' from device and send the data to the
2030 * data handler. Start from offset and read at most maxbytes.
2031 *
2032 * Return values: Some PTP_RC_* code.
2033 **/
2034 uint16_t
2035 ptp_getpartialobject_to_handler (PTPParams* params, uint32_t handle, uint32_t offset,
2036 uint32_t maxbytes, PTPDataHandler *handler)
2037 {
2038 PTPContainer ptp;
2039
2040 PTP_CNT_INIT(ptp, PTP_OC_GetPartialObject, handle, offset, maxbytes);
2041 return ptp_transaction_new(params, &ptp, PTP_DP_GETDATA, 0, handler);
2042 }
2043
2044 /**
2045 * ptp_nikon_getpartialobjectex:
2046 * params: PTPParams*
2047 * handle - Object handle
2048 * offset - 64bit offset into object
2049 * maxbytes - 64bit maximum of bytes to read
2050 * handler - a ptp pata handler
2051 *
2052 * Get object 'handle' from device and send the data to the
2053 * data handler. Start from offset and read at most maxbytes.
2054 *
2055 * Return values: Some PTP_RC_* code.
2056 **/
2057 uint16_t
2058 ptp_nikon_getpartialobjectex (PTPParams* params, uint32_t handle, uint64_t offset,
2059 uint64_t maxbytes, unsigned char** object,
2060 uint32_t *len)
2061 {
2062 PTPContainer ptp;
2063
2064 /* casts due to varargs otherwise pushing 64bit values on the stack */
2065 PTP_CNT_INIT(ptp, PTP_OC_NIKON_GetPartialObjectEx, handle, ((uint32_t)offset & 0xFFFFFFFF), (uint32_t)(offset >> 32), ((uint32_t)maxbytes & 0xFFFFFFFF), (uint32_t)(maxbytes >> 32));
2066 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, object, len);
2067 }
2068
2069
2070 /**
2071 * ptp_getthumb:
2072 * params: PTPParams*
2073 * handle - Object handle
2074 * object - pointer to data area
2075 *
2076 * Get thumb for object 'handle' from device and store the data in newly
2077 * allocated 'object'.
2078 *
2079 * Return values: Some PTP_RC_* code.
2080 **/
2081 uint16_t
2082 ptp_getthumb (PTPParams* params, uint32_t handle, unsigned char** object, unsigned int *len)
2083 {
2084 PTPContainer ptp;
2085
2086 PTP_CNT_INIT(ptp, PTP_OC_GetThumb, handle);
2087 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, object, len);
2088 }
2089
2090 /**
2091 * ptp_nikon_getlargethumb:
2092 * params: PTPParams*
2093 * handle - Object handle
2094 * object - pointer to data area
2095 *
2096 * Get a large thumb for object 'handle' from device and store the data in newly
2097 * allocated 'object'. This function is Nikon specific.
2098 *
2099 * Return values: Some PTP_RC_* code.
2100 **/
2101 uint16_t
2102 ptp_nikon_getlargethumb (PTPParams* params, uint32_t handle, unsigned char** object, unsigned int *len)
2103 {
2104 PTPContainer ptp;
2105
2106 PTP_CNT_INIT(ptp, PTP_OC_NIKON_GetLargeThumb, handle);
2107 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, object, len);
2108 }
2109
2110 /**
2111 * ptp_nikon_getobjectsize:
2112 * params: PTPParams*
2113 * handle - Object handle
2114 * objectsize - size of object
2115 *
2116 * Get the 64bit objectsize for object 'handle' from device and store the size in objectsize
2117 * allocated 'object'. This function is Nikon specific.
2118 *
2119 * Return values: Some PTP_RC_* code.
2120 **/
2121 uint16_t
2122 ptp_nikon_getobjectsize (PTPParams* params, uint32_t handle, uint64_t *objectsize)
2123 {
2124 PTPContainer ptp;
2125 unsigned char *data = NULL;
2126 unsigned int size = 0;
2127
2128 *objectsize = 0;
2129
2130 PTP_CNT_INIT(ptp, PTP_OC_NIKON_GetObjectSize, handle);
2131 CHECK_PTP_RC (ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size));
2132
2133 if (size < 8) {
2134 free (data);
2135 return PTP_RC_GeneralError;
2136 }
2137
2138 *objectsize = dtoh64ap(params, data);
2139 free (data);
2140 return PTP_RC_OK;
2141 }
2142
2143 /**
2144 * ptp_deleteobject:
2145 * params: PTPParams*
2146 * handle - object handle
2147 * ofc - object format code (optional)
2148 *
2149 * Deletes desired objects.
2150 *
2151 * Return values: Some PTP_RC_* code.
2152 **/
2153 uint16_t
2154 ptp_deleteobject (PTPParams* params, uint32_t handle, uint32_t ofc)
2155 {
2156 PTPContainer ptp;
2157
2158 PTP_CNT_INIT(ptp, PTP_OC_DeleteObject, handle, ofc);
2159 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL));
2160 /* If the object is cached and could be removed, cleanse cache. */
2161 ptp_remove_object_from_cache(params, handle);
2162 return PTP_RC_OK;
2163 }
2164
2165 /**
2166 * ptp_moveobject:
2167 * params: PTPParams*
2168 * handle - source ObjectHandle
2169 * storage - destination StorageID
2170 * parent - destination parent ObjectHandle
2171 *
2172 * Move an object to a new location under the specified parent.
2173 * Note that unlike most calls, 0 must be passed for the parent if the destination
2174 * is the Storage root.
2175 *
2176 * Return values: Some PTP_RC_* code.
2177 **/
2178 uint16_t
2179 ptp_moveobject (PTPParams* params, uint32_t handle, uint32_t storage, uint32_t parent)
2180 {
2181 PTPContainer ptp;
2182
2183 PTP_CNT_INIT(ptp, PTP_OC_MoveObject, handle, storage, parent);
2184 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL));
2185 /* If the object is cached and could be removed, cleanse cache. */
2186 ptp_remove_object_from_cache(params, handle);
2187 return PTP_RC_OK;
2188 }
2189
2190 /**
2191 * ptp_copyobject:
2192 * params: PTPParams*
2193 * handle - source ObjectHandle
2194 * storage - destination StorageID
2195 * parent - destination parent ObjectHandle
2196 *
2197 * Copy an object to a new location under the specified parent.
2198 * Note that unlike most calls, 0 must be passed for the parent if the destination
2199 * is the Storage root.
2200 *
2201 * Return values: Some PTP_RC_* code.
2202 **/
2203 uint16_t
2204 ptp_copyobject (PTPParams* params, uint32_t handle, uint32_t storage, uint32_t parent)
2205 {
2206 PTPContainer ptp;
2207
2208 PTP_CNT_INIT(ptp, PTP_OC_CopyObject, handle, storage, parent);
2209 return ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL);
2210 }
2211
2212 /**
2213 * ptp_sendobjectinfo:
2214 * params: PTPParams*
2215 * uint32_t* store - destination StorageID on Responder
2216 * uint32_t* parenthandle - Parent ObjectHandle on responder
2217 * uint32_t* handle - see Return values
2218 * PTPObjectInfo* objectinfo- ObjectInfo that is to be sent
2219 *
2220 * Sends ObjectInfo of file that is to be sent via SendFileObject.
2221 *
2222 * Return values: Some PTP_RC_* code.
2223 * Upon success : uint32_t* store - Responder StorageID in which
2224 * object will be stored
2225 * uint32_t* parenthandle- Responder Parent ObjectHandle
2226 * in which the object will be stored
2227 * uint32_t* handle - Responder's reserved ObjectHandle
2228 * for the incoming object
2229 **/
2230 uint16_t
2231 ptp_sendobjectinfo (PTPParams* params, uint32_t* store,
2232 uint32_t* parenthandle, uint32_t* handle,
2233 PTPObjectInfo* objectinfo)
2234 {
2235 PTPContainer ptp;
2236 uint16_t ret;
2237 unsigned char *data = NULL;
2238 uint32_t size;
2239
2240 PTP_CNT_INIT(ptp, PTP_OC_SendObjectInfo, *store, *parenthandle);
2241 size = ptp_pack_OI(params, objectinfo, &data);
2242 ret = ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, &data, NULL);
2243 free(data);
2244 *store=ptp.Param1;
2245 *parenthandle=ptp.Param2;
2246 *handle=ptp.Param3;
2247 return ret;
2248 }
2249
2250 /**
2251 * ptp_sendobject:
2252 * params: PTPParams*
2253 * char* object - contains the object that is to be sent
2254 * uint64_t size - object size
2255 *
2256 * Sends object to Responder.
2257 *
2258 * Return values: Some PTP_RC_* code.
2259 *
2260 */
2261 uint16_t
2262 ptp_sendobject (PTPParams* params, unsigned char* object, uint64_t size)
2263 {
2264 PTPContainer ptp;
2265
2266 PTP_CNT_INIT(ptp, PTP_OC_SendObject);
2267 return ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, &object, NULL);
2268 }
2269
2270 /**
2271 * ptp_sendobject_from_handler:
2272 * params: PTPParams*
2273 * PTPDataHandler* - File descriptor to read() object from
2274 * uint64_t size - File/object size
2275 *
2276 * Sends object from file descriptor by consecutive reads from this
2277 * descriptor.
2278 *
2279 * Return values: Some PTP_RC_* code.
2280 **/
2281 uint16_t
2282 ptp_sendobject_from_handler (PTPParams* params, PTPDataHandler *handler, uint64_t size)
2283 {
2284 PTPContainer ptp;
2285
2286 PTP_CNT_INIT(ptp, PTP_OC_SendObject);
2287 return ptp_transaction_new(params, &ptp, PTP_DP_SENDDATA, size, handler);
2288 }
2289
2290
2291 /**
2292 * ptp_sendobject_fromfd:
2293 * params: PTPParams*
2294 * fd - File descriptor to read() object from
2295 * uint64_t size - File/object size
2296 *
2297 * Sends object from file descriptor by consecutive reads from this
2298 * descriptor.
2299 *
2300 * Return values: Some PTP_RC_* code.
2301 **/
2302 uint16_t
2303 ptp_sendobject_fromfd (PTPParams* params, int fd, uint64_t size)
2304 {
2305 PTPContainer ptp;
2306 PTPDataHandler handler;
2307 uint16_t ret;
2308
2309 PTP_CNT_INIT(ptp, PTP_OC_SendObject);
2310 ptp_init_fd_handler (&handler, fd);
2311 ret = ptp_transaction_new(params, &ptp, PTP_DP_SENDDATA, size, &handler);
2312 ptp_exit_fd_handler (&handler);
2313 return ret;
2314 }
2315
2316 #define PROPCACHE_TIMEOUT 5 /* seconds */
2317
2318 uint16_t
2319 ptp_getdevicepropdesc (PTPParams* params, uint16_t propcode,
2320 PTPDevicePropDesc* devicepropertydesc)
2321 {
2322 PTPContainer ptp;
2323 uint16_t ret = PTP_RC_OK;
2324 unsigned char *data = NULL;
2325 unsigned int size, newoffset;
2326
2327 PTP_CNT_INIT(ptp, PTP_OC_GetDevicePropDesc, propcode);
2328 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size));
2329
2330 if (!data) {
2331 ptp_debug (params, "no data received for getdevicepropdesc");
2332 return PTP_RC_InvalidDevicePropFormat;
2333 }
2334
2335 if (params->device_flags & DEVICE_FLAG_OLYMPUS_XML_WRAPPED) {
2336 #ifdef HAVE_LIBXML2
2337 xmlNodePtr code;
2338
2339 ret = ptp_olympus_parse_output_xml (params,(char*)data,size,&code);
2340 if (ret == PTP_RC_OK) {
2341 int x;
2342
2343 if ( (xmlChildElementCount(code) == 1) &&
2344 (!strcmp((char*)code->name,"c1014"))
2345 ) {
2346 code = xmlFirstElementChild (code);
2347
2348 if ( (sscanf((char*)code->name,"p%x", &x)) &&
2349 (x == propcode)
2350 ) {
2351 ret = parse_9301_propdesc (params, xmlFirstElementChild (code), devicepropertydesc);
2352 xmlFreeDoc(code->doc);
2353 }
2354 }
2355 } else {
2356 ptp_debug(params,"failed to parse output xml, ret %x?", ret);
2357 }
2358 #endif
2359 } else {
2360 if (!ptp_unpack_DPD(params, data, devicepropertydesc, size, &newoffset)) {
2361 ptp_debug(params,"failed to unpack DPD of propcode 0x%04x, likely corrupted?", propcode);
2362 free (data);
2363 return PTP_RC_InvalidDevicePropFormat;
2364 }
2365 }
2366 free(data);
2367 return ret;
2368 }
2369
2370
2371 uint16_t
2372 ptp_getdevicepropvalue (PTPParams* params, uint16_t propcode,
2373 PTPPropertyValue* value, uint16_t datatype)
2374 {
2375 PTPContainer ptp;
2376 unsigned char *data = NULL;
2377 unsigned int size, offset = 0;
2378 uint16_t ret;
2379
2380 PTP_CNT_INIT(ptp, PTP_OC_GetDevicePropValue, propcode);
2381 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size));
2382 ret = ptp_unpack_DPV(params, data, &offset, size, value, datatype) ? PTP_RC_OK : PTP_RC_GeneralError;
2383 if (ret != PTP_RC_OK)
2384 ptp_debug (params, "ptp_getdevicepropvalue: unpacking DPV failed");
2385 free(data);
2386 return ret;
2387 }
2388
2389 uint16_t
2390 ptp_setdevicepropvalue (PTPParams* params, uint16_t propcode,
2391 PTPPropertyValue *value, uint16_t datatype)
2392 {
2393 PTPContainer ptp;
2394 uint16_t ret;
2395 unsigned char *data = NULL;
2396 uint32_t size;
2397
2398 PTP_CNT_INIT(ptp, PTP_OC_SetDevicePropValue, propcode);
2399 size=ptp_pack_DPV(params, value, &data, datatype);
2400 ret=ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, &data, NULL);
2401 free(data);
2402 return ret;
2403 }
2404
2405 /**
2406 * ptp_ek_sendfileobjectinfo:
2407 * params: PTPParams*
2408 * uint32_t* store - destination StorageID on Responder
2409 * uint32_t* parenthandle - Parent ObjectHandle on responder
2410 * uint32_t* handle - see Return values
2411 * PTPObjectInfo* objectinfo- ObjectInfo that is to be sent
2412 *
2413 * Sends ObjectInfo of file that is to be sent via SendFileObject.
2414 *
2415 * Return values: Some PTP_RC_* code.
2416 * Upon success : uint32_t* store - Responder StorageID in which
2417 * object will be stored
2418 * uint32_t* parenthandle- Responder Parent ObjectHandle
2419 * in which the object will be stored
2420 * uint32_t* handle - Responder's reserved ObjectHandle
2421 * for the incoming object
2422 **/
2423 uint16_t
2424 ptp_ek_sendfileobjectinfo (PTPParams* params, uint32_t* store,
2425 uint32_t* parenthandle, uint32_t* handle,
2426 PTPObjectInfo* objectinfo)
2427 {
2428 PTPContainer ptp;
2429 uint16_t ret;
2430 unsigned char *data = NULL;
2431 uint32_t size;
2432
2433 PTP_CNT_INIT(ptp, PTP_OC_EK_SendFileObjectInfo, *store, *parenthandle);
2434 size=ptp_pack_OI(params, objectinfo, &data);
2435 ret=ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, &data, NULL);
2436 free(data);
2437 *store=ptp.Param1;
2438 *parenthandle=ptp.Param2;
2439 *handle=ptp.Param3;
2440 return ret;
2441 }
2442
2443 /**
2444 * ptp_ek_getserial:
2445 * params: PTPParams*
2446 * char** serial - contains the serial number of the camera
2447 * uint32_t* size - contains the string length
2448 *
2449 * Gets the serial number from the device. (ptp serial)
2450 *
2451 * Return values: Some PTP_RC_* code.
2452 *
2453 */
2454 uint16_t
2455 ptp_ek_getserial (PTPParams* params, unsigned char **data, unsigned int *size)
2456 {
2457 PTPContainer ptp;
2458
2459 PTP_CNT_INIT(ptp, PTP_OC_EK_GetSerial);
2460 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, data, size);
2461 }
2462
2463 /**
2464 * ptp_ek_setserial:
2465 * params: PTPParams*
2466 * char* serial - contains the new serial number
2467 * uint32_t size - string length
2468 *
2469 * Sets the serial number of the device. (ptp serial)
2470 *
2471 * Return values: Some PTP_RC_* code.
2472 *
2473 */
2474 uint16_t
2475 ptp_ek_setserial (PTPParams* params, unsigned char *data, unsigned int size)
2476 {
2477 PTPContainer ptp;
2478
2479 PTP_CNT_INIT(ptp, PTP_OC_EK_SetSerial);
2480 return ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, &data, NULL);
2481 }
2482
2483 /* unclear what it does yet */
2484 uint16_t
2485 ptp_ek_9007 (PTPParams* params, unsigned char **data, unsigned int *size)
2486 {
2487 PTPContainer ptp;
2488
2489 PTP_CNT_INIT(ptp, 0x9007);
2490 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, data, size);
2491 }
2492
2493 /* unclear what it does yet */
2494 uint16_t
2495 ptp_ek_9009 (PTPParams* params, uint32_t *p1, uint32_t *p2)
2496 {
2497 PTPContainer ptp;
2498
2499 PTP_CNT_INIT(ptp, 0x9009);
2500 *p1 = *p2 = 0;
2501 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL));
2502 *p1 = ptp.Param1;
2503 *p2 = ptp.Param2;
2504 return PTP_RC_OK;
2505 }
2506
2507 /* unclear yet, but I guess it returns the info from 9008 */
2508 uint16_t
2509 ptp_ek_900c (PTPParams* params, unsigned char **data, unsigned int *size)
2510 {
2511 PTPContainer ptp;
2512
2513 PTP_CNT_INIT(ptp, 0x900c);
2514 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, data, size);
2515 /* returned data is 16bit,16bit,32bit,32bit */
2516 }
2517
2518 /**
2519 * ptp_ek_settext:
2520 * params: PTPParams*
2521 * PTPEKTextParams* - contains the texts to display.
2522 *
2523 * Displays the specified texts on the TFT of the camera.
2524 *
2525 * Return values: Some PTP_RC_* code.
2526 *
2527 */
2528 uint16_t
2529 ptp_ek_settext (PTPParams* params, PTPEKTextParams *text)
2530 {
2531 PTPContainer ptp;
2532 uint16_t ret;
2533 unsigned char *data = 0;
2534 uint32_t size;
2535
2536 PTP_CNT_INIT(ptp, PTP_OC_EK_SetText);
2537 if (0 == (size = ptp_pack_EK_text(params, text, &data)))
2538 return PTP_ERROR_BADPARAM;
2539 ret = ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, &data, NULL);
2540 free(data);
2541 return ret;
2542 }
2543
2544 /**
2545 * ptp_ek_sendfileobject:
2546 * params: PTPParams*
2547 * char* object - contains the object that is to be sent
2548 * uint32_t size - object size
2549 *
2550 * Sends object to Responder.
2551 *
2552 * Return values: Some PTP_RC_* code.
2553 *
2554 */
2555 uint16_t
2556 ptp_ek_sendfileobject (PTPParams* params, unsigned char* object, uint32_t size)
2557 {
2558 PTPContainer ptp;
2559
2560 PTP_CNT_INIT(ptp, PTP_OC_EK_SendFileObject);
2561 return ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, &object, NULL);
2562 }
2563
2564 /**
2565 * ptp_ek_sendfileobject_from_handler:
2566 * params: PTPParams*
2567 * PTPDataHandler* handler - contains the handler of the object that is to be sent
2568 * uint32_t size - object size
2569 *
2570 * Sends object to Responder.
2571 *
2572 * Return values: Some PTP_RC_* code.
2573 *
2574 */
2575 uint16_t
2576 ptp_ek_sendfileobject_from_handler (PTPParams* params, PTPDataHandler*handler, uint32_t size)
2577 {
2578 PTPContainer ptp;
2579
2580 PTP_CNT_INIT(ptp, PTP_OC_EK_SendFileObject);
2581 return ptp_transaction_new(params, &ptp, PTP_DP_SENDDATA, size, handler);
2582 }
2583
2584 /*************************************************************************
2585 *
2586 * Canon PTP extensions support
2587 *
2588 * (C) Nikolai Kopanygin 2003
2589 *
2590 *************************************************************************/
2591
2592
2593 /**
2594 * ptp_canon_getpartialobjectinfo:
2595 * params: PTPParams*
2596 * uint32_t handle - ObjectHandle
2597 * uint32_t p2 - Not fully understood parameter
2598 * 0 - returns full size
2599 * 1 - returns thumbnail size (or EXIF?)
2600 *
2601 * Gets form the responder the size of the specified object.
2602 *
2603 * Return values: Some PTP_RC_* code.
2604 * Upon success : uint32_t* size - The object size
2605 * uint32_t* rp2 - Still unknown return parameter
2606 * (perhaps upper 32bit of size)
2607 *
2608 *
2609 **/
2610 uint16_t
2611 ptp_canon_getpartialobjectinfo (PTPParams* params, uint32_t handle, uint32_t p2,
2612 uint32_t* size, uint32_t* rp2)
2613 {
2614 PTPContainer ptp;
2615
2616 PTP_CNT_INIT(ptp, PTP_OC_CANON_GetPartialObjectInfo, handle, p2);
2617 *size = *rp2 = 0;
2618 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL));
2619 *size=ptp.Param1;
2620 *rp2=ptp.Param2;
2621 return PTP_RC_OK;
2622 }
2623
2624 /**
2625 * ptp_canon_get_mac_address:
2626 * params: PTPParams*
2627 * value 0 works.
2628 * Gets the MAC address of the wireless transmitter.
2629 *
2630 * Return values: Some PTP_RC_* code.
2631 * Upon success : unsigned char* mac - The MAC address
2632 *
2633 **/
2634 uint16_t
2635 ptp_canon_get_mac_address (PTPParams* params, unsigned char **mac)
2636 {
2637 PTPContainer ptp;
2638
2639 PTP_CNT_INIT(ptp, PTP_OC_CANON_GetMACAddress);
2640 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, mac, NULL);
2641 }
2642
2643 /**
2644 * ptp_canon_get_directory:
2645 * params: PTPParams*
2646
2647 * Gets the full directory of the camera.
2648 *
2649 * Return values: Some PTP_RC_* code.
2650 * Upon success : PTPObjectHandles *handles - filled out with handles
2651 * PTPObjectInfo **oinfos - allocated array of PTP Object Infos
2652 * uint32_t **flags - allocated array of CANON Flags
2653 *
2654 **/
2655 uint16_t
2656 ptp_canon_get_directory (PTPParams* params,
2657 PTPObjectHandles *handles,
2658 PTPObjectInfo **oinfos, /* size(handles->n) */
2659 uint32_t **flags /* size(handles->n) */
2660 ) {
2661 PTPContainer ptp;
2662 unsigned char *data = NULL;
2663 uint16_t ret;
2664
2665 PTP_CNT_INIT(ptp, PTP_OC_CANON_GetDirectory);
2666 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, NULL));
2667 ret = ptp_unpack_canon_directory(params, data, ptp.Param1, handles, oinfos, flags);
2668 free (data);
2669 return ret;
2670 }
2671
2672 /**
2673 * ptp_canon_gettreeinfo:
2674 * params: PTPParams*
2675 * uint32_t *out
2676 *
2677 * Switches the camera display to on and lets the user
2678 * select what to transfer. Sends a 0xc011 event when started
2679 * and 0xc013 if direct transfer aborted.
2680 *
2681 * Return values: Some PTP_RC_* code.
2682 *
2683 **/
2684 uint16_t
2685 ptp_canon_gettreeinfo (PTPParams* params, uint32_t *out)
2686 {
2687 PTPContainer ptp;
2688
2689 PTP_CNT_INIT(ptp, PTP_OC_CANON_GetTreeInfo, 0xf);
2690 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL));
2691 if (ptp.Nparam > 0)
2692 *out = ptp.Param1;
2693 return PTP_RC_OK;
2694 }
2695
2696 /**
2697 * ptp_canon_getpairinginfo:
2698 * params: PTPParams*
2699 * int nr
2700 *
2701 * Get the pairing information.
2702 *
2703 * Return values: Some PTP_RC_* code.
2704 *
2705 **/
2706 uint16_t
2707 ptp_canon_getpairinginfo (PTPParams* params, uint32_t nr, unsigned char **data, unsigned int *size)
2708 {
2709 PTPContainer ptp;
2710
2711 PTP_CNT_INIT(ptp, PTP_OC_CANON_GetPairingInfo, nr);
2712 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, data, size);
2713 }
2714
2715 /**
2716 * ptp_canon_get_target_handles:
2717 * params: PTPParams*
2718 * PTPCanon_directtransfer_entry **out
2719 * unsigned int *outsize
2720 *
2721 * Retrieves direct transfer entries specifying the images to transfer
2722 * from the camera (to be retrieved after 0xc011 event).
2723 *
2724 * Return values: Some PTP_RC_* code.
2725 *
2726 **/
2727 uint16_t
2728 ptp_canon_gettreesize (PTPParams* params,
2729 PTPCanon_directtransfer_entry **entries, unsigned int *cnt)
2730 {
2731 PTPContainer ptp;
2732 uint16_t ret = PTP_RC_OK;
2733 unsigned char *data = NULL, *cur;
2734 unsigned int size, i;
2735
2736 PTP_CNT_INIT(ptp, PTP_OC_CANON_GetTreeSize);
2737 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size));
2738 *cnt = dtoh32a(data);
2739 *entries = calloc(sizeof(PTPCanon_directtransfer_entry),(*cnt));
2740 if (!*entries) {
2741 ret = PTP_RC_GeneralError;
2742 goto exit;
2743 }
2744 cur = data+4;
2745 for (i=0;i<*cnt;i++) {
2746 unsigned char len;
2747 (*entries)[i].oid = dtoh32a(cur);
2748 if (!ptp_unpack_string(params, cur, 4, size-(cur-data-4), &len, &(*entries)[i].str))
2749 break;
2750 cur += 4+(cur[4]*2+1);
2751 }
2752 exit:
2753 free (data);
2754 return ret;
2755 }
2756
2757 /**
2758 * ptp_canon_checkevent:
2759 * params: PTPParams*
2760 *
2761 * The camera has a FIFO stack, in which it accumulates events.
2762 * Partially these events are communicated also via the USB interrupt pipe
2763 * according to the PTP USB specification, partially not.
2764 * This operation returns from the device a block of data, empty,
2765 * if the event stack is empty, or filled with an event's data otherwise.
2766 * The event is removed from the stack in the latter case.
2767 * The Remote Capture app sends this command to the camera all the time
2768 * of connection, filling with it the gaps between other operations.
2769 *
2770 * Return values: Some PTP_RC_* code.
2771 * Upon success : PTPUSBEventContainer* event - is filled with the event data
2772 * if any
2773 * int *isevent - returns 1 in case of event
2774 * or 0 otherwise
2775 **/
2776 uint16_t
2777 ptp_canon_checkevent (PTPParams* params, PTPContainer* event, int* isevent)
2778 {
2779 PTPContainer ptp;
2780 unsigned char *data = NULL;
2781 unsigned int size;
2782
2783 PTP_CNT_INIT(ptp, PTP_OC_CANON_CheckEvent);
2784 *isevent=0;
2785 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size));
2786 if (data && size) { /* check if we had a successful call with data */
2787 ptp_unpack_EC(params, data, event, size);
2788 *isevent=1;
2789 free(data);
2790 }
2791 return PTP_RC_OK;
2792 }
2793
2794 uint16_t
2795 ptp_add_event (PTPParams *params, PTPContainer *evt)
2796 {
2797 params->events = realloc(params->events, sizeof(PTPContainer)*(params->nrofevents+1));
2798 memcpy (¶ms->events[params->nrofevents],evt,1*sizeof(PTPContainer));
2799 params->nrofevents += 1;
2800 return PTP_RC_OK;
2801 }
2802
2803 /* CANON EOS fast directory mode */
2804 /* FIXME: incomplete ... needs storage mode retrieval support too (storage == 0xffffffff) */
2805 static uint16_t
2806 ptp_list_folder_eos (PTPParams *params, uint32_t storage, uint32_t handle) {
2807 unsigned int k, i, j, last, changed;
2808 PTPCANONFolderEntry *tmp = NULL;
2809 unsigned int nroftmp = 0;
2810 uint16_t ret;
2811 PTPStorageIDs storageids;
2812 PTPObject *ob;
2813
2814 if ((handle != 0xffffffff) && (handle != 0)) {
2815 ret = ptp_object_want (params, handle, PTPOBJECT_OBJECTINFO_LOADED, &ob);
2816 if ((ret == PTP_RC_OK) && (ob->flags & PTPOBJECT_DIRECTORY_LOADED))
2817 return PTP_RC_OK;
2818 }
2819
2820 if (storage == 0xffffffff) {
2821 if (handle != 0xffffffff)
2822 handle = 0xffffffff;
2823 ret = ptp_getstorageids(params, &storageids);
2824 if (ret != PTP_RC_OK)
2825 return ret;
2826 } else {
2827 storageids.n = 1;
2828 storageids.Storage = malloc(sizeof(storageids.Storage[0]));
2829 storageids.Storage[0] = storage;
2830 }
2831 last = changed = 0;
2832
2833 for (k=0;k<storageids.n;k++) {
2834 if ((storageids.Storage[k] & 0xffff) == 0) {
2835 ptp_debug (params, "reading directory, storage 0x%08x skipped (invalid)", storageids.Storage[k]);
2836 continue;
2837 }
2838 ptp_debug (params, "reading handle %08x directory of 0x%08x", storageids.Storage[k], handle);
2839 tmp = NULL;
2840 ret = ptp_canon_eos_getobjectinfoex (
2841 params, storageids.Storage[k], handle ? handle : 0xffffffff, 0x100000, &tmp, &nroftmp);
2842 if (ret != PTP_RC_OK) {
2843 ptp_error (params, "error 0x%04x", ret);
2844 free (storageids.Storage);
2845 return ret;
2846 }
2847 /* convert read entries into objectinfos */
2848 for (i=0;i<nroftmp;i++) {
2849 PTPObject *newobs;
2850
2851 ob = NULL;
2852 for (j=0;j<params->nrofobjects;j++) {
2853 if (params->objects[(last+j)%params->nrofobjects].oid == tmp[i].ObjectHandle) {
2854 ob = ¶ms->objects[(last+j)%params->nrofobjects];
2855 break;
2856 }
2857 }
2858 if (j == params->nrofobjects) {
2859 ptp_debug (params, "adding new objectid 0x%08x (nrofobs=%d,j=%d)", tmp[i].ObjectHandle, params->nrofobjects,j);
2860 newobs = realloc (params->objects,sizeof(PTPObject)*(params->nrofobjects+1));
2861 if (!newobs) {
2862 free (tmp);
2863 free (storageids.Storage);
2864 return PTP_RC_GeneralError;
2865 }
2866 params->objects = newobs;
2867 memset (¶ms->objects[params->nrofobjects],0,sizeof(params->objects[params->nrofobjects]));
2868 params->objects[params->nrofobjects].oid = tmp[i].ObjectHandle;
2869 params->objects[params->nrofobjects].flags = 0;
2870
2871 params->objects[params->nrofobjects].oi.StorageID = storageids.Storage[k];
2872 params->objects[params->nrofobjects].flags |= PTPOBJECT_STORAGEID_LOADED;
2873 if (handle == 0xffffffff)
2874 params->objects[params->nrofobjects].oi.ParentObject = 0;
2875 else
2876 params->objects[params->nrofobjects].oi.ParentObject = handle;
2877 params->objects[params->nrofobjects].flags |= PTPOBJECT_PARENTOBJECT_LOADED;
2878 params->objects[params->nrofobjects].oi.Filename = strdup(tmp[i].Filename);
2879 params->objects[params->nrofobjects].oi.ObjectFormat = tmp[i].ObjectFormatCode;
2880
2881 ptp_debug (params, " flags %x", tmp[i].Flags);
2882 if (tmp[i].Flags & 0x1)
2883 params->objects[params->nrofobjects].oi.ProtectionStatus = PTP_PS_ReadOnly;
2884 else
2885 params->objects[params->nrofobjects].oi.ProtectionStatus = PTP_PS_NoProtection;
2886 params->objects[params->nrofobjects].canon_flags = tmp[i].Flags;
2887 params->objects[params->nrofobjects].oi.ObjectCompressedSize = tmp[i].ObjectSize;
2888 params->objects[params->nrofobjects].oi.CaptureDate = tmp[i].Time;
2889 params->objects[params->nrofobjects].oi.ModificationDate = tmp[i].Time;
2890 params->objects[params->nrofobjects].flags |= PTPOBJECT_OBJECTINFO_LOADED;
2891
2892 /*debug_objectinfo(params, tmp[i].ObjectHandle, ¶ms->objects[params->nrofobjects].oi);*/
2893 last = params->nrofobjects;
2894 params->nrofobjects++;
2895 changed = 1;
2896 } else {
2897 ptp_debug (params, "adding old objectid 0x%08x (nrofobs=%d,j=%d)", tmp[i].ObjectHandle, params->nrofobjects,j);
2898 ob = ¶ms->objects[(last+j)%params->nrofobjects];
2899 /* for speeding up search */
2900 last = (last+j)%params->nrofobjects;
2901 if (handle != PTP_HANDLER_SPECIAL) {
2902 ob->oi.ParentObject = handle;
2903 ob->flags |= PTPOBJECT_PARENTOBJECT_LOADED;
2904 }
2905 if (storageids.Storage[k] != PTP_HANDLER_SPECIAL) {
2906 ob->oi.StorageID = storageids.Storage[k];
2907 ob->flags |= PTPOBJECT_STORAGEID_LOADED;
2908 }
2909 }
2910 }
2911 free (tmp);
2912 }
2913 if (changed) ptp_objects_sort (params);
2914
2915 /* Do not cache ob, it might be reallocated and have a new address */
2916 if (handle != 0xffffffff) {
2917 ret = ptp_object_want (params, handle, PTPOBJECT_OBJECTINFO_LOADED, &ob);
2918 if (ret == PTP_RC_OK)
2919 ob->flags |= PTPOBJECT_DIRECTORY_LOADED;
2920 }
2921 free (storageids.Storage);
2922 return PTP_RC_OK;
2923 }
2924
2925 uint16_t
2926 ptp_list_folder (PTPParams *params, uint32_t storage, uint32_t handle) {
2927 unsigned int i, changed, last;
2928 uint16_t ret;
2929 uint32_t xhandle = handle;
2930 PTPObject *newobs;
2931 PTPObjectHandles handles;
2932
2933 ptp_debug (params, "(storage=0x%08x, handle=0x%08x)", storage, handle);
2934 /* handle=0 is only not read when there is no object in the list yet
2935 * and we do the initial read. */
2936 if (!handle && params->nrofobjects)
2937 return PTP_RC_OK;
2938 /* but we can override this to read 0 object of storages */
2939 if (handle == PTP_HANDLER_SPECIAL)
2940 handle = 0;
2941
2942 /* Canon EOS Fast directory strategy */
2943 if ((params->deviceinfo.VendorExtensionID == PTP_VENDOR_CANON) &&
2944 ptp_operation_issupported(params, PTP_OC_CANON_EOS_GetObjectInfoEx)) {
2945 ret = ptp_list_folder_eos (params, storage, handle);
2946 if (ret == PTP_RC_OK)
2947 return ret;
2948 }
2949
2950 if (handle) { /* 0 is the virtual root */
2951 PTPObject *ob;
2952 /* first check if object itself is loaded, and get its objectinfo. */
2953 ret = ptp_object_want (params, handle, PTPOBJECT_OBJECTINFO_LOADED, &ob);
2954 if (ret != PTP_RC_OK)
2955 return ret;
2956 if (ob->oi.ObjectFormat != PTP_OFC_Association)
2957 return PTP_RC_GeneralError;
2958 if (ob->flags & PTPOBJECT_DIRECTORY_LOADED) return PTP_RC_OK;
2959 ob->flags |= PTPOBJECT_DIRECTORY_LOADED;
2960 /*debug_objectinfo(params, handle, &ob->oi);*/
2961 }
2962
2963 #if 0 /* apple devices report it, but the conrtent they have does not match the standard somehow. Neesd further debugging */
2964 if (ptp_operation_issupported(params, PTP_OC_GetFilesystemManifest)) {
2965 uint64_t numoifs = 0;
2966 PTPObjectFilesystemInfo *oifs = NULL;
2967
2968 if (storage == PTP_HANDLER_SPECIAL) storage = 0;
2969 ret = ptp_getfilesystemmanifest (params, storage, 0, handle, &numoifs, &oifs);
2970 if (ret != PTP_RC_OK || !numoifs)
2971 goto fallback;
2972
2973 last = changed = 0;
2974 for (i=0;i<numoifs;i++) {
2975 PTPObject *ob;
2976 unsigned int j;
2977
2978 ob = NULL;
2979 for (j=0;j<params->nrofobjects;j++) {
2980 if (params->objects[(last+j)%params->nrofobjects].oid == oifs[i].ObjectHandle) {
2981 ob = ¶ms->objects[(last+j)%params->nrofobjects];
2982 break;
2983 }
2984 }
2985 if (j == params->nrofobjects) {
2986 ptp_debug (params, "adding new objectid 0x%08x (nrofobs=%d,j=%d)", oifs[i].ObjectHandle, params->nrofobjects,j);
2987 newobs = realloc (params->objects,sizeof(PTPObject)*(params->nrofobjects+1));
2988 if (!newobs) {
2989 free (oifs);
2990 return PTP_RC_GeneralError;
2991 }
2992 params->objects = newobs;
2993 memset (¶ms->objects[params->nrofobjects],0,sizeof(params->objects[params->nrofobjects]));
2994 params->objects[params->nrofobjects].oid = oifs[i].ObjectHandle;
2995 params->objects[params->nrofobjects].flags = 0;
2996 ob = ¶ms->objects[params->nrofobjects];
2997 params->nrofobjects++;
2998 changed = 1;
2999 } else {
3000 ptp_debug (params, "adding old objectid 0x%08x (nrofobs=%d,j=%d)", oifs[i].ObjectHandle, params->nrofobjects,j);
3001 ob = ¶ms->objects[(last+j)%params->nrofobjects];
3002 /* for speeding up search */
3003 last = (last+j)%params->nrofobjects;
3004 }
3005
3006 ob->oi.StorageID = oifs[i].StorageID;
3007 ob->oi.ObjectFormat = oifs[i].ObjectFormat;
3008 ob->oi.ProtectionStatus = oifs[i].ProtectionStatus;
3009 ob->oi.ObjectCompressedSize = oifs[i].ObjectCompressedSize64;
3010 ob->oi.ParentObject = oifs[i].ParentObject;
3011
3012 /* bad iOS, returns StorageID instead of 0x0 */
3013 if (ob->oi.ParentObject == oifs[i].StorageID) {
3014 ptp_debug (params, "objectid 0x%08x aka %s has parent %08x, rewriting to 0", oifs[i].ObjectHandle, oifs[i].Filename, oifs[i].ParentObject);
3015 ob->oi.ParentObject = 0;
3016 }
3017
3018 ob->oi.AssociationType = oifs[i].AssociationType;
3019 ob->oi.AssociationDesc = oifs[i].AssociationDesc;
3020 ob->oi.SequenceNumber = oifs[i].SequenceNumber;
3021 ob->oi.Filename = oifs[i].Filename; /* hand over memory ownership */
3022 ob->oi.ModificationDate = oifs[i].ModificationDate;
3023 /* FIXME: most of it ... but not the image sizes */
3024 ob->flags |= PTPOBJECT_OBJECTINFO_LOADED|PTPOBJECT_STORAGEID_LOADED|PTPOBJECT_PARENTOBJECT_LOADED;
3025 }
3026 free (oifs);
3027 if (changed) ptp_objects_sort (params);
3028 return PTP_RC_OK;
3029 }
3030 fallback:
3031 #endif
3032
3033 ptp_debug (params, "Listing ... ");
3034 if (handle == 0) xhandle = PTP_HANDLER_SPECIAL; /* 0 would mean all */
3035 ret = ptp_getobjecthandles (params, storage, 0, xhandle, &handles);
3036 if (ret == PTP_RC_ParameterNotSupported) {/* try without storage */
3037 storage = PTP_HANDLER_SPECIAL;
3038 ret = ptp_getobjecthandles (params, PTP_HANDLER_SPECIAL, 0, xhandle, &handles);
3039 }
3040 if (ret == PTP_RC_ParameterNotSupported) { /* fall back to always supported method */
3041 xhandle = PTP_HANDLER_SPECIAL;
3042 handle = PTP_HANDLER_SPECIAL;
3043 ret = ptp_getobjecthandles (params, PTP_HANDLER_SPECIAL, 0, 0, &handles);
3044 }
3045 if (ret != PTP_RC_OK)
3046 return ret;
3047 last = changed = 0;
3048 for (i=0;i<handles.n;i++) {
3049 PTPObject *ob;
3050 unsigned int j;
3051
3052 ob = NULL;
3053 for (j=0;j<params->nrofobjects;j++) {
3054 if (params->objects[(last+j)%params->nrofobjects].oid == handles.Handler[i]) {
3055 ob = ¶ms->objects[(last+j)%params->nrofobjects];
3056 break;
3057 }
3058 }
3059 if (j == params->nrofobjects) {
3060 ptp_debug (params, "adding new objectid 0x%08x (nrofobs=%d,j=%d)", handles.Handler[i], params->nrofobjects,j);
3061 newobs = realloc (params->objects,sizeof(PTPObject)*(params->nrofobjects+1));
3062 if (!newobs) return PTP_RC_GeneralError;
3063 params->objects = newobs;
3064 memset (¶ms->objects[params->nrofobjects],0,sizeof(params->objects[params->nrofobjects]));
3065 params->objects[params->nrofobjects].oid = handles.Handler[i];
3066 params->objects[params->nrofobjects].flags = 0;
3067 /* root directory list files might return all files, so avoid tagging it */
3068 if (handle != PTP_HANDLER_SPECIAL && handle) {
3069 ptp_debug (params, " parenthandle 0x%08x", handle);
3070 if (handles.Handler[i] == handle) { /* EOS bug where oid == parent(oid) */
3071 params->objects[params->nrofobjects].oi.ParentObject = 0;
3072 } else {
3073 params->objects[params->nrofobjects].oi.ParentObject = handle;
3074 }
3075 params->objects[params->nrofobjects].flags |= PTPOBJECT_PARENTOBJECT_LOADED;
3076 }
3077 if (storage != PTP_HANDLER_SPECIAL) {
3078 ptp_debug (params, " storage 0x%08x", storage);
3079 params->objects[params->nrofobjects].oi.StorageID = storage;
3080 params->objects[params->nrofobjects].flags |= PTPOBJECT_STORAGEID_LOADED;
3081 }
3082 params->nrofobjects++;
3083 changed = 1;
3084 } else {
3085 ptp_debug (params, "adding old objectid 0x%08x (nrofobs=%d,j=%d)", handles.Handler[i], params->nrofobjects,j);
3086 ob = ¶ms->objects[(last+j)%params->nrofobjects];
3087 /* for speeding up search */
3088 last = (last+j)%params->nrofobjects;
3089 if (handle != PTP_HANDLER_SPECIAL) {
3090 ob->oi.ParentObject = handle;
3091 ob->flags |= PTPOBJECT_PARENTOBJECT_LOADED;
3092 }
3093 if (storage != PTP_HANDLER_SPECIAL) {
3094 ob->oi.StorageID = storage;
3095 ob->flags |= PTPOBJECT_STORAGEID_LOADED;
3096 }
3097 }
3098 }
3099 free (handles.Handler);
3100 if (changed) ptp_objects_sort (params);
3101 return PTP_RC_OK;
3102 }
3103
3104
3105 static void
3106 handle_event_internal (PTPParams *params, PTPContainer *event)
3107 {
3108 /* handle some PTP stack internal events */
3109 switch (event->Code) {
3110 case PTP_EC_DevicePropChanged: {
3111 unsigned int i;
3112
3113 /* mark the property for a forced refresh on the next query */
3114 for (i=0;i<params->nrofdeviceproperties;i++)
3115 if (params->deviceproperties[i].desc.DevicePropertyCode == event->Param1) {
3116 params->deviceproperties[i].timestamp = 0;
3117 break;
3118 }
3119 break;
3120 }
3121 case PTP_EC_StoreAdded:
3122 case PTP_EC_StoreRemoved: {
3123 unsigned int i;
3124
3125 /* FIXME: if we just remove 1 out of many storages, we do not need to invalidate/reload the entire tree? */
3126
3127 /* refetch storage IDs and also invalidate whole object tree */
3128 free (params->storageids.Storage);
3129 params->storageids.Storage = NULL;
3130 params->storageids.n = 0;
3131 ptp_getstorageids (params, ¶ms->storageids);
3132
3133 /* free object storage as it might be associated with the storage ids */
3134 /* FIXME: enhance and just delete the ones from the storage */
3135 for (i=0;i<params->nrofobjects;i++)
3136 ptp_free_object (¶ms->objects[i]);
3137 free (params->objects);
3138 params->objects = NULL;
3139 params->nrofobjects = 0;
3140
3141 params->storagechanged = 1;
3142 /* mirror what we do in camera_init, fetch root directory entries. */
3143 if (params->deviceinfo.VendorExtensionID != PTP_VENDOR_SONY)
3144 ptp_list_folder (params, PTP_HANDLER_SPECIAL, PTP_HANDLER_SPECIAL);
3145
3146 {
3147 unsigned int k;
3148
3149 for (k=0;k<params->storageids.n;k++) {
3150 if (!(params->storageids.Storage[k] & 0xffff)) continue;
3151 if (params->storageids.Storage[k] == 0x80000001) continue;
3152 ptp_list_folder (params, params->storageids.Storage[k], PTP_HANDLER_SPECIAL);
3153 }
3154 }
3155
3156 break;
3157 }
3158 default: /* check if we should handle it internally too */
3159 break;
3160 }
3161 }
3162
3163 uint16_t
3164 ptp_check_event_queue (PTPParams *params)
3165 {
3166 PTPContainer event;
3167 uint16_t ret;
3168
3169 /* We try to do a event check without I/O */
3170 /* Basically this means just looking at the meanwhile queued events */
3171
3172 ret = params->event_check_queue(params,&event);
3173
3174 if (ret == PTP_RC_OK) {
3175 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);
3176 ptp_add_event (params, &event);
3177 handle_event_internal (params, &event);
3178 }
3179 if (ret == PTP_ERROR_TIMEOUT) /* ok, just new events */
3180 ret = PTP_RC_OK;
3181 return ret;
3182 }
3183
3184 uint16_t
3185 ptp_check_event (PTPParams *params)
3186 {
3187 PTPContainer event;
3188 uint16_t ret;
3189
3190 if (params->deviceinfo.VendorExtensionID == PTP_VENDOR_NIKON) {
3191 if (ptp_operation_issupported(params, PTP_OC_NIKON_GetEventEx)) {
3192 unsigned int evtcnt = 0, i;
3193 PTPContainer *xevent = NULL;
3194
3195 ret = ptp_nikon_check_eventex(params, &xevent, &evtcnt);
3196 if (ret != PTP_RC_OperationNotSupported)
3197 CHECK_PTP_RC(ret);
3198
3199 if (evtcnt) {
3200 for (i = 0; i < evtcnt; i++)
3201 handle_event_internal (params, &xevent[i]);
3202 params->events = realloc(params->events, sizeof(PTPContainer)*(evtcnt+params->nrofevents));
3203 memcpy (¶ms->events[params->nrofevents],xevent,evtcnt*sizeof(PTPContainer));
3204 params->nrofevents += evtcnt;
3205 params->event90c7works = 1;
3206 }
3207 free (xevent);
3208 if (params->event90c7works)
3209 return PTP_RC_OK;
3210 /* fall through to generic event handling */
3211 } else {
3212 /* Method offered by Nikon DSLR, Nikon 1, and some older Nikon Coolpix P*
3213 * The Nikon Coolpix P2 however does not return anything. So if we never get
3214 * events from here, use the ptp "interrupt" method */
3215 if (ptp_operation_issupported(params, PTP_OC_NIKON_GetEvent)) {
3216 unsigned int evtcnt = 0, i;
3217 PTPContainer *xevent = NULL;
3218
3219 ret = ptp_nikon_check_event(params, &xevent, &evtcnt);
3220 if (ret != PTP_RC_OperationNotSupported)
3221 CHECK_PTP_RC(ret);
3222
3223 if (evtcnt) {
3224 for (i = 0; i < evtcnt; i++)
3225 handle_event_internal (params, &xevent[i]);
3226 params->events = realloc(params->events, sizeof(PTPContainer)*(evtcnt+params->nrofevents));
3227 memcpy (¶ms->events[params->nrofevents],xevent,evtcnt*sizeof(PTPContainer));
3228 params->nrofevents += evtcnt;
3229 params->event90c7works = 1;
3230 }
3231 free (xevent);
3232 if (params->event90c7works)
3233 return PTP_RC_OK;
3234 /* fall through to generic event handling */
3235 }
3236 }
3237 }
3238 /* should not get here ... EOS has no normal PTP events and another queue handling. */
3239 if ( (params->deviceinfo.VendorExtensionID == PTP_VENDOR_CANON) &&
3240 ptp_operation_issupported(params, PTP_OC_CANON_EOS_GetEvent)
3241 ) {
3242 return PTP_RC_OK;
3243 }
3244
3245 if ( (params->deviceinfo.VendorExtensionID == PTP_VENDOR_CANON) &&
3246 ptp_operation_issupported(params, PTP_OC_CANON_CheckEvent)
3247 ) {
3248 int isevent;
3249
3250 CHECK_PTP_RC(ptp_canon_checkevent (params,&event,&isevent));
3251
3252 if (isevent) {
3253 ret = PTP_RC_OK;
3254 goto store_event;
3255 }
3256 /* Event Emulate Mode 0 (unset) and 1-5 get interrupt events. 6-7 does not. */
3257 if (params->canon_event_mode > 5)
3258 return PTP_RC_OK;
3259
3260 /* FIXME: fallthrough or return? */
3261 #ifdef __APPLE__
3262 /* the libusb 1 on darwin currently does not like polling
3263 * for interrupts, they have no timeout for it. 2010/08/23
3264 * Check back in 2011 or so. -Marcus
3265 */
3266 return PTP_RC_OK;
3267 #endif
3268 }
3269 ret = params->event_check(params,&event);
3270
3271 store_event:
3272 if (ret == PTP_RC_OK) {
3273 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);
3274 ptp_add_event (params, &event);
3275
3276 handle_event_internal (params, &event);
3277
3278
3279 }
3280 if (ret == PTP_ERROR_TIMEOUT) /* ok, just new events */
3281 ret = PTP_RC_OK;
3282 return ret;
3283 }
3284
3285 uint16_t
3286 ptp_wait_event (PTPParams *params)
3287 {
3288 PTPContainer event;
3289 uint16_t ret;
3290
3291 ret = params->event_wait(params,&event);
3292 if (ret == PTP_RC_OK) {
3293 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);
3294 ptp_add_event (params, &event);
3295
3296 handle_event_internal (params, &event);
3297 }
3298 if (ret == PTP_ERROR_TIMEOUT) /* ok, just new events */
3299 ret = PTP_RC_OK;
3300 return ret;
3301 }
3302
3303 int
3304 ptp_get_one_event(PTPParams *params, PTPContainer *event)
3305 {
3306 if (!params->nrofevents)
3307 return 0;
3308 memcpy (event, params->events, sizeof(PTPContainer));
3309 memmove (params->events, params->events+1, sizeof(PTPContainer)*(params->nrofevents-1));
3310 /* do not realloc on shrink. */
3311 params->nrofevents--;
3312 if (!params->nrofevents) {
3313 free (params->events);
3314 params->events = NULL;
3315 }
3316 return 1;
3317 }
3318
3319 /**
3320 * ptp_get_one_event_by_type:
3321 *
3322 * Check if one specific event has appeared in the queue, and return it back to us, and remove it from the queue.
3323
3324 * params: PTPParams* in: params
3325 * code in: event code
3326 * event out: event container
3327 *
3328 * Return values: 1 if removed, 0 if not.
3329 */
3330 int
3331 ptp_get_one_event_by_type(PTPParams *params, uint16_t code, PTPContainer *event)
3332 {
3333 unsigned int i;
3334
3335 if (!params->nrofevents)
3336 return 0;
3337 for (i=0;i<params->nrofevents;i++) {
3338 if (params->events[i].Code == code) {
3339 memcpy (event, params->events+i, sizeof(PTPContainer));
3340 memmove (params->events+i, params->events+i+1, sizeof(PTPContainer)*(params->nrofevents-i-1));
3341 /* do not realloc on shrink. */
3342 params->nrofevents--;
3343 if (!params->nrofevents) {
3344 free (params->events);
3345 params->events = NULL;
3346 }
3347 return 1;
3348 }
3349 }
3350 return 0;
3351 }
3352
3353 /**
3354 * ptp_have_event:
3355 *
3356 * Check if one specific event has appeared in the queue, without draining it.
3357 *
3358 * params: PTPParams* in: params
3359 * code in: event code
3360 *
3361 * Return values: 1 if removed, 0 if not.
3362 */
3363 int
3364 ptp_have_event(PTPParams *params, uint16_t code)
3365 {
3366 unsigned int i;
3367
3368 if (!params->nrofevents)
3369 return 0;
3370 for (i=0;i<params->nrofevents;i++)
3371 if (params->events[i].Code == code)
3372 return 1;
3373 return 0;
3374 }
3375
3376 /**
3377 * ptp_canon_eos_getevent:
3378 *
3379 * This retrieves configuration status/updates/changes
3380 * on EOS cameras. It reads a datablock which has a list of variable
3381 * sized structures.
3382 *
3383 * params: PTPParams*
3384 *
3385 * Return values: Some PTP_RC_* code.
3386 *
3387 **/
3388 uint16_t
3389 ptp_canon_eos_getevent (PTPParams* params, PTPCanon_changes_entry **entries, int *nrofentries)
3390 {
3391 PTPContainer ptp;
3392 unsigned char *data = NULL;
3393 unsigned int size;
3394
3395 PTP_CNT_INIT(ptp, PTP_OC_CANON_EOS_GetEvent);
3396 *nrofentries = 0;
3397 *entries = NULL;
3398 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size));
3399 *nrofentries = ptp_unpack_CANON_changes(params,data,size,entries);
3400 free (data);
3401 return PTP_RC_OK;
3402 }
3403
3404 uint16_t
3405 ptp_check_eos_events (PTPParams *params)
3406 {
3407 PTPCanon_changes_entry *entries = NULL, *nentries;
3408 int nrofentries = 0;
3409
3410 while (1) { /* call it repeatedly until the camera does not report any */
3411 CHECK_PTP_RC(ptp_canon_eos_getevent (params, &entries, &nrofentries));
3412 if (!nrofentries)
3413 return PTP_RC_OK;
3414
3415 if (params->nrofbacklogentries) {
3416 nentries = realloc(params->backlogentries,sizeof(entries[0])*(params->nrofbacklogentries+nrofentries));
3417 if (!nentries)
3418 return PTP_RC_GeneralError;
3419 params->backlogentries = nentries;
3420 memcpy (nentries+params->nrofbacklogentries, entries, nrofentries*sizeof(entries[0]));
3421 params->nrofbacklogentries += nrofentries;
3422 free (entries);
3423 } else {
3424 params->backlogentries = entries;
3425 params->nrofbacklogentries = nrofentries;
3426 }
3427 }
3428 return PTP_RC_OK;
3429 }
3430
3431 int
3432 ptp_get_one_eos_event (PTPParams *params, PTPCanon_changes_entry *entry)
3433 {
3434 if (!params->nrofbacklogentries)
3435 return 0;
3436 memcpy (entry, params->backlogentries, sizeof(*entry));
3437 if (params->nrofbacklogentries > 1) {
3438 memmove (params->backlogentries,params->backlogentries+1,sizeof(*entry)*(params->nrofbacklogentries-1));
3439 params->nrofbacklogentries--;
3440 } else {
3441 free (params->backlogentries);
3442 params->backlogentries = NULL;
3443 params->nrofbacklogentries = 0;
3444 }
3445 return 1;
3446 }
3447
3448
3449 uint16_t
3450 ptp_canon_eos_getdevicepropdesc (PTPParams* params, uint16_t propcode,
3451 PTPDevicePropDesc *dpd)
3452 {
3453 unsigned int i;
3454
3455 for (i=0;i<params->nrofcanon_props;i++)
3456 if (params->canon_props[i].proptype == propcode)
3457 break;
3458 if (params->nrofcanon_props == i)
3459 return PTP_RC_Undefined;
3460 memcpy (dpd, ¶ms->canon_props[i].dpd, sizeof (*dpd));
3461 if (dpd->FormFlag == PTP_DPFF_Enumeration) {
3462 /* need to duplicate the Enumeration alloc */
3463 dpd->FORM.Enum.SupportedValue = calloc (sizeof (PTPPropertyValue),dpd->FORM.Enum.NumberOfValues);
3464 memcpy (dpd->FORM.Enum.SupportedValue,
3465 params->canon_props[i].dpd.FORM.Enum.SupportedValue,
3466 sizeof (PTPPropertyValue)*dpd->FORM.Enum.NumberOfValues
3467 );
3468 }
3469 if (dpd->DataType == PTP_DTC_STR) {
3470 dpd->FactoryDefaultValue.str = strdup( params->canon_props[i].dpd.FactoryDefaultValue.str );
3471 dpd->CurrentValue.str = strdup( params->canon_props[i].dpd.CurrentValue.str );
3472 }
3473
3474 return PTP_RC_OK;
3475 }
3476
3477
3478 uint16_t
3479 ptp_canon_eos_getstorageids (PTPParams* params, PTPStorageIDs* storageids)
3480 {
3481 PTPContainer ptp;
3482 unsigned char *data = NULL;
3483 unsigned int size;
3484
3485 PTP_CNT_INIT(ptp, PTP_OC_CANON_EOS_GetStorageIDs);
3486 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size));
3487 ptp_unpack_SIDs(params, data, storageids, size);
3488 free(data);
3489 return PTP_RC_OK;
3490 }
3491
3492 uint16_t
3493 ptp_canon_eos_getstorageinfo (PTPParams* params, uint32_t p1, unsigned char **data, unsigned int *size)
3494 {
3495 PTPContainer ptp;
3496
3497 PTP_CNT_INIT(ptp, PTP_OC_CANON_EOS_GetStorageInfo, p1);
3498 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, data, size);
3499 /* FIXME: do stuff with data */
3500 }
3501
3502 uint16_t
3503 ptp_canon_eos_getobjectinfoex (
3504 PTPParams* params, uint32_t storageid, uint32_t oid, uint32_t unk,
3505 PTPCANONFolderEntry **entries, unsigned int *nrofentries
3506 ) {
3507 PTPContainer ptp;
3508 uint16_t ret = PTP_RC_OK;
3509 unsigned char *data = NULL, *xdata;
3510 unsigned int size, i;
3511
3512 PTP_CNT_INIT(ptp, PTP_OC_CANON_EOS_GetObjectInfoEx, storageid, oid, unk);
3513 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size));
3514 if (!data) {
3515 *nrofentries = 0;
3516 return PTP_RC_OK;
3517 }
3518
3519 if (size < 4) {
3520 ret = PTP_RC_GeneralError;
3521 goto exit;
3522 }
3523 /* check for integer overflow */
3524 if (dtoh32a(data) >= INT_MAX/sizeof(PTPCANONFolderEntry)) {
3525 ret = PTP_RC_GeneralError;
3526 goto exit;
3527 }
3528
3529 *nrofentries = dtoh32a(data);
3530 *entries = calloc(*nrofentries , sizeof(PTPCANONFolderEntry));
3531 if (!*entries) {
3532 ret = PTP_RC_GeneralError;
3533 goto exit;
3534 }
3535
3536 xdata = data+sizeof(uint32_t);
3537 for (i=0;i<*nrofentries;i++) {
3538 unsigned int entrysize;
3539
3540 if (4 + (xdata - data) > size) {
3541 ptp_debug (params, "reading canon FEs run over read data size? (1)\n");
3542 free (*entries);
3543 *entries = NULL;
3544 *nrofentries = 0;
3545 ret = PTP_RC_GeneralError;
3546 goto exit;
3547 }
3548 entrysize = dtoh32a(xdata);
3549 if ((entrysize + (xdata-data)) > size) {
3550 ptp_debug (params, "reading canon FEs run over read data size? (2)\n");
3551 free (*entries);
3552 *entries = NULL;
3553 *nrofentries = 0;
3554 ret = PTP_RC_GeneralError;
3555 goto exit;
3556 }
3557 if (entrysize < 4 + 48 + 4) {
3558 ptp_debug (params, "%d entry size %d does not match expected 56\n", i, entrysize);
3559 free (*entries);
3560 *entries = NULL;
3561 *nrofentries = 0;
3562 ret = PTP_RC_GeneralError;
3563 goto exit;
3564 }
3565 ptp_unpack_Canon_EOS_FE (params, &xdata[4], entrysize - 4, &((*entries)[i]));
3566 xdata += entrysize;
3567 }
3568 exit:
3569 free (data);
3570 return ret;
3571 }
3572
3573 /**
3574 * ptp_canon_eos_getpartialobject:
3575 *
3576 * This retrieves a part of an PTP object which you specify as object id.
3577 * The id originates from 0x9116 call.
3578 * After finishing it, we seem to need to call ptp_canon_eos_enddirecttransfer.
3579 *
3580 * params: PTPParams*
3581 * oid Object ID
3582 * offset The offset where to start the data transfer
3583 * xsize Size in bytes of the transfer to do
3584 * data Pointer that receives the malloc()ed memory of the transfer.
3585 *
3586 * Return values: Some PTP_RC_* code.
3587 *
3588 */
3589 uint16_t
3590 ptp_canon_eos_getpartialobject (PTPParams* params, uint32_t oid, uint32_t offset, uint32_t xsize, unsigned char**data)
3591 {
3592 PTPContainer ptp;
3593
3594 PTP_CNT_INIT(ptp, PTP_OC_CANON_EOS_GetPartialObject, oid, offset, xsize);
3595 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, data, NULL);
3596 }
3597
3598 /**
3599 * ptp_canon_eos_getpartialobjectex:
3600 *
3601 * This retrieves a part of an PTP object which you specify as object id.
3602 * The id originates from 0x9116 call.
3603 * After finishing it, we seem to need to call ptp_canon_eos_enddirecttransfer.
3604 *
3605 * params: PTPParams*
3606 * oid Object ID
3607 * offset The offset where to start the data transfer
3608 * xsize Size in bytes of the transfer to do
3609 * data Pointer that receives the malloc()ed memory of the transfer.
3610 *
3611 * Return values: Some PTP_RC_* code.
3612 *
3613 */
3614 uint16_t
3615 ptp_canon_eos_getpartialobjectex (PTPParams* params, uint32_t oid, uint32_t offset, uint32_t xsize, unsigned char**data)
3616 {
3617 PTPContainer ptp;
3618
3619 /* 5bf19091 00008001 00001000 00000000 */
3620 /* objectid offset size ? 64bit part ? */
3621 PTP_CNT_INIT(ptp, PTP_OC_CANON_EOS_GetPartialObjectEx, oid, offset, xsize, 0);
3622 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, data, NULL);
3623 }
3624
3625 uint16_t
3626 ptp_canon_eos_setdevicepropvalueex (PTPParams* params, unsigned char* data, unsigned int size)
3627 {
3628 PTPContainer ptp;
3629
3630 PTP_CNT_INIT(ptp, PTP_OC_CANON_EOS_SetDevicePropValueEx);
3631 return ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, &data, NULL);
3632 }
3633
3634 uint16_t
3635 ptp_canon_eos_setdevicepropvalue (PTPParams* params,
3636 uint16_t propcode, PTPPropertyValue *value, uint16_t datatype
3637 ) {
3638 PTPContainer ptp;
3639 uint16_t ret;
3640 unsigned char *data = NULL;
3641 unsigned int i, size;
3642
3643 PTP_CNT_INIT(ptp, PTP_OC_CANON_EOS_SetDevicePropValueEx);
3644
3645 for (i=0;i<params->nrofcanon_props;i++)
3646 if (params->canon_props[i].proptype == propcode)
3647 break;
3648 if (params->nrofcanon_props == i)
3649 return PTP_RC_Undefined;
3650
3651 switch (propcode) {
3652 case PTP_DPC_CANON_EOS_ImageFormat:
3653 case PTP_DPC_CANON_EOS_ImageFormatCF:
3654 case PTP_DPC_CANON_EOS_ImageFormatSD:
3655 case PTP_DPC_CANON_EOS_ImageFormatExtHD:
3656 /* special handling of ImageFormat properties */
3657 size = 8 + ptp_pack_EOS_ImageFormat( params, NULL, value->u16 );
3658 data = malloc( size );
3659 if (!data) return PTP_RC_GeneralError;
3660 ptp_pack_EOS_ImageFormat( params, data + 8, value->u16 );
3661 break;
3662 case PTP_DPC_CANON_EOS_CustomFuncEx:
3663 /* special handling of CustomFuncEx properties */
3664 ptp_debug (params, "ptp2/ptp_canon_eos_setdevicepropvalue: setting EOS prop %x to %s",propcode,value->str);
3665 size = 8 + ptp_pack_EOS_CustomFuncEx( params, NULL, value->str );
3666 data = malloc( size );
3667 if (!data) return PTP_RC_GeneralError;
3668 ptp_pack_EOS_CustomFuncEx( params, data + 8, value->str );
3669 break;
3670 default:
3671 if (datatype != PTP_DTC_STR) {
3672 data = calloc(3,sizeof(uint32_t));
3673 if (!data) return PTP_RC_GeneralError;
3674 size = sizeof(uint32_t)*3;
3675 } else {
3676 size = strlen(value->str) + 1 + 8;
3677 data = calloc(size,sizeof(char));
3678 if (!data) return PTP_RC_GeneralError;
3679 }
3680 switch (datatype) {
3681 case PTP_DTC_INT8:
3682 case PTP_DTC_UINT8:
3683 /*fprintf (stderr, "%x -> %d\n", propcode, value->u8);*/
3684 htod8a(&data[8], value->u8);
3685 break;
3686 case PTP_DTC_UINT16:
3687 case PTP_DTC_INT16:
3688 /*fprintf (stderr, "%x -> %d\n", propcode, value->u16);*/
3689 htod16a(&data[8], value->u16);
3690 break;
3691 case PTP_DTC_INT32:
3692 case PTP_DTC_UINT32:
3693 /*fprintf (stderr, "%x -> %d\n", propcode, value->u32);*/
3694 htod32a(&data[8], value->u32);
3695 break;
3696 case PTP_DTC_STR:
3697 strcpy((char*)data + 8, value->str);
3698 break;
3699 }
3700 }
3701
3702 htod32a(&data[0], size);
3703 htod32a(&data[4], propcode);
3704
3705 ret = ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, &data, NULL);
3706 free (data);
3707 if (ret == PTP_RC_OK) {
3708 /* commit to cache only after successful setting */
3709 switch (propcode) {
3710 case PTP_DPC_CANON_EOS_ImageFormat:
3711 case PTP_DPC_CANON_EOS_ImageFormatCF:
3712 case PTP_DPC_CANON_EOS_ImageFormatSD:
3713 case PTP_DPC_CANON_EOS_ImageFormatExtHD:
3714 /* special handling of ImageFormat properties */
3715 params->canon_props[i].dpd.CurrentValue.u16 = value->u16;
3716 break;
3717 case PTP_DPC_CANON_EOS_CustomFuncEx:
3718 /* special handling of CustomFuncEx properties */
3719 params->canon_props[i].dpd.CurrentValue.str = strdup( value->str );
3720 break;
3721 default:
3722 switch (datatype) {
3723 case PTP_DTC_INT8:
3724 case PTP_DTC_UINT8:
3725 params->canon_props[i].dpd.CurrentValue.u8 = value->u8;
3726 break;
3727 case PTP_DTC_UINT16:
3728 case PTP_DTC_INT16:
3729 params->canon_props[i].dpd.CurrentValue.u16 = value->u16;
3730 break;
3731 case PTP_DTC_INT32:
3732 case PTP_DTC_UINT32:
3733 params->canon_props[i].dpd.CurrentValue.u32 = value->u32;
3734 break;
3735 case PTP_DTC_STR:
3736 free (params->canon_props[i].dpd.CurrentValue.str);
3737 params->canon_props[i].dpd.CurrentValue.str = strdup(value->str);
3738 break;
3739 }
3740 }
3741 }
3742 return ret;
3743 }
3744
3745 /**
3746 * ptp_canon_getpartialobject:
3747 *
3748 * This operation is used to read from the device a data
3749 * block of an object from a specified offset.
3750 *
3751 * params: PTPParams*
3752 * uint32_t handle - the handle of the requested object
3753 * uint32_t offset - the offset in bytes from the beginning of the object
3754 * uint32_t size - the requested size of data block to read
3755 * uint32_t pos - 1 for the first block, 2 - for a block in the middle,
3756 * 3 - for the last block
3757 *
3758 * Return values: Some PTP_RC_* code.
3759 * char **block - the pointer to the block of data read
3760 * uint32_t* readnum - the number of bytes read
3761 *
3762 **/
3763 uint16_t
3764 ptp_canon_getpartialobject (PTPParams* params, uint32_t handle,
3765 uint32_t offset, uint32_t size,
3766 uint32_t pos, unsigned char** block,
3767 uint32_t* readnum)
3768 {
3769 PTPContainer ptp;
3770 uint16_t ret;
3771 unsigned char *data = NULL;
3772
3773 PTP_CNT_INIT(ptp, PTP_OC_CANON_GetPartialObjectEx, handle, offset, size, pos);
3774 ret=ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, NULL);
3775 if (ret==PTP_RC_OK) {
3776 *block=data;
3777 *readnum=ptp.Param1;
3778 }
3779 free (data);
3780 return ret;
3781 }
3782
3783 /**
3784 * ptp_canon_getviewfinderimage:
3785 *
3786 * This operation can be used to read the image which is currently
3787 * in the camera's viewfinder. The image size is 320x240, format is JPEG.
3788 * Of course, prior to calling this operation, one must turn the viewfinder
3789 * on with the CANON_ViewfinderOn command.
3790 * Invoking this operation many times, one can get live video from the camera!
3791 *
3792 * params: PTPParams*
3793 *
3794 * Return values: Some PTP_RC_* code.
3795 * char **image - the pointer to the read image
3796 * unit32_t *size - the size of the image in bytes
3797 *
3798 **/
3799 uint16_t
3800 ptp_canon_getviewfinderimage (PTPParams* params, unsigned char** image, uint32_t* size)
3801 {
3802 PTPContainer ptp;
3803 uint16_t ret;
3804
3805 PTP_CNT_INIT(ptp, PTP_OC_CANON_GetViewfinderImage);
3806 ret=ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, image, NULL);
3807 if (ret==PTP_RC_OK)
3808 *size=ptp.Param1;
3809 return ret;
3810 }
3811
3812 /**
3813 * ptp_canon_getchanges:
3814 *
3815 * This is an interesting operation, about the effect of which I am not sure.
3816 * This command is called every time when a device property has been changed
3817 * with the SetDevicePropValue operation, and after some other operations.
3818 * This operation reads the array of Device Properties which have been changed
3819 * by the previous operation.
3820 * Probably, this operation is even required to make those changes work.
3821 *
3822 * params: PTPParams*
3823 *
3824 * Return values: Some PTP_RC_* code.
3825 * uint16_t** props - the pointer to the array of changed properties
3826 * uint32_t* propnum - the number of elements in the *props array
3827 *
3828 **/
3829 uint16_t
3830 ptp_canon_getchanges (PTPParams* params, uint16_t** props, uint32_t* propnum)
3831 {
3832 PTPContainer ptp;
3833 unsigned char *data = NULL;
3834 unsigned int size;
3835
3836 PTP_CNT_INIT(ptp, PTP_OC_CANON_GetChanges);
3837 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size));
3838 *propnum=ptp_unpack_uint16_t_array(params,data,0,size,props);
3839 free(data);
3840 return PTP_RC_OK;
3841 }
3842
3843 /**
3844 * ptp_canon_getobjectinfo:
3845 *
3846 * This command reads a specified object's record in a device's filesystem,
3847 * or the records of all objects belonging to a specified folder (association).
3848 *
3849 * params: PTPParams*
3850 * uint32_t store - StorageID,
3851 * uint32_t p2 - Yet unknown (0 value works OK)
3852 * uint32_t parent - Parent Object Handle
3853 * # If Parent Object Handle is 0xffffffff,
3854 * # the Parent Object is the top level folder.
3855 * uint32_t handle - Object Handle
3856 * # If Object Handle is 0, the records of all objects
3857 * # belonging to the Parent Object are read.
3858 * # If Object Handle is not 0, only the record of this
3859 * # Object is read.
3860 *
3861 * Return values: Some PTP_RC_* code.
3862 * PTPCANONFolderEntry** entries - the pointer to the folder entry array
3863 * uint32_t* entnum - the number of elements of the array
3864 *
3865 **/
3866 uint16_t
3867 ptp_canon_getobjectinfo (PTPParams* params, uint32_t store, uint32_t p2,
3868 uint32_t parent, uint32_t handle,
3869 PTPCANONFolderEntry** entries, uint32_t* entnum)
3870 {
3871 PTPContainer ptp;
3872 uint16_t ret;
3873 unsigned char *data = NULL;
3874 unsigned int i, size;
3875
3876 *entnum = 0;
3877 *entries = NULL;
3878 PTP_CNT_INIT(ptp, PTP_OC_CANON_GetObjectInfoEx, store, p2, parent, handle);
3879 data = NULL;
3880 size = 0;
3881 ret=ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size);
3882 if (ret != PTP_RC_OK)
3883 goto exit;
3884 if (!data)
3885 return ret;
3886 if (ptp.Param1 > size/PTP_CANON_FolderEntryLen) {
3887 ptp_debug (params, "param1 is %d, size is only %d", ptp.Param1, size);
3888 ret = PTP_RC_GeneralError;
3889 goto exit;
3890 }
3891
3892 *entnum = ptp.Param1;
3893 *entries= calloc(*entnum, sizeof(PTPCANONFolderEntry));
3894 if (*entries == NULL) {
3895 ret = PTP_RC_GeneralError;
3896 goto exit;
3897 }
3898 for(i=0; i<(*entnum); i++) {
3899 if (size < i*PTP_CANON_FolderEntryLen) break;
3900 ptp_unpack_Canon_FE(params,
3901 data+i*PTP_CANON_FolderEntryLen,
3902 &((*entries)[i]) );
3903 }
3904
3905 exit:
3906 free (data);
3907 return ret;
3908 }
3909
3910 /**
3911 * ptp_canon_get_objecthandle_by_name:
3912 *
3913 * This command looks up the specified object on the camera.
3914 *
3915 * Format is "A:\\PATH".
3916 *
3917 * The 'A' is the VolumeLabel from GetStorageInfo,
3918 * my IXUS has "A" for the card and "V" for internal memory.
3919 *
3920 * params: PTPParams*
3921 * char* name - path name
3922 *
3923 * Return values: Some PTP_RC_* code.
3924 * uint32_t *oid - PTP object id.
3925 *
3926 **/
3927 uint16_t
3928 ptp_canon_get_objecthandle_by_name (PTPParams* params, char* name, uint32_t* objectid)
3929 {
3930 PTPContainer ptp;
3931 uint16_t ret;
3932 unsigned char *data;
3933 uint8_t len = 0;
3934
3935 PTP_CNT_INIT(ptp, PTP_OC_CANON_GetObjectHandleByName);
3936 data = calloc (2,(strlen(name)+2));
3937 if (!data) return PTP_RC_GeneralError;
3938 ptp_pack_string (params, name, data, 0, &len);
3939 ret=ptp_transaction (params, &ptp, PTP_DP_SENDDATA, (len+1)*2+1, &data, NULL);
3940 free (data);
3941 *objectid = ptp.Param1;
3942 return ret;
3943 }
3944
3945 /**
3946 * ptp_canon_get_customize_data:
3947 *
3948 * This command downloads the specified theme slot, including jpegs
3949 * and wav files.
3950 *
3951 * params: PTPParams*
3952 * uint32_t themenr - nr of theme
3953 *
3954 * Return values: Some PTP_RC_* code.
3955 * unsigned char **data - pointer to data pointer
3956 * unsigned int *size - size of data returned
3957 *
3958 **/
3959 uint16_t
3960 ptp_canon_get_customize_data (PTPParams* params, uint32_t themenr,
3961 unsigned char **data, unsigned int *size)
3962 {
3963 PTPContainer ptp;
3964
3965 PTP_CNT_INIT(ptp, PTP_OC_CANON_GetCustomizeData, themenr);
3966 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, data, size);
3967 }
3968
3969
3970 uint16_t
3971 ptp_nikon_curve_download (PTPParams* params, unsigned char **data, unsigned int *size)
3972 {
3973 PTPContainer ptp;
3974
3975 PTP_CNT_INIT(ptp, PTP_OC_NIKON_CurveDownload);
3976 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, data, size);
3977 }
3978
3979 /**
3980 * ptp_sony_sdioconnect:
3981 *
3982 * This changes modes of the camera
3983 *
3984 * params: PTPParams*
3985 *
3986 * Return values: Some PTP_RC_* code.
3987 *
3988 **/
3989 uint16_t
3990 ptp_sony_sdioconnect (PTPParams* params, uint32_t p1, uint32_t p2, uint32_t p3)
3991 {
3992 PTPContainer ptp;
3993 unsigned char *data = NULL;
3994
3995 PTP_CNT_INIT(ptp, PTP_OC_SONY_SDIOConnect, p1, p2, p3);
3996 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, NULL));
3997 free (data);
3998 return PTP_RC_OK;
3999 }
4000
4001 /**
4002 * ptp_sony_qx_connect:
4003 *
4004 * This changes modes of the camera
4005 *
4006 * params: PTPParams*
4007 *
4008 * Return values: Some PTP_RC_* code.
4009 *
4010 **/
4011 uint16_t
4012 ptp_sony_qx_connect (PTPParams* params, uint32_t p1, uint32_t p2, uint32_t p3)
4013 {
4014 PTPContainer ptp;
4015 unsigned char *data = NULL;
4016
4017 PTP_CNT_INIT(ptp, PTP_OC_SONY_QX_Connect, p1, p2, p3);
4018 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, NULL));
4019 free (data);
4020 return PTP_RC_OK;
4021 }
4022
4023 /**
4024 * ptp_sony_get_vendorpropcodes:
4025 *
4026 * This command downloads the vendor specific property codes.
4027 *
4028 * params: PTPParams*
4029 *
4030 * Return values: Some PTP_RC_* code.
4031 * unsigned char **data - pointer to data pointer
4032 * unsigned int *size - size of data returned
4033 *
4034 **/
4035 uint16_t
4036 ptp_sony_get_vendorpropcodes (PTPParams* params, uint16_t **props, unsigned int *size)
4037 {
4038 PTPContainer ptp;
4039 unsigned char *xdata = NULL;
4040 unsigned int xsize, psize1 = 0, psize2 = 0;
4041 uint16_t *props1 = NULL,*props2 = NULL;
4042
4043 *props = NULL;
4044 *size = 0;
4045 PTP_CNT_INIT(ptp, PTP_OC_SONY_GetSDIOGetExtDeviceInfo, 0xc8 /* unclear */);
4046 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &xdata, &xsize));
4047 if (xsize == 0) {
4048 ptp_debug (params, "No special operations sent?");
4049 return PTP_RC_OK;
4050 }
4051
4052 psize1 = ptp_unpack_uint16_t_array (params, xdata+2, 0, xsize, &props1);
4053 ptp_debug (params, "xsize %d, got size %d\n", xsize, psize1*2 + 2 + 4);
4054 if (psize1*2 + 2 + 4 < xsize) {
4055 psize2 = ptp_unpack_uint16_t_array(params,xdata+2+psize1*2+4, 0, xsize, &props2);
4056 }
4057 *props = calloc(psize1+psize2, sizeof(uint16_t));
4058 if (!*props) {
4059 ptp_debug (params, "oom during malloc?");
4060 free (props1);
4061 free (props2);
4062 free (xdata);
4063 return PTP_RC_OK;
4064 }
4065 *size = psize1+psize2;
4066 memcpy (*props, props1, psize1*sizeof(uint16_t));
4067 memcpy ((*props)+psize1, props2, psize2*sizeof(uint16_t));
4068 free (props1);
4069 free (props2);
4070 free (xdata);
4071 return PTP_RC_OK;
4072 }
4073
4074 uint16_t
4075 ptp_sony_qx_get_vendorpropcodes (PTPParams* params, uint16_t **props, unsigned int *size)
4076 {
4077 PTPContainer ptp;
4078 unsigned char *xdata = NULL;
4079 unsigned int xsize, psize1 = 0, psize2 = 0;
4080 uint16_t *props1 = NULL,*props2 = NULL;
4081
4082 *props = NULL;
4083 *size = 0;
4084 PTP_CNT_INIT(ptp, PTP_OC_SONY_QX_GetSDIOGetExtDeviceInfo, 0xc8 /* unclear */);
4085 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &xdata, &xsize));
4086 if (xsize == 0) {
4087 ptp_debug (params, "No special operations sent?");
4088 return PTP_RC_OK;
4089 }
4090
4091 psize1 = ptp_unpack_uint16_t_array (params, xdata+2, 0, xsize, &props1);
4092 ptp_debug (params, "xsize %d, got size %d\n", xsize, psize1*2 + 2 + 4);
4093 if (psize1*2 + 2 + 4 < xsize) {
4094 psize2 = ptp_unpack_uint16_t_array(params,xdata+2+psize1*2+4, 0, xsize, &props2);
4095 }
4096 *props = calloc(psize1+psize2, sizeof(uint16_t));
4097 if (!*props) {
4098 ptp_debug (params, "oom during malloc?");
4099 free (props1);
4100 free (props2);
4101 free (xdata);
4102 return PTP_RC_OK;
4103 }
4104 *size = psize1+psize2;
4105 memcpy (*props, props1, psize1*sizeof(uint16_t));
4106 memcpy ((*props)+psize1, props2, psize2*sizeof(uint16_t));
4107 free (props1);
4108 free (props2);
4109 free (xdata);
4110 return PTP_RC_OK;
4111 }
4112
4113
4114 uint16_t
4115 ptp_sony_getdevicepropdesc (PTPParams* params, uint16_t propcode, PTPDevicePropDesc *dpd)
4116 {
4117 PTPContainer ptp;
4118 unsigned char *data = NULL;
4119 unsigned int size, len = 0;
4120 uint16_t ret;
4121
4122 PTP_CNT_INIT(ptp, PTP_OC_SONY_GetDevicePropdesc, propcode);
4123 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size));
4124 if (!data) return PTP_RC_GeneralError;
4125 /* first 16 bit is 0xc8 0x00, then an array of 16 bit PTP ids */
4126 ret = ptp_unpack_Sony_DPD(params,data,dpd,size,&len) ? PTP_RC_OK : PTP_RC_GeneralError;
4127 free (data);
4128 return ret;
4129 }
4130
4131 static uint16_t
4132 _ptp_sony_getalldevicepropdesc (PTPParams* params, uint16_t opcode)
4133 {
4134 PTPContainer ptp;
4135 unsigned char *data = NULL, *dpddata;
4136 unsigned int size, readlen;
4137 PTPDevicePropDesc dpd;
4138 time_t now;
4139
4140 ptp_debug (params, "_ptp_sony_getalldevicepropdesc: opcode %04x", opcode);
4141 /* for old A900 / A700 who does not have this, but has capture */
4142 if (!ptp_operation_issupported(params, opcode))
4143 return PTP_RC_OK;
4144
4145 PTP_CNT_INIT(ptp, opcode);
4146 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size));
4147 if (!data)
4148 return PTP_RC_GeneralError;
4149 if (size <= 8) {
4150 free (data);
4151 return PTP_RC_GeneralError;
4152 }
4153 dpddata = data+8; /* nr of entries 32bit, 0 32bit */
4154 size -= 8;
4155 time(&now);
4156 while (size>0) {
4157 unsigned int i;
4158 uint16_t propcode;
4159
4160 if (!ptp_unpack_Sony_DPD (params, dpddata, &dpd, size, &readlen))
4161 break;
4162
4163 propcode = dpd.DevicePropertyCode;
4164
4165 for (i=0;i<params->nrofdeviceproperties;i++)
4166 if (params->deviceproperties[i].desc.DevicePropertyCode == propcode)
4167 break;
4168
4169 /* debug output to see what changes */
4170 if (i != params->nrofdeviceproperties) {
4171 switch (dpd.DataType) {
4172 case PTP_DTC_INT8:
4173 #define CHECK_CHANGED(type) \
4174 if (params->deviceproperties[i].desc.CurrentValue.type != dpd.CurrentValue.type) \
4175 ptp_debug (params, "ptp_sony_getalldevicepropdesc: %s(%04x): value %d -> %d", ptp_get_property_description (params, propcode), propcode, params->deviceproperties[i].desc.CurrentValue.type, dpd.CurrentValue.type);
4176 CHECK_CHANGED(i8);
4177 break;
4178 case PTP_DTC_UINT8:
4179 CHECK_CHANGED(u8);
4180 break;
4181 case PTP_DTC_UINT16:
4182 CHECK_CHANGED(u16);
4183 break;
4184 case PTP_DTC_INT16:
4185 CHECK_CHANGED(i16);
4186 break;
4187 case PTP_DTC_INT32:
4188 CHECK_CHANGED(i32);
4189 break;
4190 case PTP_DTC_UINT32:
4191 CHECK_CHANGED(u32);
4192 break;
4193 default:
4194 break;
4195 }
4196 }
4197
4198 if (i == params->nrofdeviceproperties) {
4199 params->deviceproperties = realloc(params->deviceproperties,(i+1)*sizeof(params->deviceproperties[0]));
4200 memset(¶ms->deviceproperties[i],0,sizeof(params->deviceproperties[0]));
4201 params->nrofdeviceproperties++;
4202 } else {
4203 ptp_free_devicepropdesc (¶ms->deviceproperties[i].desc);
4204 }
4205 params->deviceproperties[i].desc = dpd;
4206 params->deviceproperties[i].timestamp = now;
4207 #if 0
4208 ptp_debug (params, "dpd.DevicePropertyCode %04x, readlen %d, getset %d", dpd.DevicePropertyCode, readlen, dpd.GetSet);
4209 switch (dpd.DataType) {
4210 case PTP_DTC_INT8:
4211 ptp_debug (params, "value %d/%x", dpd.CurrentValue.i8, dpd.CurrentValue.i8);
4212 break;
4213 case PTP_DTC_UINT8:
4214 ptp_debug (params, "value %d/%x", dpd.CurrentValue.u8, dpd.CurrentValue.u8);
4215 break;
4216 case PTP_DTC_UINT16:
4217 ptp_debug (params, "value %d/%x", dpd.CurrentValue.u16, dpd.CurrentValue.u16);
4218 break;
4219 case PTP_DTC_INT16:
4220 ptp_debug (params, "value %d/%x", dpd.CurrentValue.i16, dpd.CurrentValue.i16);
4221 break;
4222 case PTP_DTC_INT32:
4223 ptp_debug (params, "value %d/%x", dpd.CurrentValue.i32, dpd.CurrentValue.i32);
4224 break;
4225 case PTP_DTC_UINT32:
4226 ptp_debug (params, "value %d/%x", dpd.CurrentValue.u32, dpd.CurrentValue.u32);
4227 break;
4228 default:
4229 ptp_debug (params, "unknown type %x", dpd.DataType);
4230 break;
4231 }
4232 #endif
4233 dpddata += readlen;
4234 size -= readlen;
4235 }
4236 free(data);
4237 return PTP_RC_OK;
4238 }
4239
4240 uint16_t
4241 ptp_sony_getalldevicepropdesc (PTPParams* params) {
4242 return _ptp_sony_getalldevicepropdesc (params, PTP_OC_SONY_GetAllDevicePropData);
4243 }
4244
4245 uint16_t
4246 ptp_sony_qx_getalldevicepropdesc (PTPParams* params) {
4247 return _ptp_sony_getalldevicepropdesc (params, PTP_OC_SONY_QX_GetAllDevicePropData);
4248 }
4249
4250 uint16_t
4251 ptp_sony_setdevicecontrolvaluea (PTPParams* params, uint16_t propcode,
4252 PTPPropertyValue *value, uint16_t datatype)
4253 {
4254 PTPContainer ptp;
4255 uint16_t ret;
4256 unsigned char *data;
4257 uint32_t size;
4258
4259 PTP_CNT_INIT(ptp, PTP_OC_SONY_SetControlDeviceA, propcode);
4260 size = ptp_pack_DPV(params, value, &data, datatype);
4261 ret = ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, &data, NULL);
4262 free(data);
4263 return ret;
4264 }
4265
4266 uint16_t
4267 ptp_sony_qx_setdevicecontrolvaluea (PTPParams* params, uint16_t propcode,
4268 PTPPropertyValue *value, uint16_t datatype)
4269 {
4270 PTPContainer ptp;
4271 uint16_t ret;
4272 unsigned char *data;
4273 uint32_t size;
4274
4275 PTP_CNT_INIT(ptp, PTP_OC_SONY_QX_SetControlDeviceA, propcode);
4276 size = ptp_pack_DPV(params, value, &data, datatype);
4277 ret = ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, &data, NULL);
4278 free(data);
4279 return ret;
4280 }
4281
4282 uint16_t
4283 ptp_sony_setdevicecontrolvalueb (PTPParams* params, uint16_t propcode,
4284 PTPPropertyValue *value, uint16_t datatype)
4285 {
4286 PTPContainer ptp;
4287 uint16_t ret;
4288 unsigned char *data;
4289 uint32_t size;
4290
4291 PTP_CNT_INIT(ptp, PTP_OC_SONY_SetControlDeviceB, propcode);
4292 size = ptp_pack_DPV(params, value, &data , datatype);
4293 ret = ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, &data, NULL);
4294 free(data);
4295 return ret;
4296 }
4297
4298 uint16_t
4299 ptp_sony_qx_setdevicecontrolvalueb (PTPParams* params, uint16_t propcode,
4300 PTPPropertyValue *value, uint16_t datatype)
4301 {
4302 PTPContainer ptp;
4303 uint16_t ret;
4304 unsigned char *data;
4305 uint32_t size;
4306
4307 PTP_CNT_INIT(ptp, PTP_OC_SONY_QX_SetControlDeviceB, propcode);
4308 size = ptp_pack_DPV(params, value, &data , datatype);
4309 ret = ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, &data, NULL);
4310 free(data);
4311 return ret;
4312 }
4313
4314
4315 uint16_t
4316 ptp_sony_9280 (PTPParams* params, uint32_t param1,
4317 uint32_t additional, uint32_t data2, uint32_t data3, uint32_t data4, uint8_t x, uint8_t y)
4318 {
4319 PTPContainer ptp;
4320 unsigned char buf[18];
4321 unsigned char *buffer;
4322
4323 PTP_CNT_INIT(ptp, 0x9280, param1);
4324
4325 if ((additional != 0) && (additional != 2))
4326 return PTP_RC_GeneralError;
4327
4328 htod32a(&buf[0], additional);
4329 htod32a(&buf[4], data2);
4330 htod32a(&buf[8], data3);
4331 htod32a(&buf[12], data4);
4332
4333 /* only sent in the case where additional is 2 */
4334 buf[16]= x; buf[17]= y;
4335
4336 buffer=buf;
4337 return ptp_transaction(params, &ptp, PTP_DP_SENDDATA, 16+additional, &buffer, NULL);
4338 }
4339
4340 uint16_t
4341 ptp_sony_9281 (PTPParams* params, uint32_t param1) {
4342 PTPContainer ptp;
4343 unsigned int size = 0;
4344 unsigned char *buffer = NULL;
4345 uint16_t ret;
4346
4347 PTP_CNT_INIT(ptp, 0x9281, param1);
4348 ret = ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &buffer, &size);
4349 free (buffer);
4350 return ret;
4351 }
4352
4353 /**
4354 * ptp_generic_getdevicepropdesc:
4355 *
4356 * This command gets a propertydesc.
4357 * If a vendor specific property desc query is available, it uses that.
4358 * If not, it falls back to the generic PTP getdevicepropdesc.
4359 *
4360 * params: PTPParams*
4361 * uint16_t propcode
4362 * PTPDevicePropDesc *dpd
4363 *
4364 * Return values: Some PTP_RC_* code.
4365 *
4366 **/
4367 /* Cache time in seconds. Should perhaps be more granular... */
4368
4369 uint16_t
4370 ptp_generic_getdevicepropdesc (PTPParams *params, uint16_t propcode, PTPDevicePropDesc *dpd)
4371 {
4372 unsigned int i;
4373 time_t now;
4374
4375 for (i=0;i<params->nrofdeviceproperties;i++)
4376 if (params->deviceproperties[i].desc.DevicePropertyCode == propcode)
4377 break;
4378 if (i == params->nrofdeviceproperties) {
4379 params->deviceproperties = realloc(params->deviceproperties,(i+1)*sizeof(params->deviceproperties[0]));
4380 memset(¶ms->deviceproperties[i],0,sizeof(params->deviceproperties[0]));
4381 params->nrofdeviceproperties++;
4382 }
4383
4384 if (params->deviceproperties[i].desc.DataType != PTP_DTC_UNDEF) {
4385 time(&now);
4386 if (params->deviceproperties[i].timestamp + params->cachetime > now) {
4387 duplicate_DevicePropDesc(¶ms->deviceproperties[i].desc, dpd);
4388 return PTP_RC_OK;
4389 }
4390 /* free cached entry as we will refetch it. */
4391 ptp_free_devicepropdesc (¶ms->deviceproperties[i].desc);
4392 }
4393
4394 if ( (params->deviceinfo.VendorExtensionID == PTP_VENDOR_SONY) &&
4395 ptp_operation_issupported(params, PTP_OC_SONY_GetAllDevicePropData)
4396 ) {
4397 CHECK_PTP_RC(ptp_sony_getalldevicepropdesc (params));
4398
4399 for (i=0;i<params->nrofdeviceproperties;i++)
4400 if (params->deviceproperties[i].desc.DevicePropertyCode == propcode)
4401 break;
4402 if (i == params->nrofdeviceproperties) {
4403 ptp_debug (params, "alpha property 0x%04x not found?\n", propcode);
4404 return PTP_RC_GeneralError;
4405 }
4406 time(&now);
4407 params->deviceproperties[i].timestamp = now;
4408 duplicate_DevicePropDesc(¶ms->deviceproperties[i].desc, dpd);
4409 return PTP_RC_OK;
4410 }
4411 if ( (params->deviceinfo.VendorExtensionID == PTP_VENDOR_SONY) &&
4412 ptp_operation_issupported(params, PTP_OC_SONY_QX_GetAllDevicePropData)
4413 ) {
4414 CHECK_PTP_RC(ptp_sony_qx_getalldevicepropdesc (params));
4415
4416 for (i=0;i<params->nrofdeviceproperties;i++)
4417 if (params->deviceproperties[i].desc.DevicePropertyCode == propcode)
4418 break;
4419 if (i == params->nrofdeviceproperties) {
4420 ptp_debug (params, "qx property 0x%04x not found?\n", propcode);
4421 return PTP_RC_GeneralError;
4422 }
4423 time(&now);
4424 params->deviceproperties[i].timestamp = now;
4425 duplicate_DevicePropDesc(¶ms->deviceproperties[i].desc, dpd);
4426 return PTP_RC_OK;
4427 }
4428 if ( (params->deviceinfo.VendorExtensionID == PTP_VENDOR_SONY) &&
4429 ptp_operation_issupported(params, PTP_OC_SONY_GetDevicePropdesc)
4430 ) {
4431 CHECK_PTP_RC(ptp_sony_getdevicepropdesc (params, propcode, ¶ms->deviceproperties[i].desc));
4432
4433 time(&now);
4434 params->deviceproperties[i].timestamp = now;
4435 duplicate_DevicePropDesc(¶ms->deviceproperties[i].desc, dpd);
4436 return PTP_RC_OK;
4437 }
4438
4439
4440 if (ptp_operation_issupported(params, PTP_OC_GetDevicePropDesc)) {
4441 CHECK_PTP_RC(ptp_getdevicepropdesc (params, propcode, ¶ms->deviceproperties[i].desc));
4442
4443 time(&now);
4444 params->deviceproperties[i].timestamp = now;
4445 duplicate_DevicePropDesc(¶ms->deviceproperties[i].desc, dpd);
4446 return PTP_RC_OK;
4447 }
4448
4449 return PTP_RC_OperationNotSupported;
4450 }
4451
4452 /**
4453 * ptp_generic_setdevicepropvalue:
4454 *
4455 * This command sets a property value, device specific.
4456 *
4457 * params: PTPParams*
4458 * uint16_t propcode
4459 * PTPDevicePropertyValue *value
4460 * uint16_t datatype
4461 *
4462 * Return values: Some PTP_RC_* code.
4463 *
4464 **/
4465 uint16_t
4466 ptp_generic_setdevicepropvalue (PTPParams* params, uint16_t propcode,
4467 PTPPropertyValue *value, uint16_t datatype)
4468 {
4469 unsigned int i;
4470
4471 /* reset the cache entry */
4472 for (i=0;i<params->nrofdeviceproperties;i++)
4473 if (params->deviceproperties[i].desc.DevicePropertyCode == propcode)
4474 break;
4475 if (i != params->nrofdeviceproperties)
4476 params->deviceproperties[i].timestamp = 0;
4477
4478 /* FIXME: change the cache? hmm */
4479 /* this works for some methods, but not for all */
4480 if ( (params->deviceinfo.VendorExtensionID == PTP_VENDOR_SONY) &&
4481 ptp_operation_issupported(params, PTP_OC_SONY_SetControlDeviceA)
4482 )
4483 return ptp_sony_setdevicecontrolvaluea (params, propcode, value, datatype);
4484 /* Sony QX method */
4485 if ( (params->deviceinfo.VendorExtensionID == PTP_VENDOR_SONY) &&
4486 ptp_operation_issupported(params, PTP_OC_SONY_QX_SetControlDeviceA)
4487 )
4488 return ptp_sony_qx_setdevicecontrolvaluea (params, propcode, value, datatype);
4489 return ptp_setdevicepropvalue (params, propcode, value, datatype);
4490 }
4491
4492 /**
4493 * ptp_nikon_get_vendorpropcodes:
4494 *
4495 * This command downloads the vendor specific property codes.
4496 *
4497 * params: PTPParams*
4498 *
4499 * Return values: Some PTP_RC_* code.
4500 * unsigned char **data - pointer to data pointer
4501 * unsigned int *size - size of data returned
4502 *
4503 **/
4504 uint16_t
4505 ptp_nikon_get_vendorpropcodes (PTPParams* params, uint16_t **props, unsigned int *size)
4506 {
4507 PTPContainer ptp;
4508 unsigned char *data = NULL;
4509 unsigned int xsize = 0;
4510
4511 *props = NULL;
4512 *size = 0;
4513 PTP_CNT_INIT(ptp, PTP_OC_NIKON_GetVendorPropCodes);
4514 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &xsize));
4515 *size = ptp_unpack_uint16_t_array(params,data,0,xsize,props);
4516 free (data);
4517 return PTP_RC_OK;
4518 }
4519
4520 uint16_t
4521 ptp_nikon_getfileinfoinblock ( PTPParams* params,
4522 uint32_t p1, uint32_t p2, uint32_t p3,
4523 unsigned char **data, unsigned int *size
4524 ) {
4525 PTPContainer ptp;
4526
4527 PTP_CNT_INIT(ptp, PTP_OC_NIKON_GetFileInfoInBlock, p1, p2, p3);
4528 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, data, size);
4529 }
4530
4531 /**
4532 * ptp_nikon_get_liveview_image:
4533 *
4534 * This command gets a LiveView image from newer Nikons DSLRs.
4535 *
4536 * params: PTPParams*
4537 *
4538 * Return values: Some PTP_RC_* code.
4539 *
4540 **/
4541 uint16_t
4542 ptp_nikon_get_liveview_image (PTPParams* params, unsigned char **data, unsigned int *size)
4543 {
4544 PTPContainer ptp;
4545
4546 PTP_CNT_INIT(ptp, PTP_OC_NIKON_GetLiveViewImg);
4547 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, data, size);
4548 }
4549
4550 /**
4551 * ptp_nikon_get_preview_image:
4552 *
4553 * This command gets a Preview image from newer Nikons DSLRs.
4554 *
4555 * params: PTPParams*
4556 *
4557 * Return values: Some PTP_RC_* code.
4558 *
4559 **/
4560 uint16_t
4561 ptp_nikon_get_preview_image (PTPParams* params, unsigned char **xdata, unsigned int *xsize,
4562 uint32_t *handle)
4563 {
4564 PTPContainer ptp;
4565
4566 PTP_CNT_INIT(ptp, PTP_OC_NIKON_GetPreviewImg);
4567
4568 /* FIXME:
4569 * pdslrdashboard passes 3 parameters:
4570 * objectid, minimum size, maximum size
4571 */
4572 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, xdata, xsize));
4573 if (ptp.Nparam > 0)
4574 *handle = ptp.Param1;
4575 return PTP_RC_OK;
4576 }
4577
4578 /**
4579 * ptp_canon_eos_get_remotemode:
4580 *
4581 * This command gets the EOS remote mode.
4582 *
4583 * params: PTPParams*
4584 *
4585 * Return values: Some PTP_RC_* code.
4586 *
4587 **/
4588 uint16_t
4589 ptp_canon_eos_getremotemode (PTPParams* params, uint32_t *mode)
4590 {
4591 PTPContainer ptp;
4592
4593 PTP_CNT_INIT(ptp, PTP_OC_CANON_EOS_GetRemoteMode);
4594
4595 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL));
4596 *mode = 0;
4597 if (ptp.Nparam > 0)
4598 *mode = ptp.Param1;
4599 return PTP_RC_OK;
4600 }
4601
4602 /**
4603 * ptp_canon_eos_get_viewfinder_image:
4604 *
4605 * This command gets a Viewfinder image from newer Nikons DSLRs.
4606 *
4607 * params: PTPParams*
4608 *
4609 * Return values: Some PTP_RC_* code.
4610 *
4611 **/
4612 uint16_t
4613 ptp_canon_eos_get_viewfinder_image (PTPParams* params, unsigned char **data, unsigned int *size)
4614 {
4615 PTPContainer ptp;
4616
4617 /* Saw 3 arguments ... 0x00200000 for EOS1000D, also used 0x00100000 */
4618 PTP_CNT_INIT(ptp, PTP_OC_CANON_EOS_GetViewFinderData, 0x00200000 /* from trace */, 0, 0);
4619 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, data, size);
4620 }
4621
4622 uint16_t
4623 ptp_canon_eos_get_viewfinder_image_handler (PTPParams* params, PTPDataHandler*handler)
4624 {
4625 PTPContainer ptp;
4626
4627 /* Saw 3 arguments ... 0x00200000 for EOS1000D, also used 0x00100000 */
4628 PTP_CNT_INIT(ptp, PTP_OC_CANON_EOS_GetViewFinderData, 0x00200000 /* from trace */, 0, 0);
4629 return ptp_transaction_new(params, &ptp, PTP_DP_GETDATA, 0, handler);
4630 }
4631
4632 /**
4633 * ptp_nikon_check_event:
4634 *
4635 * This command checks the event queue on the Nikon.
4636 *
4637 * params: PTPParams*
4638 * PTPUSBEventContainer **event - list of usb events.
4639 * int *evtcnt - number of usb events in event structure.
4640 *
4641 * Return values: Some PTP_RC_* code.
4642 *
4643 **/
4644 uint16_t
4645 ptp_nikon_check_event (PTPParams* params, PTPContainer** event, unsigned int* evtcnt)
4646 {
4647 PTPContainer ptp;
4648 unsigned char *data = NULL;
4649 unsigned int size;
4650
4651 PTP_CNT_INIT(ptp, PTP_OC_NIKON_GetEvent);
4652 *evtcnt = 0;
4653 CHECK_PTP_RC(ptp_transaction (params, &ptp, PTP_DP_GETDATA, 0, &data, &size));
4654 ptp_unpack_Nikon_EC (params, data, size, event, evtcnt);
4655 free (data);
4656 return PTP_RC_OK;
4657 }
4658
4659 /**
4660 * ptp_nikon_check_eventex:
4661 *
4662 * This command checks the event queue on the Nikon.
4663 *
4664 * params: PTPParams*
4665 * PTPUSBEventContainer **event - list of usb events.
4666 * int *evtcnt - number of usb events in event structure.
4667 *
4668 * Return values: Some PTP_RC_* code.
4669 *
4670 **/
4671 uint16_t
4672 ptp_nikon_check_eventex (PTPParams* params, PTPContainer** event, unsigned int* evtcnt)
4673 {
4674 PTPContainer ptp;
4675 unsigned char *data = NULL;
4676 unsigned int size;
4677
4678 PTP_CNT_INIT(ptp, PTP_OC_NIKON_GetEventEx);
4679 *evtcnt = 0;
4680 CHECK_PTP_RC(ptp_transaction (params, &ptp, PTP_DP_GETDATA, 0, &data, &size));
4681 ptp_unpack_Nikon_EC_EX (params, data, size, event, evtcnt);
4682 free (data);
4683 return PTP_RC_OK;
4684 }
4685
4686 /**
4687 * ptp_nikon_getptpipinfo:
4688 *
4689 * This command gets the ptpip info data.
4690 *
4691 * params: PTPParams*
4692 * unsigned char *data - data
4693 * unsigned int size - size of returned data
4694 *
4695 * Return values: Some PTP_RC_* code.
4696 *
4697 **/
4698 uint16_t
4699 ptp_nikon_getptpipinfo (PTPParams* params, unsigned char **data, unsigned int *size)
4700 {
4701 PTPContainer ptp;
4702
4703 PTP_CNT_INIT(ptp, PTP_OC_NIKON_GetDevicePTPIPInfo);
4704 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, data, size);
4705 }
4706
4707 /**
4708 * ptp_nikon_getwifiprofilelist:
4709 *
4710 * This command gets the wifi profile list.
4711 *
4712 * params: PTPParams*
4713 *
4714 * Return values: Some PTP_RC_* code.
4715 *
4716 **/
4717 uint16_t
4718 ptp_nikon_getwifiprofilelist (PTPParams* params)
4719 {
4720 PTPContainer ptp;
4721 uint16_t ret;
4722 unsigned char *data = NULL;
4723 unsigned int size, pos, profn, n;
4724 char *buffer;
4725 uint8_t len;
4726
4727 PTP_CNT_INIT(ptp, PTP_OC_NIKON_GetProfileAllData);
4728 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size));
4729
4730 ret = PTP_RC_Undefined; /* FIXME: Add more precise error code */
4731
4732 if (size < 2)
4733 goto exit;
4734
4735 params->wifi_profiles_version = data[0];
4736 params->wifi_profiles_number = data[1];
4737 free(params->wifi_profiles);
4738
4739 params->wifi_profiles = calloc(params->wifi_profiles_number,sizeof(PTPNIKONWifiProfile));
4740
4741 pos = 2;
4742 profn = 0;
4743 while (profn < params->wifi_profiles_number && pos < size) {
4744 if (pos+6 >= size)
4745 goto exit;
4746 params->wifi_profiles[profn].id = data[pos++];
4747 params->wifi_profiles[profn].valid = data[pos++];
4748
4749 n = dtoh32a(&data[pos]);
4750 pos += 4;
4751 if (pos+n+4 >= size)
4752 goto exit;
4753 strncpy(params->wifi_profiles[profn].profile_name, (char*)&data[pos], n);
4754 params->wifi_profiles[profn].profile_name[16] = '\0';
4755 pos += n;
4756
4757 params->wifi_profiles[profn].display_order = data[pos++];
4758 params->wifi_profiles[profn].device_type = data[pos++];
4759 params->wifi_profiles[profn].icon_type = data[pos++];
4760
4761 if (!ptp_unpack_string(params, data, pos, size, &len, &buffer))
4762 goto exit;
4763 strncpy(params->wifi_profiles[profn].creation_date, buffer, sizeof(params->wifi_profiles[profn].creation_date));
4764 free (buffer);
4765 pos += (len*2+1);
4766 if (pos+1 >= size)
4767 goto exit;
4768 /* FIXME: check if it is really last usage date */
4769 if (!ptp_unpack_string(params, data, pos, size, &len, &buffer))
4770 goto exit;
4771 strncpy(params->wifi_profiles[profn].lastusage_date, buffer, sizeof(params->wifi_profiles[profn].lastusage_date));
4772 free (buffer);
4773 pos += (len*2+1);
4774 if (pos+5 >= size)
4775 goto exit;
4776
4777 n = dtoh32a(&data[pos]);
4778 pos += 4;
4779 if (pos+n >= size)
4780 goto exit;
4781 strncpy(params->wifi_profiles[profn].essid, (char*)&data[pos], n);
4782 params->wifi_profiles[profn].essid[32] = '\0';
4783 pos += n;
4784 pos += 1;
4785 profn++;
4786 }
4787
4788 #if 0
4789 PTPNIKONWifiProfile test;
4790 memset(&test, 0, sizeof(PTPNIKONWifiProfile));
4791 strcpy(test.profile_name, "MyTest");
4792 test.icon_type = 1;
4793 strcpy(test.essid, "nikon");
4794 test.ip_address = 10 + 11 << 16 + 11 << 24;
4795 test.subnet_mask = 24;
4796 test.access_mode = 1;
4797 test.wifi_channel = 1;
4798 test.key_nr = 1;
4799
4800 ptp_nikon_writewifiprofile(params, &test);
4801 #endif
4802 /* everything went Ok */
4803 ret = PTP_RC_OK;
4804 exit:
4805 free (data);
4806 return ret;
4807 }
4808
4809 /**
4810 * ptp_nikon_writewifiprofile:
4811 *
4812 * This command gets the ptpip info data.
4813 *
4814 * params: PTPParams*
4815 * unsigned int profilenr - profile number
4816 * unsigned char *data - data
4817 * unsigned int size - size of returned data
4818 *
4819 * Return values: Some PTP_RC_* code.
4820 *
4821 **/
4822 uint16_t
4823 ptp_nikon_writewifiprofile (PTPParams* params, PTPNIKONWifiProfile* profile)
4824 {
4825 PTPContainer ptp;
4826 unsigned char buffer[1024];
4827 unsigned char* data = buffer;
4828 int size = 0;
4829 int i;
4830 uint8_t len;
4831 int profilenr = -1;
4832 unsigned char guid[16];
4833
4834 ptp_nikon_getptpipguid(guid);
4835
4836 if (!params->wifi_profiles)
4837 CHECK_PTP_RC(ptp_nikon_getwifiprofilelist(params));
4838
4839 for (i = 0; i < params->wifi_profiles_number; i++) {
4840 if (!params->wifi_profiles[i].valid) {
4841 profilenr = params->wifi_profiles[i].id;
4842 break;
4843 }
4844 }
4845
4846 if (profilenr == -1) {
4847 /* No free profile! */
4848 return PTP_RC_StoreFull;
4849 }
4850
4851 memset(buffer, 0, 1024);
4852
4853 buffer[0x00] = 0x64; /* Version */
4854
4855 /* Profile name */
4856 htod32a(&buffer[0x01], 17);
4857 /* 16 as third parameter, so there will always be a null-byte in the end */
4858 strncpy((char*)&buffer[0x05], profile->profile_name, 16);
4859
4860 buffer[0x16] = 0x00; /* Display order */
4861 buffer[0x17] = profile->device_type;
4862 buffer[0x18] = profile->icon_type;
4863
4864 /* FIXME: Creation date: put a real date here */
4865 ptp_pack_string(params, "19990909T090909", data, 0x19, &len);
4866
4867 /* IP parameters */
4868 memcpy(&buffer[0x3A],&profile->ip_address,sizeof(profile->ip_address));
4869 /**((unsigned int*)&buffer[0x3A]) = profile->ip_address; *//* Do not reverse bytes */
4870 buffer[0x3E] = profile->subnet_mask;
4871 memcpy(&buffer[0x3F],&profile->gateway_address,sizeof(profile->gateway_address));
4872 /**((unsigned int*)&buffer[0x3F]) = profile->gateway_address; */ /* Do not reverse bytes */
4873 buffer[0x43] = profile->address_mode;
4874
4875 /* Wifi parameters */
4876 buffer[0x44] = profile->access_mode;
4877 buffer[0x45] = profile->wifi_channel;
4878
4879 htod32a(&buffer[0x46], 33); /* essid */
4880 /* 32 as third parameter, so there will always be a null-byte in the end */
4881 strncpy((char*)&buffer[0x4A], profile->essid, 32);
4882
4883 buffer[0x6B] = profile->authentification;
4884 buffer[0x6C] = profile->encryption;
4885 htod32a(&buffer[0x6D], 64);
4886 for (i = 0; i < 64; i++) {
4887 buffer[0x71+i] = profile->key[i];
4888 }
4889 buffer[0xB1] = profile->key_nr;
4890 memcpy(&buffer[0xB2], guid, 16);
4891
4892 switch(profile->encryption) {
4893 case 1: /* WEP 64bit */
4894 htod16a(&buffer[0xC2], 5); /* (64-24)/8 = 5 */
4895 break;
4896 case 2: /* WEP 128bit */
4897 htod16a(&buffer[0xC2], 13); /* (128-24)/8 = 13 */
4898 break;
4899 default:
4900 htod16a(&buffer[0xC2], 0);
4901 }
4902 size = 0xC4;
4903
4904 PTP_CNT_INIT(ptp, PTP_OC_NIKON_SendProfileData, profilenr);
4905 return ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, &data, NULL);
4906 }
4907
4908 /**
4909 * ptp_mtp_getobjectpropssupported:
4910 *
4911 * This command gets the object properties possible from the device.
4912 *
4913 * params: PTPParams*
4914 * uint ofc - object format code
4915 * unsigned int *propnum - number of elements in returned array
4916 * uint16_t *props - array of supported properties
4917 *
4918 * Return values: Some PTP_RC_* code.
4919 *
4920 **/
4921 uint16_t
4922 ptp_mtp_getobjectpropssupported (PTPParams* params, uint16_t ofc,
4923 uint32_t *propnum, uint16_t **props
4924 ) {
4925 PTPContainer ptp;
4926 unsigned char *data = NULL;
4927 unsigned int xsize = 0;
4928
4929 PTP_CNT_INIT(ptp, PTP_OC_MTP_GetObjectPropsSupported, ofc);
4930 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &xsize));
4931 if (!data) return PTP_RC_GeneralError;
4932 *propnum=ptp_unpack_uint16_t_array (params, data, 0, xsize, props);
4933 free(data);
4934 return PTP_RC_OK;
4935 }
4936
4937 /**
4938 * ptp_mtp_getobjectpropdesc:
4939 *
4940 * This command gets the object property description.
4941 *
4942 * params: PTPParams*
4943 * uint16_t opc - object property code
4944 * uint16_t ofc - object format code
4945 *
4946 * Return values: Some PTP_RC_* code.
4947 *
4948 **/
4949 uint16_t
4950 ptp_mtp_getobjectpropdesc (
4951 PTPParams* params, uint16_t opc, uint16_t ofc, PTPObjectPropDesc *opd
4952 ) {
4953 PTPContainer ptp;
4954 unsigned char *data = NULL;
4955 unsigned int size;
4956
4957 PTP_CNT_INIT(ptp, PTP_OC_MTP_GetObjectPropDesc, opc, ofc);
4958 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size));
4959 ptp_unpack_OPD (params, data, opd, size);
4960 free(data);
4961 return PTP_RC_OK;
4962 }
4963
4964 /**
4965 * ptp_mtp_getobjectpropvalue:
4966 *
4967 * This command gets the object properties of an object handle.
4968 *
4969 * params: PTPParams*
4970 * uint32_t objectid - object format code
4971 * uint16_t opc - object prop code
4972 *
4973 * Return values: Some PTP_RC_* code.
4974 *
4975 **/
4976 uint16_t
4977 ptp_mtp_getobjectpropvalue (
4978 PTPParams* params, uint32_t oid, uint16_t opc,
4979 PTPPropertyValue *value, uint16_t datatype
4980 ) {
4981 PTPContainer ptp;
4982 uint16_t ret = PTP_RC_OK;
4983 unsigned char *data = NULL;
4984 unsigned int size, offset = 0;
4985
4986 PTP_CNT_INIT(ptp, PTP_OC_MTP_GetObjectPropValue, oid, opc);
4987 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size));
4988 if (!ptp_unpack_DPV(params, data, &offset, size, value, datatype)) {
4989 ptp_debug (params, "ptp_mtp_getobjectpropvalue: unpacking DPV failed");
4990 ret = PTP_RC_GeneralError;
4991 }
4992 free(data);
4993 return ret;
4994 }
4995
4996 /**
4997 * ptp_mtp_setobjectpropvalue:
4998 *
4999 * This command gets the object properties of an object handle.
5000 *
5001 * params: PTPParams*
5002 * uint32_t objectid - object format code
5003 * uint16_t opc - object prop code
5004 *
5005 * Return values: Some PTP_RC_* code.
5006 *
5007 **/
5008 uint16_t
5009 ptp_mtp_setobjectpropvalue (
5010 PTPParams* params, uint32_t oid, uint16_t opc,
5011 PTPPropertyValue *value, uint16_t datatype
5012 ) {
5013 PTPContainer ptp;
5014 uint16_t ret;
5015 unsigned char *data = NULL;
5016 uint32_t size;
5017
5018 PTP_CNT_INIT(ptp, PTP_OC_MTP_SetObjectPropValue, oid, opc);
5019 size = ptp_pack_DPV(params, value, &data, datatype);
5020 ret = ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, &data, NULL);
5021 free(data);
5022 return ret;
5023 }
5024
5025 uint16_t
5026 ptp_mtp_getobjectreferences (PTPParams* params, uint32_t handle, uint32_t** ohArray, uint32_t* arraylen)
5027 {
5028 PTPContainer ptp;
5029 unsigned char *data = NULL;
5030 unsigned int size;
5031
5032 PTP_CNT_INIT(ptp, PTP_OC_MTP_GetObjectReferences, handle);
5033 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data , &size));
5034 /* Sandisk Sansa skips the DATA phase, but returns OK as response.
5035 * this will gives us a NULL here. Handle it. -Marcus */
5036 if ((data == NULL) || (size == 0)) {
5037 *arraylen = 0;
5038 *ohArray = NULL;
5039 } else {
5040 *arraylen = ptp_unpack_uint32_t_array(params, data , 0, size, ohArray);
5041 }
5042 free(data);
5043 return PTP_RC_OK;
5044 }
5045
5046 uint16_t
5047 ptp_mtp_setobjectreferences (PTPParams* params, uint32_t handle, uint32_t* ohArray, uint32_t arraylen)
5048 {
5049 PTPContainer ptp;
5050 uint16_t ret;
5051 unsigned char *data = NULL;
5052 uint32_t size;
5053
5054 PTP_CNT_INIT(ptp, PTP_OC_MTP_SetObjectReferences, handle);
5055 size = ptp_pack_uint32_t_array(params, ohArray, arraylen, &data);
5056 ret = ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, &data, NULL);
5057 free(data);
5058 return ret;
5059 }
5060
5061 uint16_t
5062 ptp_mtp_getobjectproplist_generic (PTPParams* params, uint32_t handle, uint32_t formats, uint32_t properties, uint32_t propertygroups, uint32_t level, MTPProperties **props, int *nrofprops)
5063 {
5064 PTPContainer ptp;
5065 unsigned char *data = NULL;
5066 unsigned int size;
5067
5068 PTP_CNT_INIT(ptp, PTP_OC_MTP_GetObjPropList, handle, formats, properties, propertygroups, level);
5069 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size));
5070 *nrofprops = ptp_unpack_OPL(params, data, props, size);
5071 free(data);
5072 return PTP_RC_OK;
5073 }
5074
5075 uint16_t
5076 ptp_mtp_getobjectproplist_level (PTPParams* params, uint32_t handle, uint32_t level, MTPProperties **props, int *nrofprops)
5077 {
5078 return ptp_mtp_getobjectproplist_generic (params, handle,
5079 0x00000000U, /* 0x00000000U should be "all formats" */
5080 0xFFFFFFFFU, /* 0xFFFFFFFFU should be "all properties" */
5081 0,
5082 level,
5083 props,
5084 nrofprops
5085 );
5086 }
5087
5088
5089 uint16_t
5090 ptp_mtp_getobjectproplist (PTPParams* params, uint32_t handle, MTPProperties **props, int *nrofprops)
5091 {
5092 return ptp_mtp_getobjectproplist_level(params, handle, 0xFFFFFFFFU, props, nrofprops);
5093 }
5094
5095 uint16_t
5096 ptp_mtp_getobjectproplist_single (PTPParams* params, uint32_t handle, MTPProperties **props, int *nrofprops)
5097 {
5098 return ptp_mtp_getobjectproplist_level(params, handle, 0, props, nrofprops);
5099 }
5100
5101 uint16_t
5102 ptp_mtp_sendobjectproplist (PTPParams* params, uint32_t* store, uint32_t* parenthandle, uint32_t* handle,
5103 uint16_t objecttype, uint64_t objectsize, MTPProperties *props, int nrofprops)
5104 {
5105 PTPContainer ptp;
5106 uint16_t ret;
5107 unsigned char *data = NULL;
5108 uint32_t size;
5109
5110 PTP_CNT_INIT(ptp, PTP_OC_MTP_SendObjectPropList, *store, *parenthandle, (uint32_t) objecttype,
5111 (uint32_t) (objectsize >> 32), (uint32_t) (objectsize & 0xffffffffU)
5112 );
5113
5114 /* Set object handle to 0 for a new object */
5115 size = ptp_pack_OPL(params,props,nrofprops,&data);
5116 ret = ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, &data, NULL);
5117 free(data);
5118 *store = ptp.Param1;
5119 *parenthandle = ptp.Param2;
5120 *handle = ptp.Param3;
5121
5122 return ret;
5123 }
5124
5125 uint16_t
5126 ptp_mtp_setobjectproplist (PTPParams* params, MTPProperties *props, int nrofprops)
5127 {
5128 PTPContainer ptp;
5129 unsigned char *data = NULL;
5130 uint32_t size;
5131
5132 PTP_CNT_INIT(ptp, PTP_OC_MTP_SetObjPropList);
5133 size = ptp_pack_OPL(params,props,nrofprops,&data);
5134 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, &data, NULL));
5135 free(data);
5136 return PTP_RC_OK;
5137 }
5138
5139 uint16_t
5140 ptp_mtpz_sendwmdrmpdapprequest (PTPParams* params, unsigned char *appcertmsg, uint32_t size)
5141 {
5142 PTPContainer ptp;
5143
5144 PTP_CNT_INIT(ptp, PTP_OC_MTP_WMDRMPD_SendWMDRMPDAppRequest);
5145 return ptp_transaction (params, &ptp, PTP_DP_SENDDATA, size, &appcertmsg, NULL);
5146 }
5147
5148 uint16_t
5149 ptp_mtpz_getwmdrmpdappresponse (PTPParams* params, unsigned char **response, uint32_t *size)
5150 {
5151 PTPContainer ptp;
5152
5153 PTP_CNT_INIT(ptp, PTP_OC_MTP_WMDRMPD_GetWMDRMPDAppResponse);
5154 *size = 0;
5155 *response = NULL;
5156 return ptp_transaction (params, &ptp, PTP_DP_GETDATA, 0, response, size);
5157 }
5158
5159 /****** CHDK interface ******/
5160
5161 uint16_t
5162 ptp_chdk_get_memory(PTPParams* params, int start, int num, unsigned char **buf)
5163 {
5164 PTPContainer ptp;
5165
5166 PTP_CNT_INIT(ptp, PTP_OC_CHDK, PTP_CHDK_GetMemory, start, num);
5167 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, buf, NULL);
5168 }
5169
5170 uint16_t
5171 ptp_chdk_set_memory_long(PTPParams* params, int addr, int val)
5172 {
5173 PTPContainer ptp;
5174 unsigned char *buf = (unsigned char *) &val; /* FIXME ... endianness? */
5175
5176 PTP_CNT_INIT(ptp, PTP_OC_CHDK, PTP_CHDK_SetMemory, addr, 4);
5177 return ptp_transaction(params, &ptp, PTP_DP_SENDDATA, 4, &buf, NULL);
5178 }
5179
5180 uint16_t
5181 ptp_chdk_download(PTPParams* params, char *remote_fn, PTPDataHandler *handler)
5182 {
5183 PTPContainer ptp;
5184
5185 PTP_CNT_INIT(ptp, PTP_OC_CHDK, PTP_CHDK_TempData, 0);
5186 CHECK_PTP_RC (ptp_transaction(params, &ptp, PTP_DP_SENDDATA, strlen(remote_fn), (unsigned char**)&remote_fn, NULL));
5187
5188 PTP_CNT_INIT(ptp, PTP_OC_CHDK, PTP_CHDK_DownloadFile);
5189 return ptp_transaction_new (params, &ptp, PTP_DP_GETDATA, 0, handler);
5190 }
5191
5192 #if 0
5193 int ptp_chdk_upload(PTPParams* params, char *local_fn, char *remote_fn)
5194 {
5195 uint16_t ret;
5196 PTPContainer ptp;
5197 char *buf = NULL;
5198 FILE *f;
5199 unsigned file_len,data_len,file_name_len;
5200
5201 PTP_CNT_INIT(ptp, PTP_OC_CHDK, PTP_CHDK_UploadFile);
5202
5203 f = fopen(local_fn,"rb");
5204 if ( f == NULL )
5205 {
5206 ptp_error(params,"could not open file \'%s\'",local_fn);
5207 return 0;
5208 }
5209
5210 fseek(f,0,SEEK_END);
5211 file_len = ftell(f);
5212 fseek(f,0,SEEK_SET);
5213
5214 file_name_len = strlen(remote_fn);
5215 data_len = 4 + file_name_len + file_len;
5216 buf = malloc(data_len);
5217 memcpy(buf,&file_name_len,4);
5218 memcpy(buf+4,remote_fn,file_name_len);
5219 fread(buf+4+file_name_len,1,file_len,f);
5220
5221 fclose(f);
5222
5223 ret=ptp_transaction(params, &ptp, PTP_DP_SENDDATA, data_len, &buf, NULL);
5224
5225 free(buf);
5226
5227 if ( ret != PTP_RC_OK )
5228 {
5229 ptp_error(params,"unexpected return code 0x%x",ret);
5230 return 0;
5231 }
5232 return 1;
5233 }
5234
5235 #endif
5236
5237 /*
5238 * Preliminary remote capture over USB code. Corresponding CHDK code is in the ptp-remote-capture-test
5239 * This is under development and should not be included in builds for general distribution
5240 */
5241 /*
5242 * isready: 0: not ready, lowest 2 bits: available image formats, 0x10000000: error
5243 */
5244 uint16_t
5245 ptp_chdk_rcisready(PTPParams* params, int *isready, int *imgnum)
5246 {
5247 PTPContainer ptp;
5248
5249 PTP_CNT_INIT(ptp, PTP_OC_CHDK, PTP_CHDK_RemoteCaptureIsReady);
5250 *isready = *imgnum = 0;
5251 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL));
5252 *isready=ptp.Param1;
5253 *imgnum=ptp.Param2;
5254 return PTP_RC_OK;
5255 }
5256
5257 uint16_t
5258 ptp_chdk_rcgetchunk(PTPParams* params, int fmt, ptp_chdk_rc_chunk *chunk)
5259 {
5260 PTPContainer ptp;
5261
5262 PTP_CNT_INIT(ptp, PTP_OC_CHDK, PTP_CHDK_RemoteCaptureGetData, fmt); //get chunk
5263
5264 chunk->data = NULL;
5265 chunk->size = 0;
5266 chunk->offset = 0;
5267 chunk->last = 0;
5268 // TODO should allow ptp_getdata_transaction to send chunks directly to file, or to mem
5269 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &chunk->data, NULL));
5270 chunk->size = ptp.Param1;
5271 chunk->last = (ptp.Param2 == 0);
5272 chunk->offset = ptp.Param3; //-1 for none
5273 return PTP_RC_OK;
5274 }
5275
5276 uint16_t
5277 ptp_chdk_exec_lua(PTPParams* params, char *script, int flags, int *script_id, int *status)
5278 {
5279 PTPContainer ptp;
5280
5281 PTP_CNT_INIT(ptp, PTP_OC_CHDK, PTP_CHDK_ExecuteScript, PTP_CHDK_SL_LUA | flags);
5282 *script_id = 0;
5283 *status = 0;
5284 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_SENDDATA, strlen(script)+1, (unsigned char**)&script, NULL));
5285 *script_id = ptp.Param1;
5286 *status = ptp.Param2;
5287 return PTP_RC_OK;
5288 }
5289
5290 uint16_t
5291 ptp_chdk_get_version(PTPParams* params, int *major, int *minor)
5292 {
5293 PTPContainer ptp;
5294
5295 PTP_CNT_INIT(ptp, PTP_OC_CHDK, PTP_CHDK_Version);
5296 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL));
5297 *major = ptp.Param1;
5298 *minor = ptp.Param2;
5299 return PTP_RC_OK;
5300 }
5301
5302 uint16_t
5303 ptp_chdk_get_script_status(PTPParams* params, unsigned *status)
5304 {
5305 PTPContainer ptp;
5306
5307 PTP_CNT_INIT(ptp, PTP_OC_CHDK, PTP_CHDK_ScriptStatus);
5308 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL));
5309 *status = ptp.Param1;
5310 return PTP_RC_OK;
5311 }
5312 uint16_t
5313 ptp_chdk_get_script_support(PTPParams* params, unsigned *status)
5314 {
5315 PTPContainer ptp;
5316
5317 PTP_CNT_INIT(ptp, PTP_OC_CHDK, PTP_CHDK_ScriptSupport);
5318 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL));
5319 *status = ptp.Param1;
5320 return PTP_RC_OK;
5321 }
5322