blob: 645e1b3479b69671bace48e8790dbed85c4b4a7a [file] [log] [blame]
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001/* ptp.c
2 *
Linus Walleijb02a0662006-04-25 08:05:09 +00003 * Copyright (C) 2001-2004 Mariusz Woloszyn <emsi@ipartners.pl>
4 * Copyright (C) 2003-2006 Marcus Meissner <marcus@jet.franken.de>
Linus Walleija823a702006-08-27 21:27:46 +00005 * Copyright (C) 2006 Linus Walleij <triad@df.lth.se>
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00006 *
Linus Walleijb02a0662006-04-25 08:05:09 +00007 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
Linus Walleijeb8c6fe2006-02-03 09:46:22 +000011 *
Linus Walleijb02a0662006-04-25 08:05:09 +000012 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
Linus Walleijeb8c6fe2006-02-03 09:46:22 +000016 *
Linus Walleijb02a0662006-04-25 08:05:09 +000017 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
Linus Walleijeb8c6fe2006-02-03 09:46:22 +000021 */
22
23#include <config.h>
24#include "ptp.h"
Linus Walleijeb8c6fe2006-02-03 09:46:22 +000025
26#include <stdlib.h>
27#include <stdarg.h>
28#include <stdio.h>
29#include <string.h>
Linus Walleij96c62432006-08-21 10:04:02 +000030#include <unistd.h>
Linus Walleijeb8c6fe2006-02-03 09:46:22 +000031
32#ifdef ENABLE_NLS
33# include <libintl.h>
34# undef _
35# define _(String) dgettext (PACKAGE, String)
36# ifdef gettext_noop
37# define N_(String) gettext_noop (String)
38# else
39# define N_(String) (String)
40# endif
41#else
42# define textdomain(String) (String)
43# define gettext(String) (String)
44# define dgettext(Domain,Message) (Message)
45# define dcgettext(Domain,Message,Type) (Message)
46# define bindtextdomain(Domain,Directory) (Domain)
47# define _(String) (String)
48# define N_(String) (String)
49#endif
50
Linus Walleijb02a0662006-04-25 08:05:09 +000051#define CHECK_PTP_RC(result) {uint16_t r=(result); if (r!=PTP_RC_OK) return r;}
52
53#define PTP_CNT_INIT(cnt) {memset(&cnt,0,sizeof(cnt));}
Linus Walleijeb8c6fe2006-02-03 09:46:22 +000054
55static void
56ptp_debug (PTPParams *params, const char *format, ...)
57{
58 va_list args;
59
60 va_start (args, format);
61 if (params->debug_func!=NULL)
62 params->debug_func (params->data, format, args);
63 else
64 {
65 vfprintf (stderr, format, args);
66 fprintf (stderr,"\n");
67 fflush (stderr);
68 }
69 va_end (args);
70}
71
72static void
73ptp_error (PTPParams *params, const char *format, ...)
74{
75 va_list args;
76
77 va_start (args, format);
78 if (params->error_func!=NULL)
79 params->error_func (params->data, format, args);
80 else
81 {
82 vfprintf (stderr, format, args);
83 fprintf (stderr,"\n");
84 fflush (stderr);
85 }
86 va_end (args);
87}
88
Linus Walleijb02a0662006-04-25 08:05:09 +000089/* Pack / unpack functions */
90
91#include "ptp-pack.c"
92
Linus Walleijeb8c6fe2006-02-03 09:46:22 +000093/* send / receive functions */
94
95uint16_t
96ptp_usb_sendreq (PTPParams* params, PTPContainer* req)
97{
98 uint16_t ret;
99 PTPUSBBulkContainer usbreq;
100
101 /* build appropriate USB container */
102 usbreq.length=htod32(PTP_USB_BULK_REQ_LEN-
103 (sizeof(uint32_t)*(5-req->Nparam)));
104 usbreq.type=htod16(PTP_USB_CONTAINER_COMMAND);
105 usbreq.code=htod16(req->Code);
106 usbreq.trans_id=htod32(req->Transaction_ID);
107 usbreq.payload.params.param1=htod32(req->Param1);
108 usbreq.payload.params.param2=htod32(req->Param2);
109 usbreq.payload.params.param3=htod32(req->Param3);
110 usbreq.payload.params.param4=htod32(req->Param4);
111 usbreq.payload.params.param5=htod32(req->Param5);
112 /* send it to responder */
113 ret=params->write_func((unsigned char *)&usbreq,
114 PTP_USB_BULK_REQ_LEN-(sizeof(uint32_t)*(5-req->Nparam)),
115 params->data);
116 if (ret!=PTP_RC_OK) {
117 ret = PTP_ERROR_IO;
118/* ptp_error (params,
119 "PTP: request code 0x%04x sending req error 0x%04x",
120 req->Code,ret); */
121 }
122 return ret;
123}
124
Linus Walleije7f44be2006-08-25 19:32:29 +0000125/* Used for file transactions */
126#define FILE_BUFFER_SIZE 0x10000
127
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000128uint16_t
129ptp_usb_senddata (PTPParams* params, PTPContainer* ptp,
Linus Walleije7f44be2006-08-25 19:32:29 +0000130 unsigned char *data, unsigned int size,
131 int from_fd)
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000132{
133 uint16_t ret;
Linus Walleijb02a0662006-04-25 08:05:09 +0000134 int wlen, datawlen;
Linus Walleije7f44be2006-08-25 19:32:29 +0000135 size_t written;
Linus Walleijb02a0662006-04-25 08:05:09 +0000136 PTPUSBBulkContainer usbdata;
137
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000138 /* build appropriate USB container */
Linus Walleijb02a0662006-04-25 08:05:09 +0000139 usbdata.length = htod32(PTP_USB_BULK_HDR_LEN+size);
140 usbdata.type = htod16(PTP_USB_CONTAINER_DATA);
141 usbdata.code = htod16(ptp->Code);
142 usbdata.trans_id= htod32(ptp->Transaction_ID);
143
144 if (params->split_header_data) {
145 datawlen = 0;
146 wlen = PTP_USB_BULK_HDR_LEN;
147 } else {
148 /* For all camera devices. */
149 datawlen = (size<PTP_USB_BULK_PAYLOAD_LEN)?size:PTP_USB_BULK_PAYLOAD_LEN;
150 wlen = PTP_USB_BULK_HDR_LEN + datawlen;
Linus Walleije7f44be2006-08-25 19:32:29 +0000151 if (from_fd == -1) {
152 memcpy(usbdata.payload.data, data, datawlen);
153 } else {
154 written = read(from_fd, usbdata.payload.data, datawlen);
155 if (written != datawlen)
156 return PTP_ERROR_IO;
157 }
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000158 }
Linus Walleijb02a0662006-04-25 08:05:09 +0000159 /* send first part of data */
160 ret = params->write_func((unsigned char *)&usbdata, wlen, params->data);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000161 if (ret!=PTP_RC_OK) {
162 ret = PTP_ERROR_IO;
Linus Walleijb02a0662006-04-25 08:05:09 +0000163/* ptp_error (params,
164 "PTP: request code 0x%04x sending data error 0x%04x",
165 ptp->Code,ret);*/
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000166 return ret;
167 }
Linus Walleijb02a0662006-04-25 08:05:09 +0000168 if (size <= datawlen) return ret;
169 /* if everything OK send the rest */
Linus Walleije7f44be2006-08-25 19:32:29 +0000170 if (from_fd == -1) {
171 ret=params->write_func (data + datawlen, size - datawlen, params->data);
172 } else {
173 uint32_t bytes_to_transfer;
174 uint32_t bytes_left_to_transfer;
175 void *temp_buf;
176
177 written = 0;
178 bytes_left_to_transfer = size-datawlen;
179
180 temp_buf = malloc(FILE_BUFFER_SIZE);
181 if (temp_buf == NULL)
182 return PTP_ERROR_IO;
183
184 ret = PTP_RC_OK;
185 while(bytes_left_to_transfer > 0) {
186 if (bytes_left_to_transfer > FILE_BUFFER_SIZE) {
187 bytes_to_transfer = FILE_BUFFER_SIZE;
188 } else {
189 bytes_to_transfer = bytes_left_to_transfer;
190 }
191 written = read(from_fd, temp_buf, bytes_to_transfer);
192 if (written != bytes_to_transfer) {
193 ret = PTP_ERROR_IO;
194 break;
195 }
196 ret=params->write_func (temp_buf, bytes_to_transfer, params->data);
197 bytes_left_to_transfer -= bytes_to_transfer;
198 }
199 free(temp_buf);
200
201 }
Linus Walleijb02a0662006-04-25 08:05:09 +0000202 if (ret!=PTP_RC_OK) {
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000203 ret = PTP_ERROR_IO;
Linus Walleijb02a0662006-04-25 08:05:09 +0000204/* ptp_error (params,
205 "PTP: request code 0x%04x sending data error 0x%04x",
206 ptp->Code,ret); */
207 }
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000208 return ret;
209}
210
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000211uint16_t
212ptp_usb_getdata (PTPParams* params, PTPContainer* ptp,
Linus Walleij96c62432006-08-21 10:04:02 +0000213 unsigned char **data, unsigned int *readlen,
214 int to_fd)
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000215{
216 uint16_t ret;
217 PTPUSBBulkContainer usbdata;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000218
219 PTP_CNT_INIT(usbdata);
Linus Walleij96c62432006-08-21 10:04:02 +0000220
221 if (to_fd == -1 && *data != NULL)
222 return PTP_ERROR_BADPARAM;
223
Linus Walleijb02a0662006-04-25 08:05:09 +0000224 do {
225 unsigned int len, rlen;
226 /* read the header and potentially the first data */
227 ret=params->read_func((unsigned char *)&usbdata,
228 sizeof(usbdata), params->data, &rlen);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000229 if (ret!=PTP_RC_OK) {
230 ret = PTP_ERROR_IO;
Linus Walleijb02a0662006-04-25 08:05:09 +0000231 break;
232 } else
233 if (dtoh16(usbdata.type)!=PTP_USB_CONTAINER_DATA) {
234 ret = PTP_ERROR_DATA_EXPECTED;
235 break;
236 } else
237 if (dtoh16(usbdata.code)!=ptp->Code) {
238 ret = dtoh16(usbdata.code);
239 break;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000240 }
Linus Walleijc60275a2006-04-30 10:58:11 +0000241 if (rlen > dtoh32(usbdata.length)) {
242 /* I observed this on iRiver MTP devices. -Marcus */
243 ptp_debug (params, "ptp2/ptp_usb_getdata: read %d bytes too much, expect problems!", rlen - dtoh32(usbdata.length)
244 );
245 rlen = dtoh32(usbdata.length);
246 }
Linus Walleijb02a0662006-04-25 08:05:09 +0000247
248 /* For most PTP devices rlen is 512 == sizeof(usbdata)
249 * here. For MTP devices splitting header and data it might
250 * be 12.
251 */
252 /* Evaluate full data length. */
253 len=dtoh32(usbdata.length)-PTP_USB_BULK_HDR_LEN;
254
255 /* autodetect split header/data MTP devices */
256 if (dtoh32(usbdata.length) > 12 && (rlen==12))
257 params->split_header_data = 1;
258
Linus Walleij96c62432006-08-21 10:04:02 +0000259 if (to_fd == -1) {
260 /* Allocate memory for data. */
261 *data=calloc(len,1);
262 if (readlen)
263 *readlen = len;
Linus Walleijb02a0662006-04-25 08:05:09 +0000264
Linus Walleij96c62432006-08-21 10:04:02 +0000265 /* Copy first part of data to 'data' */
266 memcpy(*data,usbdata.payload.data,rlen - PTP_USB_BULK_HDR_LEN);
Linus Walleijb02a0662006-04-25 08:05:09 +0000267
Linus Walleij96c62432006-08-21 10:04:02 +0000268 /* Is that all of data? */
269 if (len+PTP_USB_BULK_HDR_LEN<=rlen) break;
Linus Walleijb02a0662006-04-25 08:05:09 +0000270
Linus Walleij96c62432006-08-21 10:04:02 +0000271 /* If not read the rest of it. */
272 ret=params->read_func(((unsigned char *)(*data))+
273 rlen - PTP_USB_BULK_HDR_LEN,
274 len-(rlen - PTP_USB_BULK_HDR_LEN),
275 params->data, &rlen);
276 if (ret!=PTP_RC_OK) {
277 ret = PTP_ERROR_IO;
278 break;
279 }
280 } else {
281 uint32_t bytes_to_write, written;
282 uint32_t bytes_left_to_transfer;
Linus Walleij96c62432006-08-21 10:04:02 +0000283 void *temp_buf;
284
285 if (readlen)
286 *readlen = len;
287
288 bytes_to_write = rlen - PTP_USB_BULK_HDR_LEN;
289
290 ret = write(to_fd, usbdata.payload.data, bytes_to_write);
291 if (ret != bytes_to_write) {
292 ret = PTP_ERROR_IO;
293 break;
294 }
295
296 if (len + PTP_USB_BULK_HDR_LEN <= rlen)
297 break;
298
Linus Walleije7f44be2006-08-25 19:32:29 +0000299 temp_buf = malloc(FILE_BUFFER_SIZE);
Linus Walleij96c62432006-08-21 10:04:02 +0000300 if (temp_buf == NULL) {
301 ret = PTP_ERROR_IO;
302 break;
303 }
304
305 ret = PTP_RC_OK;
306 bytes_left_to_transfer = len - (rlen - PTP_USB_BULK_HDR_LEN);
307
308 while (bytes_left_to_transfer > 0) {
Linus Walleije7f44be2006-08-25 19:32:29 +0000309 bytes_to_write = ((bytes_left_to_transfer > FILE_BUFFER_SIZE) ?
310 FILE_BUFFER_SIZE : bytes_left_to_transfer);
Linus Walleij96c62432006-08-21 10:04:02 +0000311
312 ret = params->read_func(temp_buf,
313 bytes_to_write,
314 params->data, &rlen);
315
316 if (ret != PTP_RC_OK) {
317 ret = PTP_ERROR_IO;
318 break;
319 }
320
321 written = write(to_fd, temp_buf, bytes_to_write);
322 if (written != bytes_to_write) {
323 ret = PTP_ERROR_IO;
324 break;
325 } else {
326 ret = PTP_RC_OK;
327 }
328
329 bytes_left_to_transfer -= bytes_to_write;
330 }
331
332 free(temp_buf);
333
334 if (ret != PTP_RC_OK)
335 break;
336
Linus Walleijb02a0662006-04-25 08:05:09 +0000337 }
338 } while (0);
339/*
340 if (ret!=PTP_RC_OK) {
341 ptp_error (params,
342 "PTP: request code 0x%04x getting data error 0x%04x",
343 ptp->Code, ret);
344 }*/
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000345 return ret;
346}
347
348uint16_t
349ptp_usb_getresp (PTPParams* params, PTPContainer* resp)
350{
351 uint16_t ret;
Linus Walleijb02a0662006-04-25 08:05:09 +0000352 unsigned int rlen;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000353 PTPUSBBulkContainer usbresp;
354
355 PTP_CNT_INIT(usbresp);
356 /* read response, it should never be longer than sizeof(usbresp) */
357 ret=params->read_func((unsigned char *)&usbresp,
Linus Walleijb02a0662006-04-25 08:05:09 +0000358 sizeof(usbresp), params->data, &rlen);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000359
360 if (ret!=PTP_RC_OK) {
361 ret = PTP_ERROR_IO;
362 } else
363 if (dtoh16(usbresp.type)!=PTP_USB_CONTAINER_RESPONSE) {
364 ret = PTP_ERROR_RESP_EXPECTED;
365 } else
366 if (dtoh16(usbresp.code)!=resp->Code) {
367 ret = dtoh16(usbresp.code);
368 }
369 if (ret!=PTP_RC_OK) {
370/* ptp_error (params,
371 "PTP: request code 0x%04x getting resp error 0x%04x",
372 resp->Code, ret);*/
373 return ret;
374 }
375 /* build an appropriate PTPContainer */
376 resp->Code=dtoh16(usbresp.code);
377 resp->SessionID=params->session_id;
378 resp->Transaction_ID=dtoh32(usbresp.trans_id);
379 resp->Param1=dtoh32(usbresp.payload.params.param1);
380 resp->Param2=dtoh32(usbresp.payload.params.param2);
381 resp->Param3=dtoh32(usbresp.payload.params.param3);
382 resp->Param4=dtoh32(usbresp.payload.params.param4);
383 resp->Param5=dtoh32(usbresp.payload.params.param5);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000384 return ret;
385}
386
387/* major PTP functions */
388
Linus Walleijb02a0662006-04-25 08:05:09 +0000389/* Transaction data phase description */
390#define PTP_DP_NODATA 0x0000 /* no data phase */
391#define PTP_DP_SENDDATA 0x0001 /* sending data */
392#define PTP_DP_GETDATA 0x0002 /* receiving data */
393#define PTP_DP_DATA_MASK 0x00ff /* data phase mask */
394
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000395/**
396 * ptp_transaction:
397 * params: PTPParams*
398 * PTPContainer* ptp - general ptp container
399 * uint16_t flags - lower 8 bits - data phase description
400 * unsigned int sendlen - senddata phase data length
401 * char** data - send or receive data buffer pointer
Linus Walleijb02a0662006-04-25 08:05:09 +0000402 * int* recvlen - receive data length
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000403 *
404 * Performs PTP transaction. ptp is a PTPContainer with appropriate fields
405 * filled in (i.e. operation code and parameters). It's up to caller to do
406 * so.
407 * The flags decide thether the transaction has a data phase and what is its
408 * direction (send or receive).
409 * If transaction is sending data the sendlen should contain its length in
410 * bytes, otherwise it's ignored.
411 * The data should contain an address of a pointer to data going to be sent
412 * or is filled with such a pointer address if data are received depending
413 * od dataphase direction (send or received) or is beeing ignored (no
414 * dataphase).
415 * The memory for a pointer should be preserved by the caller, if data are
416 * beeing retreived the appropriate amount of memory is beeing allocated
417 * (the caller should handle that!).
418 *
419 * Return values: Some PTP_RC_* code.
420 * Upon success PTPContainer* ptp contains PTP Response Phase container with
421 * all fields filled in.
422 **/
Linus Walleijb02a0662006-04-25 08:05:09 +0000423static uint16_t
Linus Walleij96c62432006-08-21 10:04:02 +0000424_ptp_transaction (PTPParams* params, PTPContainer* ptp,
425 uint16_t flags, unsigned int sendlen, unsigned char** data,
Linus Walleije7f44be2006-08-25 19:32:29 +0000426 int fd, unsigned int *recvlen)
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000427{
428 if ((params==NULL) || (ptp==NULL))
429 return PTP_ERROR_BADPARAM;
Linus Walleije7f44be2006-08-25 19:32:29 +0000430
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000431 ptp->Transaction_ID=params->transaction_id++;
432 ptp->SessionID=params->session_id;
433 /* send request */
434 CHECK_PTP_RC(params->sendreq_func (params, ptp));
435 /* is there a dataphase? */
436 switch (flags&PTP_DP_DATA_MASK) {
Linus Walleijb02a0662006-04-25 08:05:09 +0000437 case PTP_DP_SENDDATA:
438 CHECK_PTP_RC(params->senddata_func(params, ptp,
Linus Walleije7f44be2006-08-25 19:32:29 +0000439 *data, sendlen, fd));
Linus Walleijb02a0662006-04-25 08:05:09 +0000440 break;
441 case PTP_DP_GETDATA:
442 CHECK_PTP_RC(params->getdata_func(params, ptp,
Linus Walleije7f44be2006-08-25 19:32:29 +0000443 (unsigned char**)data, recvlen, fd));
Linus Walleijb02a0662006-04-25 08:05:09 +0000444 break;
445 case PTP_DP_NODATA:
446 break;
447 default:
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000448 return PTP_ERROR_BADPARAM;
449 }
450 /* get response */
451 CHECK_PTP_RC(params->getresp_func(params, ptp));
Linus Walleijb02a0662006-04-25 08:05:09 +0000452
453 return ptp->Code;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000454}
455
Linus Walleij96c62432006-08-21 10:04:02 +0000456static uint16_t
457ptp_transaction (PTPParams* params, PTPContainer* ptp,
458 uint16_t flags, unsigned int sendlen, unsigned char** data,
459 unsigned int *recvlen)
460{
461 return _ptp_transaction(params, ptp, flags, sendlen, data, -1, recvlen);
462}
463
464static uint16_t
Linus Walleije7f44be2006-08-25 19:32:29 +0000465ptp_transaction_fd (PTPParams* params, PTPContainer* ptp,
Linus Walleij96c62432006-08-21 10:04:02 +0000466 uint16_t flags, unsigned int sendlen,
Linus Walleije7f44be2006-08-25 19:32:29 +0000467 int fd, unsigned int *recvlen)
Linus Walleij96c62432006-08-21 10:04:02 +0000468{
Linus Walleije7f44be2006-08-25 19:32:29 +0000469 /*
470 * This dummy data needed since _ptp_transaction()
471 * will dereference the data argument
472 */
473 unsigned char *dummydata = NULL;
474
475 return _ptp_transaction(params, ptp, flags, sendlen, &dummydata, fd, recvlen);
Linus Walleij96c62432006-08-21 10:04:02 +0000476}
477
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000478/* Enets handling functions */
479
480/* PTP Events wait for or check mode */
481#define PTP_EVENT_CHECK 0x0000 /* waits for */
482#define PTP_EVENT_CHECK_FAST 0x0001 /* checks */
483
484static inline uint16_t
485ptp_usb_event (PTPParams* params, PTPContainer* event, int wait)
486{
487 uint16_t ret;
Linus Walleijb02a0662006-04-25 08:05:09 +0000488 unsigned int rlen;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000489 PTPUSBEventContainer usbevent;
490 PTP_CNT_INIT(usbevent);
491
492 if ((params==NULL) || (event==NULL))
493 return PTP_ERROR_BADPARAM;
494
495 switch(wait) {
496 case PTP_EVENT_CHECK:
497 ret=params->check_int_func((unsigned char*)&usbevent,
Linus Walleijb02a0662006-04-25 08:05:09 +0000498 sizeof(usbevent), params->data, &rlen);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000499 break;
500 case PTP_EVENT_CHECK_FAST:
501 ret=params->check_int_fast_func((unsigned char*)
Linus Walleijb02a0662006-04-25 08:05:09 +0000502 &usbevent, sizeof(usbevent), params->data, &rlen);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000503 break;
504 default:
505 ret=PTP_ERROR_BADPARAM;
506 }
507 if (ret!=PTP_RC_OK) {
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000508 ptp_error (params,
509 "PTP: reading event an error 0x%04x occured", ret);
Linus Walleijb02a0662006-04-25 08:05:09 +0000510 ret = PTP_ERROR_IO;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000511 /* reading event error is nonfatal (for example timeout) */
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000512 }
513 /* if we read anything over interrupt endpoint it must be an event */
514 /* build an appropriate PTPContainer */
515 event->Code=dtoh16(usbevent.code);
516 event->SessionID=params->session_id;
517 event->Transaction_ID=dtoh32(usbevent.trans_id);
518 event->Param1=dtoh32(usbevent.param1);
519 event->Param2=dtoh32(usbevent.param2);
520 event->Param3=dtoh32(usbevent.param3);
521
Linus Walleijb02a0662006-04-25 08:05:09 +0000522 return ret;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000523}
524
525uint16_t
526ptp_usb_event_check (PTPParams* params, PTPContainer* event) {
527
528 return ptp_usb_event (params, event, PTP_EVENT_CHECK_FAST);
529}
530
531uint16_t
532ptp_usb_event_wait (PTPParams* params, PTPContainer* event) {
533
534 return ptp_usb_event (params, event, PTP_EVENT_CHECK);
535}
536
537/**
538 * PTP operation functions
539 *
540 * all ptp_ functions should take integer parameters
541 * in host byte order!
542 **/
543
544
545/**
546 * ptp_getdeviceinfo:
547 * params: PTPParams*
548 *
549 * Gets device info dataset and fills deviceinfo structure.
550 *
551 * Return values: Some PTP_RC_* code.
552 **/
553uint16_t
554ptp_getdeviceinfo (PTPParams* params, PTPDeviceInfo* deviceinfo)
555{
556 uint16_t ret;
Linus Walleijb02a0662006-04-25 08:05:09 +0000557 unsigned int len;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000558 PTPContainer ptp;
Linus Walleijb02a0662006-04-25 08:05:09 +0000559 unsigned char* di=NULL;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000560
561 PTP_CNT_INIT(ptp);
562 ptp.Code=PTP_OC_GetDeviceInfo;
563 ptp.Nparam=0;
Linus Walleijb02a0662006-04-25 08:05:09 +0000564 len=0;
565 ret=ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &di, &len);
566 if (ret == PTP_RC_OK) ptp_unpack_DI(params, di, deviceinfo, len);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000567 free(di);
568 return ret;
569}
570
571
572/**
573 * ptp_opensession:
574 * params: PTPParams*
575 * session - session number
576 *
577 * Establishes a new session.
578 *
579 * Return values: Some PTP_RC_* code.
580 **/
581uint16_t
582ptp_opensession (PTPParams* params, uint32_t session)
583{
584 uint16_t ret;
585 PTPContainer ptp;
586
587 ptp_debug(params,"PTP: Opening session");
588
589 /* SessonID field of the operation dataset should always
590 be set to 0 for OpenSession request! */
591 params->session_id=0x00000000;
592 /* TransactionID should be set to 0 also! */
593 params->transaction_id=0x0000000;
594
595 PTP_CNT_INIT(ptp);
596 ptp.Code=PTP_OC_OpenSession;
597 ptp.Param1=session;
598 ptp.Nparam=1;
Linus Walleijb02a0662006-04-25 08:05:09 +0000599 ret=ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000600 /* now set the global session id to current session number */
601 params->session_id=session;
602 return ret;
603}
604
605/**
606 * ptp_closesession:
607 * params: PTPParams*
608 *
609 * Closes session.
610 *
611 * Return values: Some PTP_RC_* code.
612 **/
613uint16_t
614ptp_closesession (PTPParams* params)
615{
616 PTPContainer ptp;
617
618 ptp_debug(params,"PTP: Closing session");
619
620 PTP_CNT_INIT(ptp);
621 ptp.Code=PTP_OC_CloseSession;
622 ptp.Nparam=0;
Linus Walleijb02a0662006-04-25 08:05:09 +0000623 return ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000624}
625
626/**
627 * ptp_getststorageids:
628 * params: PTPParams*
629 *
Linus Walleijb02a0662006-04-25 08:05:09 +0000630 * Gets array of StorageIDs and fills the storageids structure.
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000631 *
632 * Return values: Some PTP_RC_* code.
633 **/
634uint16_t
635ptp_getstorageids (PTPParams* params, PTPStorageIDs* storageids)
636{
637 uint16_t ret;
638 PTPContainer ptp;
Linus Walleijb02a0662006-04-25 08:05:09 +0000639 unsigned int len;
640 unsigned char* sids=NULL;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000641
642 PTP_CNT_INIT(ptp);
643 ptp.Code=PTP_OC_GetStorageIDs;
644 ptp.Nparam=0;
Linus Walleijb02a0662006-04-25 08:05:09 +0000645 len=0;
646 ret=ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &sids, &len);
647 if (ret == PTP_RC_OK) ptp_unpack_SIDs(params, sids, storageids, len);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000648 free(sids);
649 return ret;
650}
651
652/**
653 * ptp_getststorageinfo:
654 * params: PTPParams*
655 * storageid - StorageID
656 *
657 * Gets StorageInfo dataset of desired storage and fills storageinfo
658 * structure.
659 *
660 * Return values: Some PTP_RC_* code.
661 **/
662uint16_t
663ptp_getstorageinfo (PTPParams* params, uint32_t storageid,
664 PTPStorageInfo* storageinfo)
665{
666 uint16_t ret;
667 PTPContainer ptp;
Linus Walleijb02a0662006-04-25 08:05:09 +0000668 unsigned char* si=NULL;
669 unsigned int len;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000670
671 PTP_CNT_INIT(ptp);
672 ptp.Code=PTP_OC_GetStorageInfo;
673 ptp.Param1=storageid;
674 ptp.Nparam=1;
Linus Walleijb02a0662006-04-25 08:05:09 +0000675 len=0;
676 ret=ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &si, &len);
677 if (ret == PTP_RC_OK) ptp_unpack_SI(params, si, storageinfo, len);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000678 free(si);
679 return ret;
680}
681
682/**
Linus Walleij13374a42006-09-13 11:55:30 +0000683 * ptp_formatstore:
684 * params: PTPParams*
685 * storageid - StorageID
686 *
687 * Formats the storage on the device.
688 *
689 * Return values: Some PTP_RC_* code.
690 **/
691uint16_t
692ptp_formatstore (PTPParams* params, uint32_t storageid)
693{
Linus Walleij13374a42006-09-13 11:55:30 +0000694 PTPContainer ptp;
695
696 PTP_CNT_INIT(ptp);
697 ptp.Code=PTP_OC_FormatStore;
698 ptp.Param1=storageid;
699 ptp.Param2=PTP_FST_Undefined;
700 ptp.Nparam=2;
Linus Walleij4f40d112006-09-21 07:44:53 +0000701 return ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL);
Linus Walleij13374a42006-09-13 11:55:30 +0000702}
703
704/**
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000705 * ptp_getobjecthandles:
706 * params: PTPParams*
707 * storage - StorageID
708 * objectformatcode - ObjectFormatCode (optional)
709 * associationOH - ObjectHandle of Association for
710 * wich a list of children is desired
711 * (optional)
712 * objecthandles - pointer to structute
713 *
714 * Fills objecthandles with structure returned by device.
715 *
716 * Return values: Some PTP_RC_* code.
717 **/
718uint16_t
719ptp_getobjecthandles (PTPParams* params, uint32_t storage,
720 uint32_t objectformatcode, uint32_t associationOH,
721 PTPObjectHandles* objecthandles)
722{
723 uint16_t ret;
724 PTPContainer ptp;
Linus Walleijb02a0662006-04-25 08:05:09 +0000725 unsigned char* oh=NULL;
726 unsigned int len;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000727
728 PTP_CNT_INIT(ptp);
729 ptp.Code=PTP_OC_GetObjectHandles;
730 ptp.Param1=storage;
731 ptp.Param2=objectformatcode;
732 ptp.Param3=associationOH;
733 ptp.Nparam=3;
Linus Walleijb02a0662006-04-25 08:05:09 +0000734 len=0;
735 ret=ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &oh, &len);
736 if (ret == PTP_RC_OK) ptp_unpack_OH(params, oh, objecthandles, len);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000737 free(oh);
738 return ret;
739}
740
Linus Walleijb02a0662006-04-25 08:05:09 +0000741/**
742 * ptp_getnumobjects:
743 * params: PTPParams*
744 * storage - StorageID
745 * objectformatcode - ObjectFormatCode (optional)
746 * associationOH - ObjectHandle of Association for
747 * wich a list of children is desired
748 * (optional)
749 * numobs - pointer to uint32_t that takes number of objects
750 *
751 * Fills numobs with number of objects on device.
752 *
753 * Return values: Some PTP_RC_* code.
754 **/
755uint16_t
756ptp_getnumobjects (PTPParams* params, uint32_t storage,
757 uint32_t objectformatcode, uint32_t associationOH,
758 uint32_t* numobs)
759{
760 uint16_t ret;
761 PTPContainer ptp;
762 int len;
763
764 PTP_CNT_INIT(ptp);
765 ptp.Code=PTP_OC_GetObjectHandles;
766 ptp.Param1=storage;
767 ptp.Param2=objectformatcode;
768 ptp.Param3=associationOH;
769 ptp.Nparam=3;
770 len=0;
771 ret=ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL);
772 if (ret == PTP_RC_OK) {
773 if (ptp.Nparam >= 1)
774 *numobs = ptp.Param1;
775 else
776 ret = PTP_RC_GeneralError;
777 }
778 return ret;
779}
780
781/**
782 * ptp_getobjectinfo:
783 * params: PTPParams*
784 * handle - Object handle
785 * objectinfo - pointer to objectinfo that is returned
786 *
787 * Get objectinfo structure for handle from device.
788 *
789 * Return values: Some PTP_RC_* code.
790 **/
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000791uint16_t
792ptp_getobjectinfo (PTPParams* params, uint32_t handle,
793 PTPObjectInfo* objectinfo)
794{
795 uint16_t ret;
796 PTPContainer ptp;
Linus Walleijb02a0662006-04-25 08:05:09 +0000797 unsigned char* oi=NULL;
798 unsigned int len;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000799
800 PTP_CNT_INIT(ptp);
801 ptp.Code=PTP_OC_GetObjectInfo;
802 ptp.Param1=handle;
803 ptp.Nparam=1;
Linus Walleijb02a0662006-04-25 08:05:09 +0000804 len=0;
805 ret=ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &oi, &len);
806 if (ret == PTP_RC_OK) ptp_unpack_OI(params, oi, objectinfo, len);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000807 free(oi);
808 return ret;
809}
810
Linus Walleijb02a0662006-04-25 08:05:09 +0000811/**
812 * ptp_getobject:
813 * params: PTPParams*
814 * handle - Object handle
815 * object - pointer to data area
816 *
817 * Get object 'handle' from device and store the data in newly
818 * allocated 'object'.
819 *
820 * Return values: Some PTP_RC_* code.
821 **/
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000822uint16_t
Linus Walleijb02a0662006-04-25 08:05:09 +0000823ptp_getobject (PTPParams* params, uint32_t handle, unsigned char** object)
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000824{
825 PTPContainer ptp;
Linus Walleijb02a0662006-04-25 08:05:09 +0000826 unsigned int len;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000827
828 PTP_CNT_INIT(ptp);
829 ptp.Code=PTP_OC_GetObject;
830 ptp.Param1=handle;
831 ptp.Nparam=1;
Linus Walleijb02a0662006-04-25 08:05:09 +0000832 len=0;
833 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, object, &len);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000834}
835
Linus Walleijb02a0662006-04-25 08:05:09 +0000836/**
Linus Walleij96c62432006-08-21 10:04:02 +0000837 * ptp_getobject_tofd:
838 * params: PTPParams*
839 * handle - Object handle
840 * fd - File descriptor to write() to
841 *
842 * Get object 'handle' from device and write the data to the
843 * given file descriptor.
844 *
845 * Return values: Some PTP_RC_* code.
846 **/
847uint16_t
848ptp_getobject_tofd (PTPParams* params, uint32_t handle, int fd)
849{
850 PTPContainer ptp;
851 unsigned int len;
852
853 PTP_CNT_INIT(ptp);
854 ptp.Code=PTP_OC_GetObject;
855 ptp.Param1=handle;
856 ptp.Nparam=1;
857 len=0;
Linus Walleije7f44be2006-08-25 19:32:29 +0000858 return ptp_transaction_fd(params, &ptp, PTP_DP_GETDATA, 0, fd, &len);
Linus Walleij96c62432006-08-21 10:04:02 +0000859}
860
861/**
Linus Walleijb02a0662006-04-25 08:05:09 +0000862 * ptp_getpartialobject:
863 * params: PTPParams*
864 * handle - Object handle
865 * offset - Offset into object
866 * maxbytes - Maximum of bytes to read
867 * object - pointer to data area
868 *
869 * Get object 'handle' from device and store the data in newly
870 * allocated 'object'. Start from offset and read at most maxbytes.
871 *
872 * Return values: Some PTP_RC_* code.
873 **/
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000874uint16_t
Linus Walleijb02a0662006-04-25 08:05:09 +0000875ptp_getpartialobject (PTPParams* params, uint32_t handle, uint32_t offset,
876 uint32_t maxbytes, unsigned char** object)
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000877{
878 PTPContainer ptp;
Linus Walleijb02a0662006-04-25 08:05:09 +0000879 unsigned int len;
880
881 PTP_CNT_INIT(ptp);
882 ptp.Code=PTP_OC_GetPartialObject;
883 ptp.Param1=handle;
884 ptp.Param2=offset;
885 ptp.Param3=maxbytes;
886 ptp.Nparam=3;
887 len=0;
888 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, object, &len);
889}
890
891/**
892 * ptp_getthumb:
893 * params: PTPParams*
894 * handle - Object handle
895 * object - pointer to data area
896 *
897 * Get thumb for object 'handle' from device and store the data in newly
898 * allocated 'object'.
899 *
900 * Return values: Some PTP_RC_* code.
901 **/
902uint16_t
903ptp_getthumb (PTPParams* params, uint32_t handle, unsigned char** object)
904{
905 PTPContainer ptp;
906 unsigned int len;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000907
908 PTP_CNT_INIT(ptp);
909 ptp.Code=PTP_OC_GetThumb;
910 ptp.Param1=handle;
911 ptp.Nparam=1;
Linus Walleijb02a0662006-04-25 08:05:09 +0000912 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, object, &len);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000913}
914
915/**
916 * ptp_deleteobject:
917 * params: PTPParams*
918 * handle - object handle
919 * ofc - object format code (optional)
920 *
921 * Deletes desired objects.
922 *
923 * Return values: Some PTP_RC_* code.
924 **/
925uint16_t
Linus Walleijb02a0662006-04-25 08:05:09 +0000926ptp_deleteobject (PTPParams* params, uint32_t handle, uint32_t ofc)
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000927{
928 PTPContainer ptp;
929
930 PTP_CNT_INIT(ptp);
931 ptp.Code=PTP_OC_DeleteObject;
932 ptp.Param1=handle;
933 ptp.Param2=ofc;
934 ptp.Nparam=2;
Linus Walleijb02a0662006-04-25 08:05:09 +0000935 return ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000936}
937
938/**
939 * ptp_sendobjectinfo:
940 * params: PTPParams*
941 * uint32_t* store - destination StorageID on Responder
942 * uint32_t* parenthandle - Parent ObjectHandle on responder
943 * uint32_t* handle - see Return values
944 * PTPObjectInfo* objectinfo- ObjectInfo that is to be sent
945 *
946 * Sends ObjectInfo of file that is to be sent via SendFileObject.
947 *
948 * Return values: Some PTP_RC_* code.
949 * Upon success : uint32_t* store - Responder StorageID in which
950 * object will be stored
951 * uint32_t* parenthandle- Responder Parent ObjectHandle
952 * in which the object will be stored
953 * uint32_t* handle - Responder's reserved ObjectHandle
954 * for the incoming object
955 **/
956uint16_t
957ptp_sendobjectinfo (PTPParams* params, uint32_t* store,
958 uint32_t* parenthandle, uint32_t* handle,
959 PTPObjectInfo* objectinfo)
960{
961 uint16_t ret;
962 PTPContainer ptp;
Linus Walleijb02a0662006-04-25 08:05:09 +0000963 unsigned char* oidata=NULL;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000964 uint32_t size;
965
966 PTP_CNT_INIT(ptp);
967 ptp.Code=PTP_OC_SendObjectInfo;
968 ptp.Param1=*store;
969 ptp.Param2=*parenthandle;
970 ptp.Nparam=2;
971
972 size=ptp_pack_OI(params, objectinfo, &oidata);
Linus Walleijb02a0662006-04-25 08:05:09 +0000973 ret = ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, &oidata, NULL);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000974 free(oidata);
975 *store=ptp.Param1;
976 *parenthandle=ptp.Param2;
977 *handle=ptp.Param3;
978 return ret;
979}
980
981/**
982 * ptp_sendobject:
983 * params: PTPParams*
984 * char* object - contains the object that is to be sent
985 * uint32_t size - object size
986 *
987 * Sends object to Responder.
988 *
989 * Return values: Some PTP_RC_* code.
990 *
991 */
992uint16_t
Linus Walleijb02a0662006-04-25 08:05:09 +0000993ptp_sendobject (PTPParams* params, unsigned char* object, uint32_t size)
Linus Walleijeb8c6fe2006-02-03 09:46:22 +0000994{
995 PTPContainer ptp;
996
997 PTP_CNT_INIT(ptp);
998 ptp.Code=PTP_OC_SendObject;
999 ptp.Nparam=0;
1000
Linus Walleijb02a0662006-04-25 08:05:09 +00001001 return ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, &object, NULL);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001002}
1003
Linus Walleije7f44be2006-08-25 19:32:29 +00001004/**
1005 * ptp_sendobject_fromfd:
1006 * params: PTPParams*
1007 * fd - File descriptor to read() object from
1008 * uint32_t size - File/object size
1009 *
1010 * Sends object from file descriptor by consecutive reads from this
1011 * descriptor.
1012 *
1013 * Return values: Some PTP_RC_* code.
1014 **/
1015uint16_t
1016ptp_sendobject_fromfd (PTPParams* params, int fd, uint32_t size)
1017{
1018 PTPContainer ptp;
1019
1020 PTP_CNT_INIT(ptp);
1021 ptp.Code=PTP_OC_SendObject;
1022 ptp.Nparam=0;
1023
1024 return ptp_transaction_fd(params, &ptp, PTP_DP_SENDDATA, size, fd, NULL);
1025}
1026
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001027
1028/**
1029 * ptp_initiatecapture:
1030 * params: PTPParams*
1031 * storageid - destination StorageID on Responder
1032 * ofc - object format code
1033 *
1034 * Causes device to initiate the capture of one or more new data objects
1035 * according to its current device properties, storing the data into store
1036 * indicated by storageid. If storageid is 0x00000000, the object(s) will
1037 * be stored in a store that is determined by the capturing device.
1038 * The capturing of new data objects is an asynchronous operation.
1039 *
1040 * Return values: Some PTP_RC_* code.
1041 **/
1042
1043uint16_t
1044ptp_initiatecapture (PTPParams* params, uint32_t storageid,
1045 uint32_t ofc)
1046{
1047 PTPContainer ptp;
1048
1049 PTP_CNT_INIT(ptp);
1050 ptp.Code=PTP_OC_InitiateCapture;
1051 ptp.Param1=storageid;
1052 ptp.Param2=ofc;
1053 ptp.Nparam=2;
Linus Walleijb02a0662006-04-25 08:05:09 +00001054 return ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001055}
1056
1057uint16_t
1058ptp_getdevicepropdesc (PTPParams* params, uint16_t propcode,
1059 PTPDevicePropDesc* devicepropertydesc)
1060{
1061 PTPContainer ptp;
1062 uint16_t ret;
Linus Walleijb02a0662006-04-25 08:05:09 +00001063 unsigned int len;
1064 unsigned char* dpd=NULL;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001065
1066 PTP_CNT_INIT(ptp);
1067 ptp.Code=PTP_OC_GetDevicePropDesc;
1068 ptp.Param1=propcode;
1069 ptp.Nparam=1;
Linus Walleijb02a0662006-04-25 08:05:09 +00001070 len=0;
1071 ret=ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &dpd, &len);
1072 if (ret == PTP_RC_OK) ptp_unpack_DPD(params, dpd, devicepropertydesc, len);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001073 free(dpd);
1074 return ret;
1075}
1076
Linus Walleijb02a0662006-04-25 08:05:09 +00001077
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001078uint16_t
1079ptp_getdevicepropvalue (PTPParams* params, uint16_t propcode,
Linus Walleijb02a0662006-04-25 08:05:09 +00001080 PTPPropertyValue* value, uint16_t datatype)
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001081{
1082 PTPContainer ptp;
1083 uint16_t ret;
Linus Walleijb02a0662006-04-25 08:05:09 +00001084 unsigned int len;
1085 int offset;
1086 unsigned char* dpv=NULL;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001087
1088
1089 PTP_CNT_INIT(ptp);
1090 ptp.Code=PTP_OC_GetDevicePropValue;
1091 ptp.Param1=propcode;
1092 ptp.Nparam=1;
Linus Walleijb02a0662006-04-25 08:05:09 +00001093 len=offset=0;
1094 ret=ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &dpv, &len);
1095 if (ret == PTP_RC_OK) ptp_unpack_DPV(params, dpv, &offset, len, value, datatype);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001096 free(dpv);
1097 return ret;
1098}
1099
1100uint16_t
1101ptp_setdevicepropvalue (PTPParams* params, uint16_t propcode,
Linus Walleijb02a0662006-04-25 08:05:09 +00001102 PTPPropertyValue *value, uint16_t datatype)
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001103{
1104 PTPContainer ptp;
1105 uint16_t ret;
1106 uint32_t size;
Linus Walleijb02a0662006-04-25 08:05:09 +00001107 unsigned char* dpv=NULL;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001108
1109 PTP_CNT_INIT(ptp);
1110 ptp.Code=PTP_OC_SetDevicePropValue;
1111 ptp.Param1=propcode;
1112 ptp.Nparam=1;
1113 size=ptp_pack_DPV(params, value, &dpv, datatype);
Linus Walleijb02a0662006-04-25 08:05:09 +00001114 ret=ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, &dpv, NULL);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001115 free(dpv);
1116 return ret;
1117}
1118
1119/**
1120 * ptp_ek_sendfileobjectinfo:
1121 * params: PTPParams*
1122 * uint32_t* store - destination StorageID on Responder
1123 * uint32_t* parenthandle - Parent ObjectHandle on responder
1124 * uint32_t* handle - see Return values
1125 * PTPObjectInfo* objectinfo- ObjectInfo that is to be sent
1126 *
1127 * Sends ObjectInfo of file that is to be sent via SendFileObject.
1128 *
1129 * Return values: Some PTP_RC_* code.
1130 * Upon success : uint32_t* store - Responder StorageID in which
1131 * object will be stored
1132 * uint32_t* parenthandle- Responder Parent ObjectHandle
1133 * in which the object will be stored
1134 * uint32_t* handle - Responder's reserved ObjectHandle
1135 * for the incoming object
1136 **/
1137uint16_t
1138ptp_ek_sendfileobjectinfo (PTPParams* params, uint32_t* store,
1139 uint32_t* parenthandle, uint32_t* handle,
1140 PTPObjectInfo* objectinfo)
1141{
1142 uint16_t ret;
1143 PTPContainer ptp;
Linus Walleijb02a0662006-04-25 08:05:09 +00001144 unsigned char* oidata=NULL;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001145 uint32_t size;
1146
1147 PTP_CNT_INIT(ptp);
1148 ptp.Code=PTP_OC_EK_SendFileObjectInfo;
1149 ptp.Param1=*store;
1150 ptp.Param2=*parenthandle;
1151 ptp.Nparam=2;
1152
1153 size=ptp_pack_OI(params, objectinfo, &oidata);
Linus Walleijb02a0662006-04-25 08:05:09 +00001154 ret=ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, &oidata, NULL);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001155 free(oidata);
1156 *store=ptp.Param1;
1157 *parenthandle=ptp.Param2;
1158 *handle=ptp.Param3;
1159 return ret;
1160}
1161
1162/**
Linus Walleijb02a0662006-04-25 08:05:09 +00001163 * ptp_ek_getserial:
1164 * params: PTPParams*
1165 * char** serial - contains the serial number of the camera
1166 * uint32_t* size - contains the string length
1167 *
1168 * Gets the serial number from the device. (ptp serial)
1169 *
1170 * Return values: Some PTP_RC_* code.
1171 *
1172 */
1173uint16_t
1174ptp_ek_getserial (PTPParams* params, unsigned char **data, unsigned int *size)
1175{
1176 PTPContainer ptp;
1177
1178 PTP_CNT_INIT(ptp);
1179 ptp.Code = PTP_OC_EK_GetSerial;
1180 ptp.Nparam = 0;
1181 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, data, size);
1182}
1183
1184/**
1185 * ptp_ek_setserial:
1186 * params: PTPParams*
1187 * char* serial - contains the new serial number
1188 * uint32_t size - string length
1189 *
1190 * Sets the serial number of the device. (ptp serial)
1191 *
1192 * Return values: Some PTP_RC_* code.
1193 *
1194 */
1195uint16_t
1196ptp_ek_setserial (PTPParams* params, unsigned char *data, unsigned int size)
1197{
1198 PTPContainer ptp;
1199
1200 PTP_CNT_INIT(ptp);
1201 ptp.Code = PTP_OC_EK_SetSerial;
1202 ptp.Nparam = 0;
1203 return ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, &data, NULL);
1204}
1205
1206/* unclear what it does yet */
1207uint16_t
1208ptp_ek_9007 (PTPParams* params, unsigned char **data, unsigned int *size)
1209{
1210 PTPContainer ptp;
1211
1212 PTP_CNT_INIT(ptp);
1213 ptp.Code = 0x9007;
1214 ptp.Nparam = 0;
1215 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, data, size);
1216}
1217
1218/* unclear what it does yet */
1219uint16_t
1220ptp_ek_9009 (PTPParams* params, uint32_t *p1, uint32_t *p2)
1221{
1222 PTPContainer ptp;
1223 uint16_t ret;
1224
1225 PTP_CNT_INIT(ptp);
1226 ptp.Code = 0x9009;
1227 ptp.Nparam = 0;
1228 ret = ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL);
1229 *p1 = ptp.Param1;
1230 *p2 = ptp.Param2;
1231 return ret;
1232}
1233
1234/* unclear yet, but I guess it returns the info from 9008 */
1235uint16_t
1236ptp_ek_900c (PTPParams* params, unsigned char **data, unsigned int *size)
1237{
1238 PTPContainer ptp;
1239
1240 PTP_CNT_INIT(ptp);
1241 ptp.Code = 0x900c;
1242 ptp.Nparam = 0;
1243 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, data, size);
1244 /* returned data is 16bit,16bit,32bit,32bit */
1245}
1246
1247/**
1248 * ptp_ek_settext:
1249 * params: PTPParams*
1250 * PTPEKTextParams* - contains the texts to display.
1251 *
1252 * Displays the specified texts on the TFT of the camera.
1253 *
1254 * Return values: Some PTP_RC_* code.
1255 *
1256 */
1257uint16_t
1258ptp_ek_settext (PTPParams* params, PTPEKTextParams *text)
1259{
1260 PTPContainer ptp;
1261 uint16_t ret;
1262 unsigned int size;
1263 unsigned char *data;
1264
1265 PTP_CNT_INIT(ptp);
1266 ptp.Code = PTP_OC_EK_SetText;
1267 ptp.Nparam = 0;
1268 if (0 == (size = ptp_pack_EK_text(params, text, &data)))
1269 return PTP_ERROR_BADPARAM;
1270 ret = ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, &data, NULL);
1271 free(data);
1272 return ret;
1273}
1274
1275/**
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001276 * ptp_ek_sendfileobject:
1277 * params: PTPParams*
1278 * char* object - contains the object that is to be sent
1279 * uint32_t size - object size
1280 *
1281 * Sends object to Responder.
1282 *
1283 * Return values: Some PTP_RC_* code.
1284 *
1285 */
1286uint16_t
Linus Walleijb02a0662006-04-25 08:05:09 +00001287ptp_ek_sendfileobject (PTPParams* params, unsigned char* object, uint32_t size)
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001288{
1289 PTPContainer ptp;
1290
1291 PTP_CNT_INIT(ptp);
1292 ptp.Code=PTP_OC_EK_SendFileObject;
1293 ptp.Nparam=0;
1294
Linus Walleijb02a0662006-04-25 08:05:09 +00001295 return ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, &object, NULL);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001296}
1297
1298/*************************************************************************
1299 *
1300 * Canon PTP extensions support
1301 *
1302 * (C) Nikolai Kopanygin 2003
1303 *
1304 *************************************************************************/
1305
1306
1307/**
1308 * ptp_canon_getobjectsize:
1309 * params: PTPParams*
1310 * uint32_t handle - ObjectHandle
1311 * uint32_t p2 - Yet unknown parameter,
1312 * value 0 works.
1313 *
1314 * Gets form the responder the size of the specified object.
1315 *
1316 * Return values: Some PTP_RC_* code.
1317 * Upon success : uint32_t* size - The object size
1318 * uint32_t rp2 - Yet unknown parameter
1319 *
1320 **/
1321uint16_t
1322ptp_canon_getobjectsize (PTPParams* params, uint32_t handle, uint32_t p2,
1323 uint32_t* size, uint32_t* rp2)
1324{
1325 uint16_t ret;
1326 PTPContainer ptp;
1327
1328 PTP_CNT_INIT(ptp);
1329 ptp.Code=PTP_OC_CANON_GetObjectSize;
1330 ptp.Param1=handle;
1331 ptp.Param2=p2;
1332 ptp.Nparam=2;
Linus Walleijb02a0662006-04-25 08:05:09 +00001333 ret=ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001334 *size=ptp.Param1;
1335 *rp2=ptp.Param2;
1336 return ret;
1337}
1338
1339/**
1340 * ptp_canon_startshootingmode:
1341 * params: PTPParams*
1342 *
1343 * Starts shooting session. It emits a StorageInfoChanged
1344 * event via the interrupt pipe and pushes the StorageInfoChanged
1345 * and CANON_CameraModeChange events onto the event stack
1346 * (see operation PTP_OC_CANON_CheckEvent).
1347 *
1348 * Return values: Some PTP_RC_* code.
1349 *
1350 **/
1351uint16_t
1352ptp_canon_startshootingmode (PTPParams* params)
1353{
1354 PTPContainer ptp;
1355
1356 PTP_CNT_INIT(ptp);
1357 ptp.Code=PTP_OC_CANON_StartShootingMode;
1358 ptp.Nparam=0;
Linus Walleijb02a0662006-04-25 08:05:09 +00001359 return ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001360}
1361
1362/**
1363 * ptp_canon_endshootingmode:
1364 * params: PTPParams*
1365 *
1366 * This operation is observed after pressing the Disconnect
1367 * button on the Remote Capture app. It emits a StorageInfoChanged
1368 * event via the interrupt pipe and pushes the StorageInfoChanged
1369 * and CANON_CameraModeChange events onto the event stack
1370 * (see operation PTP_OC_CANON_CheckEvent).
1371 *
1372 * Return values: Some PTP_RC_* code.
1373 *
1374 **/
1375uint16_t
1376ptp_canon_endshootingmode (PTPParams* params)
1377{
1378 PTPContainer ptp;
1379
1380 PTP_CNT_INIT(ptp);
1381 ptp.Code=PTP_OC_CANON_EndShootingMode;
1382 ptp.Nparam=0;
Linus Walleijb02a0662006-04-25 08:05:09 +00001383 return ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001384}
1385
1386/**
1387 * ptp_canon_viewfinderon:
1388 * params: PTPParams*
1389 *
1390 * Prior to start reading viewfinder images, one must call this operation.
1391 * Supposedly, this operation affects the value of the CANON_ViewfinderMode
1392 * property.
1393 *
1394 * Return values: Some PTP_RC_* code.
1395 *
1396 **/
1397uint16_t
1398ptp_canon_viewfinderon (PTPParams* params)
1399{
1400 PTPContainer ptp;
1401
1402 PTP_CNT_INIT(ptp);
1403 ptp.Code=PTP_OC_CANON_ViewfinderOn;
1404 ptp.Nparam=0;
Linus Walleijb02a0662006-04-25 08:05:09 +00001405 return ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001406}
1407
1408/**
1409 * ptp_canon_viewfinderoff:
1410 * params: PTPParams*
1411 *
1412 * Before changing the shooting mode, or when one doesn't need to read
1413 * viewfinder images any more, one must call this operation.
1414 * Supposedly, this operation affects the value of the CANON_ViewfinderMode
1415 * property.
1416 *
1417 * Return values: Some PTP_RC_* code.
1418 *
1419 **/
1420uint16_t
1421ptp_canon_viewfinderoff (PTPParams* params)
1422{
1423 PTPContainer ptp;
1424
1425 PTP_CNT_INIT(ptp);
1426 ptp.Code=PTP_OC_CANON_ViewfinderOff;
1427 ptp.Nparam=0;
Linus Walleijb02a0662006-04-25 08:05:09 +00001428 return ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001429}
1430
1431/**
1432 * ptp_canon_reflectchanges:
1433 * params: PTPParams*
1434 * uint32_t p1 - Yet unknown parameter,
1435 * value 7 works
1436 *
1437 * Make viewfinder reflect changes.
1438 * There is a button for this operation in the Remote Capture app.
1439 * What it does exactly I don't know. This operation is followed
1440 * by the CANON_GetChanges(?) operation in the log.
1441 *
1442 * Return values: Some PTP_RC_* code.
1443 *
1444 **/
1445uint16_t
1446ptp_canon_reflectchanges (PTPParams* params, uint32_t p1)
1447{
1448 PTPContainer ptp;
1449
1450 PTP_CNT_INIT(ptp);
1451 ptp.Code=PTP_OC_CANON_ReflectChanges;
1452 ptp.Param1=p1;
1453 ptp.Nparam=1;
Linus Walleijb02a0662006-04-25 08:05:09 +00001454 return ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001455}
1456
1457
1458/**
1459 * ptp_canon_checkevent:
1460 * params: PTPParams*
1461 *
1462 * The camera has a FIFO stack, in which it accumulates events.
1463 * Partially these events are communicated also via the USB interrupt pipe
1464 * according to the PTP USB specification, partially not.
1465 * This operation returns from the device a block of data, empty,
1466 * if the event stack is empty, or filled with an event's data otherwise.
1467 * The event is removed from the stack in the latter case.
1468 * The Remote Capture app sends this command to the camera all the time
1469 * of connection, filling with it the gaps between other operations.
1470 *
1471 * Return values: Some PTP_RC_* code.
1472 * Upon success : PTPUSBEventContainer* event - is filled with the event data
1473 * if any
1474 * int *isevent - returns 1 in case of event
1475 * or 0 otherwise
1476 **/
1477uint16_t
1478ptp_canon_checkevent (PTPParams* params, PTPUSBEventContainer* event, int* isevent)
1479{
1480 uint16_t ret;
1481 PTPContainer ptp;
Linus Walleijb02a0662006-04-25 08:05:09 +00001482 unsigned char *evdata = NULL;
1483 unsigned int len;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001484
1485 *isevent=0;
1486 PTP_CNT_INIT(ptp);
1487 ptp.Code=PTP_OC_CANON_CheckEvent;
1488 ptp.Nparam=0;
Linus Walleijb02a0662006-04-25 08:05:09 +00001489 len=0;
1490 ret=ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &evdata, &len);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001491 if (evdata!=NULL) {
1492 if (ret == PTP_RC_OK) {
Linus Walleijb02a0662006-04-25 08:05:09 +00001493 ptp_unpack_EC(params, evdata, event, len);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001494 *isevent=1;
1495 }
1496 free(evdata);
1497 }
1498 return ret;
1499}
1500
1501
1502/**
1503 * ptp_canon_focuslock:
1504 *
1505 * This operation locks the focus. It is followed by the CANON_GetChanges(?)
1506 * operation in the log.
1507 * It affects the CANON_MacroMode property.
1508 *
1509 * params: PTPParams*
1510 *
1511 * Return values: Some PTP_RC_* code.
1512 *
1513 **/
1514uint16_t
1515ptp_canon_focuslock (PTPParams* params)
1516{
1517 PTPContainer ptp;
1518
1519 PTP_CNT_INIT(ptp);
1520 ptp.Code=PTP_OC_CANON_FocusLock;
1521 ptp.Nparam=0;
Linus Walleijb02a0662006-04-25 08:05:09 +00001522 return ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001523}
1524
1525/**
1526 * ptp_canon_focusunlock:
1527 *
1528 * This operation unlocks the focus. It is followed by the CANON_GetChanges(?)
1529 * operation in the log.
1530 * It sets the CANON_MacroMode property value to 1 (where it occurs in the log).
1531 *
1532 * params: PTPParams*
1533 *
1534 * Return values: Some PTP_RC_* code.
1535 *
1536 **/
1537uint16_t
1538ptp_canon_focusunlock (PTPParams* params)
1539{
1540 PTPContainer ptp;
1541
1542 PTP_CNT_INIT(ptp);
1543 ptp.Code=PTP_OC_CANON_FocusUnlock;
1544 ptp.Nparam=0;
Linus Walleijb02a0662006-04-25 08:05:09 +00001545 return ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001546}
1547
1548/**
1549 * ptp_canon_initiatecaptureinmemory:
1550 *
1551 * This operation starts the image capture according to the current camera
1552 * settings. When the capture has happened, the camera emits a CaptureComplete
1553 * event via the interrupt pipe and pushes the CANON_RequestObjectTransfer,
1554 * CANON_DeviceInfoChanged and CaptureComplete events onto the event stack
1555 * (see operation CANON_CheckEvent). From the CANON_RequestObjectTransfer
1556 * event's parameter one can learn the just captured image's ObjectHandle.
1557 * The image is stored in the camera's own RAM.
1558 * On the next capture the image will be overwritten!
1559 *
1560 * params: PTPParams*
1561 *
1562 * Return values: Some PTP_RC_* code.
1563 *
1564 **/
1565uint16_t
1566ptp_canon_initiatecaptureinmemory (PTPParams* params)
1567{
1568 PTPContainer ptp;
1569
1570 PTP_CNT_INIT(ptp);
1571 ptp.Code=PTP_OC_CANON_InitiateCaptureInMemory;
1572 ptp.Nparam=0;
Linus Walleijb02a0662006-04-25 08:05:09 +00001573 return ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL);
1574}
1575
1576uint16_t
1577ptp_canon_9012 (PTPParams* params)
1578{
1579 PTPContainer ptp;
1580
1581 PTP_CNT_INIT(ptp);
1582 ptp.Code=0x9012;
1583 ptp.Nparam=0;
1584 return ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001585}
1586
1587/**
1588 * ptp_canon_getpartialobject:
1589 *
1590 * This operation is used to read from the device a data
1591 * block of an object from a specified offset.
1592 *
1593 * params: PTPParams*
1594 * uint32_t handle - the handle of the requested object
1595 * uint32_t offset - the offset in bytes from the beginning of the object
1596 * uint32_t size - the requested size of data block to read
1597 * uint32_t pos - 1 for the first block, 2 - for a block in the middle,
1598 * 3 - for the last block
1599 *
1600 * Return values: Some PTP_RC_* code.
1601 * char **block - the pointer to the block of data read
1602 * uint32_t* readnum - the number of bytes read
1603 *
1604 **/
1605uint16_t
1606ptp_canon_getpartialobject (PTPParams* params, uint32_t handle,
1607 uint32_t offset, uint32_t size,
Linus Walleijb02a0662006-04-25 08:05:09 +00001608 uint32_t pos, unsigned char** block,
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001609 uint32_t* readnum)
1610{
1611 uint16_t ret;
1612 PTPContainer ptp;
Linus Walleijb02a0662006-04-25 08:05:09 +00001613 unsigned char *data=NULL;
1614 unsigned int len;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001615
1616 PTP_CNT_INIT(ptp);
1617 ptp.Code=PTP_OC_CANON_GetPartialObject;
1618 ptp.Param1=handle;
1619 ptp.Param2=offset;
1620 ptp.Param3=size;
1621 ptp.Param4=pos;
1622 ptp.Nparam=4;
Linus Walleijb02a0662006-04-25 08:05:09 +00001623 len=0;
1624 ret=ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &len);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001625 if (ret==PTP_RC_OK) {
1626 *block=data;
1627 *readnum=ptp.Param1;
1628 }
1629 return ret;
1630}
1631
1632/**
1633 * ptp_canon_getviewfinderimage:
1634 *
1635 * This operation can be used to read the image which is currently
1636 * in the camera's viewfinder. The image size is 320x240, format is JPEG.
1637 * Of course, prior to calling this operation, one must turn the viewfinder
1638 * on with the CANON_ViewfinderOn command.
1639 * Invoking this operation many times, one can get live video from the camera!
1640 *
1641 * params: PTPParams*
1642 *
1643 * Return values: Some PTP_RC_* code.
1644 * char **image - the pointer to the read image
1645 * unit32_t *size - the size of the image in bytes
1646 *
1647 **/
1648uint16_t
Linus Walleijb02a0662006-04-25 08:05:09 +00001649ptp_canon_getviewfinderimage (PTPParams* params, unsigned char** image, uint32_t* size)
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001650{
1651 uint16_t ret;
1652 PTPContainer ptp;
Linus Walleijb02a0662006-04-25 08:05:09 +00001653 unsigned int len;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001654
1655 PTP_CNT_INIT(ptp);
1656 ptp.Code=PTP_OC_CANON_GetViewfinderImage;
1657 ptp.Nparam=0;
Linus Walleijb02a0662006-04-25 08:05:09 +00001658 ret=ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, image, &len);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001659 if (ret==PTP_RC_OK) *size=ptp.Param1;
1660 return ret;
1661}
1662
1663/**
1664 * ptp_canon_getchanges:
1665 *
1666 * This is an interesting operation, about the effect of which I am not sure.
1667 * This command is called every time when a device property has been changed
1668 * with the SetDevicePropValue operation, and after some other operations.
1669 * This operation reads the array of Device Properties which have been changed
1670 * by the previous operation.
1671 * Probably, this operation is even required to make those changes work.
1672 *
1673 * params: PTPParams*
1674 *
1675 * Return values: Some PTP_RC_* code.
1676 * uint16_t** props - the pointer to the array of changed properties
1677 * uint32_t* propnum - the number of elements in the *props array
1678 *
1679 **/
1680uint16_t
1681ptp_canon_getchanges (PTPParams* params, uint16_t** props, uint32_t* propnum)
1682{
1683 uint16_t ret;
1684 PTPContainer ptp;
Linus Walleijb02a0662006-04-25 08:05:09 +00001685 unsigned char* data=NULL;
1686 unsigned int len;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001687
1688 PTP_CNT_INIT(ptp);
1689 ptp.Code=PTP_OC_CANON_GetChanges;
1690 ptp.Nparam=0;
Linus Walleijb02a0662006-04-25 08:05:09 +00001691 len=0;
1692 ret=ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &len);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001693 if (ret == PTP_RC_OK)
1694 *propnum=ptp_unpack_uint16_t_array(params,data,0,props);
1695 free(data);
1696 return ret;
1697}
1698
1699/**
1700 * ptp_canon_getfolderentries:
1701 *
1702 * This command reads a specified object's record in a device's filesystem,
1703 * or the records of all objects belonging to a specified folder (association).
1704 *
1705 * params: PTPParams*
1706 * uint32_t store - StorageID,
1707 * uint32_t p2 - Yet unknown (0 value works OK)
1708 * uint32_t parent - Parent Object Handle
1709 * # If Parent Object Handle is 0xffffffff,
1710 * # the Parent Object is the top level folder.
1711 * uint32_t handle - Object Handle
1712 * # If Object Handle is 0, the records of all objects
1713 * # belonging to the Parent Object are read.
1714 * # If Object Handle is not 0, only the record of this
1715 * # Object is read.
1716 *
1717 * Return values: Some PTP_RC_* code.
1718 * PTPCANONFolderEntry** entries - the pointer to the folder entry array
1719 * uint32_t* entnum - the number of elements of the array
1720 *
1721 **/
1722uint16_t
1723ptp_canon_getfolderentries (PTPParams* params, uint32_t store, uint32_t p2,
1724 uint32_t parent, uint32_t handle,
1725 PTPCANONFolderEntry** entries, uint32_t* entnum)
1726{
1727 uint16_t ret;
1728 PTPContainer ptp;
Linus Walleijb02a0662006-04-25 08:05:09 +00001729 unsigned char *data = NULL;
1730 unsigned int len;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001731
1732 PTP_CNT_INIT(ptp);
1733 ptp.Code=PTP_OC_CANON_GetFolderEntries;
1734 ptp.Param1=store;
1735 ptp.Param2=p2;
1736 ptp.Param3=parent;
1737 ptp.Param4=handle;
1738 ptp.Nparam=4;
Linus Walleijb02a0662006-04-25 08:05:09 +00001739 len=0;
1740 ret=ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &len);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00001741 if (ret == PTP_RC_OK) {
1742 int i;
1743 *entnum=ptp.Param1;
1744 *entries=calloc(*entnum, sizeof(PTPCANONFolderEntry));
1745 if (*entries!=NULL) {
1746 for(i=0; i<(*entnum); i++)
1747 ptp_unpack_Canon_FE(params,
1748 data+i*PTP_CANON_FolderEntryLen,
1749 &((*entries)[i]) );
1750 } else {
1751 ret=PTP_ERROR_IO; /* Cannot allocate memory */
1752 }
1753 }
1754 free(data);
1755 return ret;
1756}
1757
Linus Walleijb02a0662006-04-25 08:05:09 +00001758/**
Linus Walleij0468fe72006-09-13 11:49:52 +00001759 * ptp_canon_lookup_object:
1760 *
1761 * This command looks up the specified object on the camera.
1762 *
1763 * Format is "A:\\PATH".
1764 *
1765 * The 'A' is the VolumeLabel from GetStorageInfo,
1766 * my IXUS has "A" for the card and "V" for internal memory.
1767 *
1768 * params: PTPParams*
1769 * char* name - path name
1770 *
1771 * Return values: Some PTP_RC_* code.
1772 * uint32_t *oid - PTP object id.
1773 *
1774 **/
1775uint16_t
1776ptp_canon_lookup_object (PTPParams* params, char* name, uint32_t* objectid)
1777{
1778 uint16_t ret;
1779 PTPContainer ptp;
1780 unsigned char *data = NULL;
1781 uint8_t len;
1782
1783 PTP_CNT_INIT (ptp);
1784 ptp.Code=PTP_OC_CANON_LookupObject;
1785 ptp.Nparam=0;
1786 len=0;
1787 data = malloc (2*(strlen(name)+1)+2);
1788 memset (data, 0, 2*(strlen(name)+1)+2);
1789 ptp_pack_string (params, name, data, 0, &len);
1790 ret=ptp_transaction (params, &ptp, PTP_DP_SENDDATA, (len+1)*2+1, &data, NULL);
1791 free (data);
1792 *objectid = ptp.Param1;
1793 return ret;
1794}
1795
1796/**
Linus Walleijb02a0662006-04-25 08:05:09 +00001797 * ptp_canon_theme_download:
1798 *
1799 * This command downloads the specified theme slot, including jpegs
1800 * and wav files.
1801 *
1802 * params: PTPParams*
1803 * uint32_t themenr - nr of theme
1804 *
1805 * Return values: Some PTP_RC_* code.
1806 * unsigned char **data - pointer to data pointer
1807 * unsigned int *size - size of data returned
1808 *
1809 **/
1810uint16_t
1811ptp_canon_theme_download (PTPParams* params, uint32_t themenr,
1812 unsigned char **data, unsigned int *size)
1813{
1814 PTPContainer ptp;
1815
1816 *data = NULL;
1817 *size = 0;
1818 PTP_CNT_INIT(ptp);
1819 ptp.Code = PTP_OC_CANON_ThemeDownload;
1820 ptp.Param1 = themenr;
1821 ptp.Nparam = 1;
1822 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, data, size);
1823}
1824
1825
Linus Walleijb02a0662006-04-25 08:05:09 +00001826uint16_t
1827ptp_nikon_curve_download (PTPParams* params, unsigned char **data, unsigned int *size) {
1828 PTPContainer ptp;
1829 *data = NULL;
1830 *size = 0;
1831 PTP_CNT_INIT(ptp);
1832 ptp.Code = PTP_OC_NIKON_CurveDownload;
1833 ptp.Nparam = 0;
1834 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, data, size);
1835}
1836
1837uint16_t
1838ptp_nikon_getfileinfoinblock ( PTPParams* params,
1839 uint32_t p1, uint32_t p2, uint32_t p3,
1840 unsigned char **data, unsigned int *size
1841) {
1842 PTPContainer ptp;
1843 *data = NULL;
1844 *size = 0;
1845 PTP_CNT_INIT(ptp);
1846 ptp.Code = PTP_OC_NIKON_GetFileInfoInBlock;
1847 ptp.Nparam = 3;
1848 ptp.Param1 = p1;
1849 ptp.Param2 = p2;
1850 ptp.Param3 = p3;
1851 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, data, size);
1852}
1853
1854/**
1855 * ptp_nikon_setcontrolmode:
1856 *
1857 * This command can switch the camera to full PC control mode.
1858 *
1859 * params: PTPParams*
1860 * uint32_t mode - mode
1861 *
1862 * Return values: Some PTP_RC_* code.
1863 *
1864 **/
1865uint16_t
1866ptp_nikon_setcontrolmode (PTPParams* params, uint32_t mode)
1867{
1868 PTPContainer ptp;
1869
1870 PTP_CNT_INIT(ptp);
1871 ptp.Code=PTP_OC_NIKON_SetControlMode;
1872 ptp.Param1=mode;
1873 ptp.Nparam=1;
1874 return ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL);
1875}
1876
1877/**
1878 * ptp_nikon_capture:
1879 *
1880 * This command captures a picture on the Nikon.
1881 *
1882 * params: PTPParams*
1883 * uint32_t x - unknown parameter. seen to be -1.
1884 *
1885 * Return values: Some PTP_RC_* code.
1886 *
1887 **/
1888uint16_t
1889ptp_nikon_capture (PTPParams* params, uint32_t x)
1890{
1891 PTPContainer ptp;
1892
1893 PTP_CNT_INIT(ptp);
1894 ptp.Code=PTP_OC_NIKON_Capture;
1895 ptp.Param1=x;
1896 ptp.Nparam=1;
1897 return ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL);
1898}
1899
1900/**
1901 * ptp_nikon_check_event:
1902 *
1903 * This command checks the event queue on the Nikon.
1904 *
1905 * params: PTPParams*
1906 * PTPUSBEventContainer **event - list of usb events.
1907 * int *evtcnt - number of usb events in event structure.
1908 *
1909 * Return values: Some PTP_RC_* code.
1910 *
1911 **/
1912uint16_t
1913ptp_nikon_check_event (PTPParams* params, PTPUSBEventContainer** event, int* evtcnt)
1914{
1915 PTPContainer ptp;
1916 uint16_t ret;
1917 unsigned char *data = NULL;
1918 unsigned int size = 0;
1919
1920 PTP_CNT_INIT(ptp);
1921 ptp.Code=PTP_OC_NIKON_CheckEvent;
1922 ptp.Nparam=0;
1923 *evtcnt = 0;
1924 ret = ptp_transaction (params, &ptp, PTP_DP_GETDATA, 0, &data, &size);
1925 if (ret == PTP_RC_OK) {
1926 ptp_unpack_Nikon_EC (params, data, size, event, evtcnt);
1927 free (data);
1928 }
1929 return ret;
1930}
1931
1932/**
1933 * ptp_nikon_device_ready:
1934 *
1935 * This command checks if the device is ready. Used after
1936 * a capture.
1937 *
1938 * params: PTPParams*
1939 *
1940 * Return values: Some PTP_RC_* code.
1941 *
1942 **/
1943uint16_t
1944ptp_nikon_device_ready (PTPParams* params)
1945{
1946 PTPContainer ptp;
1947
1948 PTP_CNT_INIT(ptp);
1949 ptp.Code=PTP_OC_NIKON_DeviceReady;
1950 ptp.Nparam=0;
1951 return ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL);
1952}
1953
1954/**
1955 * ptp_nikon_getptpipinfo:
1956 *
1957 * This command gets the ptpip info data.
1958 *
1959 * params: PTPParams*
1960 * unsigned char *data - data
1961 * unsigned int size - size of returned data
1962 *
1963 * Return values: Some PTP_RC_* code.
1964 *
1965 **/
1966uint16_t
1967ptp_nikon_getptpipinfo (PTPParams* params, unsigned char **data, unsigned int *size)
1968{
1969 PTPContainer ptp;
1970
1971 PTP_CNT_INIT(ptp);
1972 ptp.Code=PTP_OC_NIKON_GetDevicePTPIPInfo;
1973 ptp.Nparam=0;
1974 return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, data, size);
1975}
1976
1977/**
Linus Walleijaa4b0752006-07-26 22:21:04 +00001978 * ptp_nikon_getwifiprofilelist:
Linus Walleijb02a0662006-04-25 08:05:09 +00001979 *
Linus Walleijaa4b0752006-07-26 22:21:04 +00001980 * This command gets the wifi profile list.
Linus Walleijb02a0662006-04-25 08:05:09 +00001981 *
1982 * params: PTPParams*
Linus Walleijb02a0662006-04-25 08:05:09 +00001983 *
1984 * Return values: Some PTP_RC_* code.
1985 *
1986 **/
1987uint16_t
Linus Walleijaa4b0752006-07-26 22:21:04 +00001988ptp_nikon_getwifiprofilelist (PTPParams* params)
Linus Walleijb02a0662006-04-25 08:05:09 +00001989{
1990 PTPContainer ptp;
Linus Walleijaa4b0752006-07-26 22:21:04 +00001991 unsigned char* data;
1992 unsigned int size;
1993 unsigned int pos;
1994 unsigned int profn;
1995 unsigned int n;
1996 char* buffer;
1997 uint8_t len;
1998
Linus Walleijb02a0662006-04-25 08:05:09 +00001999 PTP_CNT_INIT(ptp);
2000 ptp.Code=PTP_OC_NIKON_GetProfileAllData;
2001 ptp.Nparam=0;
Linus Walleijaa4b0752006-07-26 22:21:04 +00002002 size = 0;
2003 data = NULL;
2004 CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size));
2005
2006 if (size < 2) return PTP_RC_Undefined; /* FIXME: Add more precise error code */
2007
2008 params->wifi_profiles_version = data[0];
2009 params->wifi_profiles_number = data[1];
2010 if (params->wifi_profiles)
2011 free(params->wifi_profiles);
2012
2013 params->wifi_profiles = malloc(params->wifi_profiles_number*sizeof(PTPNIKONWifiProfile));
2014 memset(params->wifi_profiles, 0, params->wifi_profiles_number*sizeof(PTPNIKONWifiProfile));
2015
2016 pos = 2;
2017 profn = 0;
2018 while (profn < params->wifi_profiles_number && pos < size) {
2019 if (pos+6 >= size) return PTP_RC_Undefined;
2020 params->wifi_profiles[profn].id = data[pos++];
2021 params->wifi_profiles[profn].valid = data[pos++];
2022
2023 n = dtoh32a(&data[pos]);
2024 pos += 4;
2025 if (pos+n+4 >= size) return PTP_RC_Undefined;
2026 strncpy(params->wifi_profiles[profn].profile_name, (char*)&data[pos], n);
2027 params->wifi_profiles[profn].profile_name[16] = '\0';
2028 pos += n;
2029
2030 params->wifi_profiles[profn].display_order = data[pos++];
2031 params->wifi_profiles[profn].device_type = data[pos++];
2032 params->wifi_profiles[profn].icon_type = data[pos++];
2033
2034 buffer = ptp_unpack_string(params, data, pos, &len);
2035 strncpy(params->wifi_profiles[profn].creation_date, buffer, sizeof(params->wifi_profiles[profn].creation_date));
2036 pos += (len*2+1);
2037 if (pos+1 >= size) return PTP_RC_Undefined;
2038 /* FIXME: check if it is really last usage date */
2039 buffer = ptp_unpack_string(params, data, pos, &len);
2040 strncpy(params->wifi_profiles[profn].lastusage_date, buffer, sizeof(params->wifi_profiles[profn].lastusage_date));
2041 pos += (len*2+1);
2042 if (pos+5 >= size) return PTP_RC_Undefined;
2043
2044 n = dtoh32a(&data[pos]);
2045 pos += 4;
2046 if (pos+n >= size) return PTP_RC_Undefined;
2047 strncpy(params->wifi_profiles[profn].essid, (char*)&data[pos], n);
2048 params->wifi_profiles[profn].essid[32] = '\0';
2049 pos += n;
2050 pos += 1;
2051 profn++;
2052 }
2053
2054#if 0
2055 PTPNIKONWifiProfile test;
2056 memset(&test, 0, sizeof(PTPNIKONWifiProfile));
2057 strcpy(test.profile_name, "MyTest");
2058 test.icon_type = 1;
2059 strcpy(test.essid, "nikon");
2060 test.ip_address = 10 + 11 << 16 + 11 << 24;
2061 test.subnet_mask = 24;
2062 test.access_mode = 1;
2063 test.wifi_channel = 1;
2064 test.key_nr = 1;
2065
2066 ptp_nikon_writewifiprofile(params, &test);
2067#endif
2068
2069 return PTP_RC_OK;
Linus Walleijb02a0662006-04-25 08:05:09 +00002070}
2071
2072/**
Linus Walleijaa4b0752006-07-26 22:21:04 +00002073 * ptp_nikon_deletewifiprofile:
2074 *
2075 * This command deletes a wifi profile.
2076 *
2077 * params: PTPParams*
2078 * unsigned int profilenr - profile number
2079 *
2080 * Return values: Some PTP_RC_* code.
2081 *
2082 **/
2083uint16_t
2084ptp_nikon_deletewifiprofile (PTPParams* params, uint32_t profilenr)
2085{
2086 PTPContainer ptp;
2087
2088 PTP_CNT_INIT(ptp);
2089 ptp.Code=PTP_OC_NIKON_DeleteProfile;
2090 ptp.Nparam=1;
2091 ptp.Param1=profilenr;
2092 return ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL);
2093}
2094
2095/**
2096 * ptp_nikon_writewifiprofile:
Linus Walleijb02a0662006-04-25 08:05:09 +00002097 *
2098 * This command gets the ptpip info data.
2099 *
2100 * params: PTPParams*
Linus Walleijaa4b0752006-07-26 22:21:04 +00002101 * unsigned int profilenr - profile number
Linus Walleijb02a0662006-04-25 08:05:09 +00002102 * unsigned char *data - data
2103 * unsigned int size - size of returned data
2104 *
2105 * Return values: Some PTP_RC_* code.
2106 *
2107 **/
2108uint16_t
Linus Walleijaa4b0752006-07-26 22:21:04 +00002109ptp_nikon_writewifiprofile (PTPParams* params, PTPNIKONWifiProfile* profile)
Linus Walleijb02a0662006-04-25 08:05:09 +00002110{
Linus Walleijaa4b0752006-07-26 22:21:04 +00002111 unsigned char guid[16];
2112
2113 PTPContainer ptp;
2114 unsigned char buffer[1024];
2115 unsigned char* data = buffer;
2116 int size = 0;
2117 int i;
2118 uint8_t len;
2119 int profilenr = -1;
2120
2121 ptp_nikon_getptpipguid(guid);
2122
2123 if (!params->wifi_profiles)
2124 CHECK_PTP_RC(ptp_nikon_getwifiprofilelist(params));
2125
2126 for (i = 0; i < params->wifi_profiles_number; i++) {
2127 if (!params->wifi_profiles[i].valid) {
2128 profilenr = params->wifi_profiles[i].id;
2129 break;
2130 }
2131 }
2132
2133 if (profilenr == -1) {
2134 /* No free profile! */
2135 return PTP_RC_StoreFull;
2136 }
2137
2138 memset(buffer, 0, 1024);
2139
2140 buffer[0x00] = 0x64; /* Version */
2141
2142 /* Profile name */
2143 htod32a(&buffer[0x01], 17);
2144 /* 16 as third parameter, so there will always be a null-byte in the end */
2145 strncpy((char*)&buffer[0x05], profile->profile_name, 16);
2146
2147 buffer[0x16] = 0x00; /* Display order */
2148 buffer[0x17] = profile->device_type;
2149 buffer[0x18] = profile->icon_type;
2150
2151 /* FIXME: Creation date: put a real date here */
2152 ptp_pack_string(params, "19990909T090909", data, 0x19, &len);
2153
2154 /* IP parameters */
2155 *((unsigned int*)&buffer[0x3A]) = profile->ip_address; /* Do not reverse bytes */
2156 buffer[0x3E] = profile->subnet_mask;
2157 *((unsigned int*)&buffer[0x3F]) = profile->gateway_address; /* Do not reverse bytes */
2158 buffer[0x43] = profile->address_mode;
2159
2160 /* Wifi parameters */
2161 buffer[0x44] = profile->access_mode;
2162 buffer[0x45] = profile->wifi_channel;
2163
2164 htod32a(&buffer[0x46], 33); /* essid */
2165 /* 32 as third parameter, so there will always be a null-byte in the end */
2166 strncpy((char*)&buffer[0x4A], profile->essid, 32);
2167
2168 buffer[0x6B] = profile->authentification;
2169 buffer[0x6C] = profile->encryption;
2170 htod32a(&buffer[0x6D], 64);
2171 for (i = 0; i < 64; i++) {
2172 buffer[0x71+i] = profile->key[i];
2173 }
2174 buffer[0xB1] = profile->key_nr;
2175 memcpy(&buffer[0xB2], guid, 16);
2176
2177 switch(profile->encryption) {
2178 case 1: /* WEP 64bit */
2179 htod16a(&buffer[0xC2], 5); /* (64-24)/8 = 5 */
2180 break;
2181 case 2: /* WEP 128bit */
2182 htod16a(&buffer[0xC2], 13); /* (128-24)/8 = 13 */
2183 break;
2184 default:
2185 htod16a(&buffer[0xC2], 0);
2186 }
2187 size = 0xC4;
2188
2189 PTP_CNT_INIT(ptp);
2190 ptp.Code=PTP_OC_NIKON_SendProfileData;
2191 ptp.Nparam=1;
2192 ptp.Param1=profilenr;
2193 return ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, &data, NULL);
Linus Walleijb02a0662006-04-25 08:05:09 +00002194}
2195
2196/**
2197 * ptp_mtp_getobjectpropssupported:
2198 *
2199 * This command gets the object properties possible from the device.
2200 *
2201 * params: PTPParams*
2202 * uint ofc - object format code
2203 * unsigned int *propnum - number of elements in returned array
2204 * uint16_t *props - array of supported properties
2205 *
2206 * Return values: Some PTP_RC_* code.
2207 *
2208 **/
2209uint16_t
2210ptp_mtp_getobjectpropssupported (PTPParams* params, uint16_t ofc,
2211 uint32_t *propnum, uint16_t **props
2212) {
2213 PTPContainer ptp;
2214 uint16_t ret;
2215 unsigned char *data = NULL;
2216 unsigned int size = 0;
2217
2218 PTP_CNT_INIT(ptp);
2219 ptp.Code=PTP_OC_MTP_GetObjectPropsSupported;
2220 ptp.Nparam = 1;
2221 ptp.Param1 = ofc;
2222 ret = ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size);
2223 if (ret == PTP_RC_OK)
2224 *propnum=ptp_unpack_uint16_t_array(params,data,0,props);
2225 free(data);
2226 return ret;
2227}
2228
2229/**
2230 * ptp_mtp_getobjectpropdesc:
2231 *
2232 * This command gets the object property description.
2233 *
2234 * params: PTPParams*
2235 * uint16_t opc - object property code
2236 * uint16_t ofc - object format code
2237 *
2238 * Return values: Some PTP_RC_* code.
2239 *
2240 **/
2241uint16_t
2242ptp_mtp_getobjectpropdesc (
2243 PTPParams* params, uint16_t opc, uint16_t ofc, PTPObjectPropDesc *opd
2244) {
2245 PTPContainer ptp;
2246 uint16_t ret;
2247 unsigned char *data = NULL;
2248 unsigned int size = 0;
2249
2250 PTP_CNT_INIT(ptp);
2251 ptp.Code=PTP_OC_MTP_GetObjectPropDesc;
2252 ptp.Nparam = 2;
2253 ptp.Param1 = opc;
2254 ptp.Param2 = ofc;
2255 ret = ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size);
2256 if (ret == PTP_RC_OK)
2257 ptp_unpack_OPD (params, data, opd, size);
2258 free(data);
2259 return ret;
2260}
2261
2262/**
2263 * ptp_mtp_getobjectpropvalue:
2264 *
2265 * This command gets the object properties of an object handle.
2266 *
2267 * params: PTPParams*
2268 * uint32_t objectid - object format code
2269 * uint16_t opc - object prop code
2270 *
2271 * Return values: Some PTP_RC_* code.
2272 *
2273 **/
2274uint16_t
2275ptp_mtp_getobjectpropvalue (
2276 PTPParams* params, uint32_t oid, uint16_t opc,
2277 PTPPropertyValue *value, uint16_t datatype
2278) {
2279 PTPContainer ptp;
2280 uint16_t ret;
2281 unsigned char *data = NULL;
2282 unsigned int size = 0;
2283 int offset = 0;
2284
2285 PTP_CNT_INIT(ptp);
2286 ptp.Code=PTP_OC_MTP_GetObjectPropValue;
2287 ptp.Nparam = 2;
2288 ptp.Param1 = oid;
2289 ptp.Param2 = opc;
2290 ret = ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size);
2291 if (ret == PTP_RC_OK)
2292 ptp_unpack_DPV(params, data, &offset, size, value, datatype);
2293 free(data);
2294 return ret;
2295}
2296
2297/**
2298 * ptp_mtp_setobjectpropvalue:
2299 *
2300 * This command gets the object properties of an object handle.
2301 *
2302 * params: PTPParams*
2303 * uint32_t objectid - object format code
2304 * uint16_t opc - object prop code
2305 *
2306 * Return values: Some PTP_RC_* code.
2307 *
2308 **/
2309uint16_t
2310ptp_mtp_setobjectpropvalue (
2311 PTPParams* params, uint32_t oid, uint16_t opc,
2312 PTPPropertyValue *value, uint16_t datatype
2313) {
2314 PTPContainer ptp;
2315 uint16_t ret;
2316 unsigned char *data = NULL;
2317 unsigned int size ;
2318
2319 PTP_CNT_INIT(ptp);
2320 ptp.Code=PTP_OC_MTP_SetObjectPropValue;
2321 ptp.Nparam = 2;
2322 ptp.Param1 = oid;
2323 ptp.Param2 = opc;
2324 size = ptp_pack_DPV(params, value, &data, datatype);
Linus Walleijf67bca92006-05-29 09:33:39 +00002325 ret = ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, &data, NULL);
Linus Walleijb02a0662006-04-25 08:05:09 +00002326 free(data);
2327 return ret;
2328}
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002329
Linus Walleijf67bca92006-05-29 09:33:39 +00002330uint16_t
2331ptp_mtp_getobjectreferences (PTPParams* params, uint32_t handle, uint32_t** ohArray, uint32_t* arraylen)
2332{
2333 PTPContainer ptp;
2334 uint16_t ret;
2335 unsigned char* dpv=NULL;
2336
2337 PTP_CNT_INIT(ptp);
2338 ptp.Code=PTP_OC_MTP_GetObjectReferences;
2339 ptp.Param1=handle;
2340 ptp.Nparam=1;
2341 ret=ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &dpv, NULL);
2342 if (ret == PTP_RC_OK) *arraylen = ptp_unpack_uint32_t_array(params, dpv, 0, ohArray);
2343 free(dpv);
2344 return ret;
2345}
2346
2347uint16_t
2348ptp_mtp_setobjectreferences (PTPParams* params, uint32_t handle, uint32_t* ohArray, uint32_t arraylen)
2349{
2350 PTPContainer ptp;
2351 uint16_t ret;
2352 uint32_t size;
2353 unsigned char* dpv=NULL;
2354
2355 PTP_CNT_INIT(ptp);
2356 ptp.Code = PTP_OC_MTP_SetObjectReferences;
2357 ptp.Param1 = handle;
2358 ptp.Nparam = 1;
2359 size = ptp_pack_uint32_t_array(params, ohArray, arraylen, &dpv);
2360 ret = ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, (unsigned char **)&dpv, NULL);
2361 free(dpv);
2362 return ret;
2363}
2364
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002365/* Non PTP protocol functions */
2366/* devinfo testing functions */
2367
2368int
2369ptp_operation_issupported(PTPParams* params, uint16_t operation)
2370{
2371 int i=0;
2372
2373 for (;i<params->deviceinfo.OperationsSupported_len;i++) {
2374 if (params->deviceinfo.OperationsSupported[i]==operation)
2375 return 1;
2376 }
2377 return 0;
2378}
2379
2380
2381int
Linus Walleijb02a0662006-04-25 08:05:09 +00002382ptp_event_issupported(PTPParams* params, uint16_t event)
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002383{
2384 int i=0;
2385
Linus Walleijb02a0662006-04-25 08:05:09 +00002386 for (;i<params->deviceinfo.EventsSupported_len;i++) {
2387 if (params->deviceinfo.EventsSupported[i]==event)
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002388 return 1;
2389 }
2390 return 0;
2391}
2392
Linus Walleijb02a0662006-04-25 08:05:09 +00002393
2394int
2395ptp_property_issupported(PTPParams* params, uint16_t property)
2396{
2397 int i=0;
2398
2399 for (;i<params->deviceinfo.DevicePropertiesSupported_len;i++)
2400 if (params->deviceinfo.DevicePropertiesSupported[i]==property)
2401 return 1;
2402 return 0;
2403}
2404
2405/* ptp structures freeing functions */
2406void
2407ptp_free_devicepropvalue(uint16_t dt, PTPPropertyValue* dpd) {
2408 switch (dt) {
2409 case PTP_DTC_INT8: case PTP_DTC_UINT8:
2410 case PTP_DTC_UINT16: case PTP_DTC_INT16:
2411 case PTP_DTC_UINT32: case PTP_DTC_INT32:
2412 case PTP_DTC_UINT64: case PTP_DTC_INT64:
2413 case PTP_DTC_UINT128: case PTP_DTC_INT128:
2414 /* Nothing to free */
2415 break;
2416 case PTP_DTC_AINT8: case PTP_DTC_AUINT8:
2417 case PTP_DTC_AUINT16: case PTP_DTC_AINT16:
2418 case PTP_DTC_AUINT32: case PTP_DTC_AINT32:
2419 case PTP_DTC_AUINT64: case PTP_DTC_AINT64:
2420 case PTP_DTC_AUINT128: case PTP_DTC_AINT128:
2421 if (dpd->a.v)
2422 free(dpd->a.v);
2423 break;
2424 case PTP_DTC_STR:
2425 if (dpd->str)
2426 free(dpd->str);
2427 break;
2428 }
2429}
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002430
2431void
2432ptp_free_devicepropdesc(PTPDevicePropDesc* dpd)
2433{
2434 uint16_t i;
2435
Linus Walleijb02a0662006-04-25 08:05:09 +00002436 ptp_free_devicepropvalue (dpd->DataType, &dpd->FactoryDefaultValue);
2437 ptp_free_devicepropvalue (dpd->DataType, &dpd->CurrentValue);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002438 switch (dpd->FormFlag) {
Linus Walleijb02a0662006-04-25 08:05:09 +00002439 case PTP_DPFF_Range:
2440 ptp_free_devicepropvalue (dpd->DataType, &dpd->FORM.Range.MinimumValue);
2441 ptp_free_devicepropvalue (dpd->DataType, &dpd->FORM.Range.MaximumValue);
2442 ptp_free_devicepropvalue (dpd->DataType, &dpd->FORM.Range.StepSize);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002443 break;
Linus Walleijb02a0662006-04-25 08:05:09 +00002444 case PTP_DPFF_Enumeration:
2445 if (dpd->FORM.Enum.SupportedValue) {
2446 for (i=0;i<dpd->FORM.Enum.NumberOfValues;i++)
2447 ptp_free_devicepropvalue (dpd->DataType, dpd->FORM.Enum.SupportedValue+i);
2448 free (dpd->FORM.Enum.SupportedValue);
2449 }
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002450 }
2451}
2452
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002453void
Linus Walleijb02a0662006-04-25 08:05:09 +00002454ptp_free_objectpropdesc(PTPObjectPropDesc* opd)
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002455{
Linus Walleijb02a0662006-04-25 08:05:09 +00002456 uint16_t i;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002457
Linus Walleijb02a0662006-04-25 08:05:09 +00002458 ptp_free_devicepropvalue (opd->DataType, &opd->FactoryDefaultValue);
2459 switch (opd->FormFlag) {
2460 case PTP_OPFF_None:
2461 break;
2462 case PTP_OPFF_Range:
2463 ptp_free_devicepropvalue (opd->DataType, &opd->FORM.Range.MinimumValue);
2464 ptp_free_devicepropvalue (opd->DataType, &opd->FORM.Range.MaximumValue);
2465 ptp_free_devicepropvalue (opd->DataType, &opd->FORM.Range.StepSize);
2466 break;
2467 case PTP_OPFF_Enumeration:
2468 if (opd->FORM.Enum.SupportedValue) {
2469 for (i=0;i<opd->FORM.Enum.NumberOfValues;i++)
2470 ptp_free_devicepropvalue (opd->DataType, opd->FORM.Enum.SupportedValue+i);
2471 free (opd->FORM.Enum.SupportedValue);
2472 }
2473 default:
2474 fprintf (stderr, "Unknown OPFF type %d\n", opd->FormFlag);
2475 break;
2476 }
2477}
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002478
2479void
2480ptp_perror(PTPParams* params, uint16_t error) {
2481
2482 int i;
2483 /* PTP error descriptions */
2484 static struct {
Linus Walleijb02a0662006-04-25 08:05:09 +00002485 short n;
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002486 const char *txt;
2487 } ptp_errors[] = {
2488 {PTP_RC_Undefined, N_("PTP: Undefined Error")},
2489 {PTP_RC_OK, N_("PTP: OK!")},
2490 {PTP_RC_GeneralError, N_("PTP: General Error")},
2491 {PTP_RC_SessionNotOpen, N_("PTP: Session Not Open")},
2492 {PTP_RC_InvalidTransactionID, N_("PTP: Invalid Transaction ID")},
2493 {PTP_RC_OperationNotSupported, N_("PTP: Operation Not Supported")},
2494 {PTP_RC_ParameterNotSupported, N_("PTP: Parameter Not Supported")},
2495 {PTP_RC_IncompleteTransfer, N_("PTP: Incomplete Transfer")},
2496 {PTP_RC_InvalidStorageId, N_("PTP: Invalid Storage ID")},
2497 {PTP_RC_InvalidObjectHandle, N_("PTP: Invalid Object Handle")},
2498 {PTP_RC_DevicePropNotSupported, N_("PTP: Device Prop Not Supported")},
2499 {PTP_RC_InvalidObjectFormatCode, N_("PTP: Invalid Object Format Code")},
2500 {PTP_RC_StoreFull, N_("PTP: Store Full")},
2501 {PTP_RC_ObjectWriteProtected, N_("PTP: Object Write Protected")},
2502 {PTP_RC_StoreReadOnly, N_("PTP: Store Read Only")},
2503 {PTP_RC_AccessDenied, N_("PTP: Access Denied")},
2504 {PTP_RC_NoThumbnailPresent, N_("PTP: No Thumbnail Present")},
2505 {PTP_RC_SelfTestFailed, N_("PTP: Self Test Failed")},
2506 {PTP_RC_PartialDeletion, N_("PTP: Partial Deletion")},
2507 {PTP_RC_StoreNotAvailable, N_("PTP: Store Not Available")},
2508 {PTP_RC_SpecificationByFormatUnsupported,
2509 N_("PTP: Specification By Format Unsupported")},
2510 {PTP_RC_NoValidObjectInfo, N_("PTP: No Valid Object Info")},
2511 {PTP_RC_InvalidCodeFormat, N_("PTP: Invalid Code Format")},
2512 {PTP_RC_UnknownVendorCode, N_("PTP: Unknown Vendor Code")},
2513 {PTP_RC_CaptureAlreadyTerminated,
2514 N_("PTP: Capture Already Terminated")},
Linus Walleijb02a0662006-04-25 08:05:09 +00002515 {PTP_RC_DeviceBusy, N_("PTP: Device Busy")},
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002516 {PTP_RC_InvalidParentObject, N_("PTP: Invalid Parent Object")},
2517 {PTP_RC_InvalidDevicePropFormat, N_("PTP: Invalid Device Prop Format")},
2518 {PTP_RC_InvalidDevicePropValue, N_("PTP: Invalid Device Prop Value")},
2519 {PTP_RC_InvalidParameter, N_("PTP: Invalid Parameter")},
2520 {PTP_RC_SessionAlreadyOpened, N_("PTP: Session Already Opened")},
2521 {PTP_RC_TransactionCanceled, N_("PTP: Transaction Canceled")},
2522 {PTP_RC_SpecificationOfDestinationUnsupported,
2523 N_("PTP: Specification Of Destination Unsupported")},
Linus Walleijb02a0662006-04-25 08:05:09 +00002524 {PTP_RC_EK_FilenameRequired, N_("PTP: EK Filename Required")},
2525 {PTP_RC_EK_FilenameConflicts, N_("PTP: EK Filename Conflicts")},
2526 {PTP_RC_EK_FilenameInvalid, N_("PTP: EK Filename Invalid")},
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002527
2528 {PTP_ERROR_IO, N_("PTP: I/O error")},
2529 {PTP_ERROR_BADPARAM, N_("PTP: Error: bad parameter")},
2530 {PTP_ERROR_DATA_EXPECTED, N_("PTP: Protocol error, data expected")},
2531 {PTP_ERROR_RESP_EXPECTED, N_("PTP: Protocol error, response expected")},
2532 {0, NULL}
Linus Walleijb02a0662006-04-25 08:05:09 +00002533};
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002534
2535 for (i=0; ptp_errors[i].txt!=NULL; i++)
Linus Walleijb02a0662006-04-25 08:05:09 +00002536 if (ptp_errors[i].n == error)
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002537 ptp_error(params, ptp_errors[i].txt);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002538}
2539
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002540const char*
Linus Walleijb02a0662006-04-25 08:05:09 +00002541ptp_get_property_description(PTPParams* params, uint16_t dpc)
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002542{
2543 int i;
Linus Walleija823a702006-08-27 21:27:46 +00002544 /* Device Property descriptions */
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002545 struct {
2546 uint16_t dpc;
2547 const char *txt;
2548 } ptp_device_properties[] = {
Linus Walleijb02a0662006-04-25 08:05:09 +00002549 {PTP_DPC_Undefined, N_("Undefined PTP Property")},
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002550 {PTP_DPC_BatteryLevel, N_("Battery Level")},
2551 {PTP_DPC_FunctionalMode, N_("Functional Mode")},
2552 {PTP_DPC_ImageSize, N_("Image Size")},
2553 {PTP_DPC_CompressionSetting, N_("Compression Setting")},
2554 {PTP_DPC_WhiteBalance, N_("White Balance")},
2555 {PTP_DPC_RGBGain, N_("RGB Gain")},
2556 {PTP_DPC_FNumber, N_("F-Number")},
2557 {PTP_DPC_FocalLength, N_("Focal Length")},
2558 {PTP_DPC_FocusDistance, N_("Focus Distance")},
2559 {PTP_DPC_FocusMode, N_("Focus Mode")},
2560 {PTP_DPC_ExposureMeteringMode, N_("Exposure Metering Mode")},
2561 {PTP_DPC_FlashMode, N_("Flash Mode")},
2562 {PTP_DPC_ExposureTime, N_("Exposure Time")},
2563 {PTP_DPC_ExposureProgramMode, N_("Exposure Program Mode")},
2564 {PTP_DPC_ExposureIndex,
2565 N_("Exposure Index (film speed ISO)")},
2566 {PTP_DPC_ExposureBiasCompensation,
2567 N_("Exposure Bias Compensation")},
2568 {PTP_DPC_DateTime, N_("Date Time")},
2569 {PTP_DPC_CaptureDelay, N_("Pre-Capture Delay")},
2570 {PTP_DPC_StillCaptureMode, N_("Still Capture Mode")},
2571 {PTP_DPC_Contrast, N_("Contrast")},
2572 {PTP_DPC_Sharpness, N_("Sharpness")},
2573 {PTP_DPC_DigitalZoom, N_("Digital Zoom")},
2574 {PTP_DPC_EffectMode, N_("Effect Mode")},
2575 {PTP_DPC_BurstNumber, N_("Burst Number")},
2576 {PTP_DPC_BurstInterval, N_("Burst Interval")},
2577 {PTP_DPC_TimelapseNumber, N_("Timelapse Number")},
2578 {PTP_DPC_TimelapseInterval, N_("Timelapse Interval")},
2579 {PTP_DPC_FocusMeteringMode, N_("Focus Metering Mode")},
2580 {PTP_DPC_UploadURL, N_("Upload URL")},
2581 {PTP_DPC_Artist, N_("Artist")},
2582 {PTP_DPC_CopyrightInfo, N_("Copyright Info")},
2583 {0,NULL}
2584 };
2585 struct {
2586 uint16_t dpc;
2587 const char *txt;
2588 } ptp_device_properties_EK[] = {
Linus Walleijb02a0662006-04-25 08:05:09 +00002589 {PTP_DPC_EK_ColorTemperature, N_("Color Temperature")},
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002590 {PTP_DPC_EK_DateTimeStampFormat,
Linus Walleijb02a0662006-04-25 08:05:09 +00002591 N_("Date Time Stamp Format")},
2592 {PTP_DPC_EK_BeepMode, N_("Beep Mode")},
2593 {PTP_DPC_EK_VideoOut, N_("Video Out")},
2594 {PTP_DPC_EK_PowerSaving, N_("Power Saving")},
2595 {PTP_DPC_EK_UI_Language, N_("UI Language")},
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002596 {0,NULL}
2597 };
2598
2599 struct {
2600 uint16_t dpc;
2601 const char *txt;
Linus Walleijb02a0662006-04-25 08:05:09 +00002602 } ptp_device_properties_Canon[] = {
2603 {PTP_DPC_CANON_BeepMode, N_("Beep Mode")},
2604 {PTP_DPC_CANON_ViewfinderMode, N_("Viewfinder Mode")},
2605 {PTP_DPC_CANON_ImageQuality, N_("Image Quality")},
2606 {PTP_DPC_CANON_ImageSize, N_("Image Size")},
2607 {PTP_DPC_CANON_FlashMode, N_("Flash Mode")},
2608 {PTP_DPC_CANON_ShootingMode, N_("Shooting Mode")},
2609 {PTP_DPC_CANON_MeteringMode, N_("Metering Mode")},
2610 {PTP_DPC_CANON_AFDistance, N_("AF Distance")},
2611 {PTP_DPC_CANON_FocusingPoint, N_("Focusing Point")},
2612 {PTP_DPC_CANON_WhiteBalance, N_("White Balance")},
2613 {PTP_DPC_CANON_ISOSpeed, N_("ISO Speed")},
2614 {PTP_DPC_CANON_Aperture, N_("Aperture")},
2615 {PTP_DPC_CANON_ShutterSpeed, N_("ShutterSpeed")},
2616 {PTP_DPC_CANON_ExpCompensation, N_("Exposure Compensation")},
2617 {PTP_DPC_CANON_Zoom, N_("Zoom")},
2618 {PTP_DPC_CANON_SizeQualityMode, N_("Size Quality Mode")},
2619 {PTP_DPC_CANON_FirmwareVersion, N_("Firmware Version")},
2620 {PTP_DPC_CANON_CameraModel, N_("Camera Model")},
2621 {PTP_DPC_CANON_CameraOwner, N_("Camera Owner")},
2622 {PTP_DPC_CANON_UnixTime, N_("UNIX Time")},
2623 {PTP_DPC_CANON_DZoomMagnification, N_("Digital Zoom Magnification")},
2624 {PTP_DPC_CANON_PhotoEffect, N_("Photo Effect")},
2625 {PTP_DPC_CANON_AssistLight, N_("Assist Light")},
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002626 {0,NULL}
2627 };
Linus Walleijb02a0662006-04-25 08:05:09 +00002628
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002629 struct {
2630 uint16_t dpc;
2631 const char *txt;
Linus Walleijb02a0662006-04-25 08:05:09 +00002632 } ptp_device_properties_Nikon[] = {
2633 {PTP_DPC_NIKON_WhiteBalanceAutoBias, /* 0xD017 */
2634 N_("Auto White Balance Bias")},
2635 {PTP_DPC_NIKON_WhiteBalanceTungstenBias, /* 0xD018 */
2636 N_("Tungsten White Balance Bias")},
Linus Walleij4f40d112006-09-21 07:44:53 +00002637 {PTP_DPC_NIKON_WhiteBalanceFluorescentBias, /* 0xD019 */
2638 N_("Fluorescent White Balance Bias")},
Linus Walleijb02a0662006-04-25 08:05:09 +00002639 {PTP_DPC_NIKON_WhiteBalanceDaylightBias, /* 0xD01a */
2640 N_("Daylight White Balance Bias")},
2641 {PTP_DPC_NIKON_WhiteBalanceFlashBias, /* 0xD01b */
2642 N_("Flash White Balance Bias")},
2643 {PTP_DPC_NIKON_WhiteBalanceCloudyBias, /* 0xD01c */
2644 N_("Cloudy White Balance Bias")},
2645 {PTP_DPC_NIKON_WhiteBalanceShadeBias, /* 0xD01d */
2646 N_("Shady White Balance Bias")},
2647 {PTP_DPC_NIKON_WhiteBalanceColorTemperature, /* 0xD01e */
2648 N_("White Balance Colour Temperature")},
2649 {PTP_DPC_NIKON_ImageSharpening, /* 0xD02a */
2650 N_("Sharpening")},
2651 {PTP_DPC_NIKON_ToneCompensation, /* 0xD02b */
2652 N_("Tone Compensation")},
2653 {PTP_DPC_NIKON_ColorModel, /* 0xD02c */
2654 N_("Color Model")},
2655 {PTP_DPC_NIKON_HueAdjustment, /* 0xD02d */
2656 N_("Hue Adjustment")},
2657 {PTP_DPC_NIKON_NonCPULensDataFocalLength, /* 0xD02e */
2658 N_("Lens Focal Length (Non CPU)")},
2659 {PTP_DPC_NIKON_NonCPULensDataMaximumAperture, /* 0xD02f */
2660 N_("Lens Max. Aperture (Non CPU)")},
2661 {PTP_DPC_NIKON_CSMMenuBankSelect, /* 0xD040 */
2662 "PTP_DPC_NIKON_CSMMenuBankSelect"},
2663 {PTP_DPC_NIKON_MenuBankNameA, /* 0xD041 */
2664 "PTP_DPC_NIKON_MenuBankNameA"},
2665 {PTP_DPC_NIKON_MenuBankNameB, /* 0xD042 */
2666 "PTP_DPC_NIKON_MenuBankNameB"},
2667 {PTP_DPC_NIKON_MenuBankNameC, /* 0xD043 */
2668 "PTP_DPC_NIKON_MenuBankNameC"},
2669 {PTP_DPC_NIKON_MenuBankNameD, /* 0xD044 */
2670 "PTP_DPC_NIKON_MenuBankNameD"},
2671 {PTP_DPC_NIKON_A1AFCModePriority, /* 0xD048 */
2672 "PTP_DPC_NIKON_A1AFCModePriority"},
2673 {PTP_DPC_NIKON_A2AFSModePriority, /* 0xD049 */
2674 "PTP_DPC_NIKON_A2AFSModePriority"},
2675 {PTP_DPC_NIKON_A3GroupDynamicAF, /* 0xD04a */
2676 "PTP_DPC_NIKON_A3GroupDynamicAF"},
2677 {PTP_DPC_NIKON_A4AFActivation, /* 0xD04b */
2678 "PTP_DPC_NIKON_A4AFActivation"},
2679 {PTP_DPC_NIKON_A5FocusAreaIllumManualFocus, /* 0xD04c */
2680 "PTP_DPC_NIKON_A5FocusAreaIllumManualFocus"},
2681 {PTP_DPC_NIKON_FocusAreaIllumContinuous, /* 0xD04d */
2682 "PTP_DPC_NIKON_FocusAreaIllumContinuous"},
2683 {PTP_DPC_NIKON_FocusAreaIllumWhenSelected, /* 0xD04e */
2684 "PTP_DPC_NIKON_FocusAreaIllumWhenSelected"},
2685 {PTP_DPC_NIKON_FocusAreaWrap, /* 0xD04f */
2686 N_("Focus Area Wrap")},
2687 {PTP_DPC_NIKON_A7VerticalAFON, /* 0xD050 */
2688 N_("Vertical AF On")},
2689 {PTP_DPC_NIKON_ISOAuto, /* 0xD054 */
2690 N_("Auto ISO")},
2691 {PTP_DPC_NIKON_B2ISOStep, /* 0xD055 */
2692 N_("ISO Step")},
2693 {PTP_DPC_NIKON_EVStep, /* 0xD056 */
2694 N_("Exposure Step")},
2695 {PTP_DPC_NIKON_B4ExposureCompEv, /* 0xD057 */
2696 N_("Exposure Compensation (EV)")},
2697 {PTP_DPC_NIKON_ExposureCompensation, /* 0xD058 */
2698 N_("Exposure Compensation")},
2699 {PTP_DPC_NIKON_CenterWeightArea, /* 0xD059 */
2700 N_("Centre Weight Area")},
2701 {PTP_DPC_NIKON_AELockMode, /* 0xD05e */
2702 N_("Exposure Lock")},
2703 {PTP_DPC_NIKON_AELAFLMode, /* 0xD05f */
2704 N_("Focus Lock")},
2705 {PTP_DPC_NIKON_MeterOff, /* 0xD062 */
2706 N_("Auto Meter Off Time")},
2707 {PTP_DPC_NIKON_SelfTimer, /* 0xD063 */
2708 N_("Self Timer Delay")},
2709 {PTP_DPC_NIKON_MonitorOff, /* 0xD064 */
2710 N_("LCD Off Time")},
2711 {PTP_DPC_NIKON_D1ShootingSpeed, /* 0xD068 */
2712 N_("Shooting Speed")},
2713 {PTP_DPC_NIKON_D2MaximumShots, /* 0xD069 */
2714 N_("Max. Shots")},
2715 {PTP_DPC_NIKON_D3ExpDelayMode, /* 0xD06a */
Linus Walleijd208f9c2006-04-27 14:16:06 +00002716 "PTP_DPC_NIKON_D3ExpDelayMode"},
Linus Walleijb02a0662006-04-25 08:05:09 +00002717 {PTP_DPC_NIKON_LongExposureNoiseReduction, /* 0xD06b */
2718 N_("Long Exposure Noise Reduction")},
2719 {PTP_DPC_NIKON_FileNumberSequence, /* 0xD06c */
2720 N_("File Number Sequencing")},
2721 {PTP_DPC_NIKON_D6ControlPanelFinderRearControl, /* 0xD06d */
Linus Walleijd208f9c2006-04-27 14:16:06 +00002722 "PTP_DPC_NIKON_D6ControlPanelFinderRearControl"},
Linus Walleijb02a0662006-04-25 08:05:09 +00002723 {PTP_DPC_NIKON_ControlPanelFinderViewfinder, /* 0xD06e */
Linus Walleijd208f9c2006-04-27 14:16:06 +00002724 "PTP_DPC_NIKON_ControlPanelFinderViewfinder"},
Linus Walleijb02a0662006-04-25 08:05:09 +00002725 {PTP_DPC_NIKON_D7Illumination, /* 0xD06f */
Linus Walleijd208f9c2006-04-27 14:16:06 +00002726 "PTP_DPC_NIKON_D7Illumination"},
Linus Walleijb02a0662006-04-25 08:05:09 +00002727 {PTP_DPC_NIKON_E1FlashSyncSpeed, /* 0xD074 */
2728 N_("Flash Sync. Speed")},
2729 {PTP_DPC_NIKON_FlashShutterSpeed, /* 0xD075 */
2730 N_("Flash Shutter Speed")},
2731 {PTP_DPC_NIKON_E3AAFlashMode, /* 0xD076 */
2732 N_("Flash Mode")},
2733 {PTP_DPC_NIKON_E4ModelingFlash, /* 0xD077 */
2734 N_("Modeling Flash")},
2735 {PTP_DPC_NIKON_BracketSet, /* 0xD078 */
2736 N_("Bracket Set")},
2737 {PTP_DPC_NIKON_E6ManualModeBracketing, /* 0xD079 */
2738 N_("Manual Mode Bracketing")},
2739 {PTP_DPC_NIKON_BracketOrder, /* 0xD07a */
2740 N_("Bracket Order")},
2741 {PTP_DPC_NIKON_E8AutoBracketSelection, /* 0xD07b */
2742 N_("Auto Bracket Selection")},
2743 {PTP_DPC_NIKON_F1CenterButtonShootingMode, /* 0xD080 */
2744 N_("Center Button Shooting Mode")},
2745 {PTP_DPC_NIKON_CenterButtonPlaybackMode, /* 0xD081 */
2746 N_("Center Button Playback Mode")},
2747 {PTP_DPC_NIKON_F2Multiselector, /* 0xD082 */
2748 N_("Multiselector")},
2749 {PTP_DPC_NIKON_F3PhotoInfoPlayback, /* 0xD083 */
2750 N_("Photo Info. Playback")},
2751 {PTP_DPC_NIKON_F4AssignFuncButton, /* 0xD084 */
2752 N_("Assign Func. Button")},
2753 {PTP_DPC_NIKON_F5CustomizeCommDials, /* 0xD085 */
2754 N_("Customise Command Dials")},
2755 {PTP_DPC_NIKON_ReverseCommandDial, /* 0xD086 */
2756 N_("Reverse Command Dial")},
2757 {PTP_DPC_NIKON_ApertureSetting, /* 0xD087 */
2758 N_("Aperture Setting")},
2759 {PTP_DPC_NIKON_MenusAndPlayback, /* 0xD088 */
2760 N_("Menus and Playback")},
2761 {PTP_DPC_NIKON_F6ButtonsAndDials, /* 0xD089 */
2762 N_("Buttons and Dials")},
2763 {PTP_DPC_NIKON_NoCFCard, /* 0xD08a */
2764 N_("No CF Card Release")},
2765 {PTP_DPC_NIKON_ImageRotation, /* 0xD092 */
2766 N_("Image Rotation")},
2767 {PTP_DPC_NIKON_Bracketing, /* 0xD0c0 */
2768 N_("Exposure Bracketing")},
2769 {PTP_DPC_NIKON_ExposureBracketingIntervalDist, /* 0xD0c1 */
2770 N_("Exposure Bracketing Distance")},
2771 {PTP_DPC_NIKON_BracketingProgram, /* 0xD0c2 */
2772 N_("Exposure Bracketing Number")},
2773 {PTP_DPC_NIKON_AutofocusLCDTopMode2, /* 0xD107 */
2774 N_("AF LCD Top Mode 2")},
2775 {PTP_DPC_NIKON_AutofocusArea, /* 0xD108 */
2776 N_("Active AF Sensor")},
2777 {PTP_DPC_NIKON_LightMeter, /* 0xD10a */
2778 N_("Exposure Meter")},
2779 {PTP_DPC_NIKON_ExposureApertureLock, /* 0xD111 */
2780 N_("Exposure Aperture Lock")},
2781 {PTP_DPC_NIKON_MaximumShots, /* 0xD103 */
2782 N_("Maximum Shots")},
2783 {PTP_DPC_NIKON_OptimizeImage, /* 0xD140 */
2784 N_("Optimize Image")},
2785 {PTP_DPC_NIKON_Saturation, /* 0xD142 */
2786 N_("Saturation")},
2787 {PTP_DPC_NIKON_CSMMenu, /* 0xD180 */
2788 N_("CSM Menu")},
2789 {PTP_DPC_NIKON_BeepOff,
2790 N_("AF Beep Mode")},
2791 {PTP_DPC_NIKON_AutofocusMode,
2792 N_("Autofocus Mode")},
2793 {PTP_DPC_NIKON_AFAssist,
2794 N_("AF Assist Lamp")},
2795 {PTP_DPC_NIKON_PADVPMode,
2796 N_("Auto ISO P/A/DVP Setting")},
2797 {PTP_DPC_NIKON_ImageReview,
2798 N_("Image Review")},
2799 {PTP_DPC_NIKON_GridDisplay,
2800 N_("Viewfinder Grid Display")},
2801 {PTP_DPC_NIKON_AFAreaIllumination,
2802 N_("AF Area Illumination")},
2803 {PTP_DPC_NIKON_FlashMode,
2804 N_("Flash Mode")},
2805 {PTP_DPC_NIKON_FlashModeManualPower,
2806 N_("Flash Mode Manual Power")},
2807 {PTP_DPC_NIKON_FlashSign,
2808 N_("Flash Sign")},
2809 {PTP_DPC_NIKON_FlashExposureCompensation,
2810 N_("Flash Exposure Compensation")},
2811 {PTP_DPC_NIKON_RemoteTimeout,
2812 N_("Remote Timeout")},
2813 {PTP_DPC_NIKON_ImageCommentString,
2814 N_("Image Comment String")},
2815 {PTP_DPC_NIKON_FlashOpen,
2816 N_("Flash Open")},
2817 {PTP_DPC_NIKON_FlashCharged,
2818 N_("Flash Charged")},
2819 {PTP_DPC_NIKON_LensID,
2820 N_("Lens ID")},
2821 {PTP_DPC_NIKON_FocalLengthMin,
2822 N_("Min. Focal Length")},
2823 {PTP_DPC_NIKON_FocalLengthMax,
2824 N_("Max. Focal Length")},
2825 {PTP_DPC_NIKON_MaxApAtMinFocalLength,
2826 N_("Max. Aperture at Min. Focal Length")},
2827 {PTP_DPC_NIKON_MaxApAtMaxFocalLength,
2828 N_("Max. Aperture at Max. Focal Length")},
2829 {PTP_DPC_NIKON_LowLight,
2830 N_("Low Light")},
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002831 {0,NULL}
2832 };
Linus Walleij545c7792006-06-13 15:22:30 +00002833 struct {
2834 uint16_t dpc;
2835 const char *txt;
2836 } ptp_device_properties_MTP[] = {
2837 {PTP_DPC_MTP_SecureTime, N_("Secure Time")},
2838 {PTP_DPC_MTP_DeviceCertificate, N_("Device Certificate")},
2839 {PTP_DPC_MTP_SynchronizationPartner,
2840 N_("Synchronization Partner")},
2841 {PTP_DPC_MTP_DeviceFriendlyName,
2842 N_("Device Friendly Name")},
2843 {PTP_DPC_MTP_VolumeLevel, N_("Volume Level")},
2844 {PTP_DPC_MTP_DeviceIcon, N_("Device Icon")},
2845 {PTP_DPC_MTP_PlaybackRate, N_("Playback Rate")},
2846 {PTP_DPC_MTP_PlaybackObject, N_("Playback Object")},
2847 {PTP_DPC_MTP_PlaybackContainerIndex,
2848 N_("Playback Container Index")},
2849 {PTP_DPC_MTP_PlaybackPosition, N_("Playback Position")},
2850 {0,NULL}
2851 };
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002852
2853 for (i=0; ptp_device_properties[i].txt!=NULL; i++)
2854 if (ptp_device_properties[i].dpc==dpc)
2855 return (ptp_device_properties[i].txt);
2856
Linus Walleij545c7792006-06-13 15:22:30 +00002857 if (params->deviceinfo.VendorExtensionID==PTP_VENDOR_MICROSOFT)
2858 for (i=0; ptp_device_properties_MTP[i].txt!=NULL; i++)
2859 if (ptp_device_properties_MTP[i].dpc==dpc)
2860 return (ptp_device_properties_MTP[i].txt);
2861
Linus Walleijb02a0662006-04-25 08:05:09 +00002862 if (params->deviceinfo.VendorExtensionID==PTP_VENDOR_EASTMAN_KODAK)
2863 for (i=0; ptp_device_properties_EK[i].txt!=NULL; i++)
2864 if (ptp_device_properties_EK[i].dpc==dpc)
2865 return (ptp_device_properties_EK[i].txt);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002866
Linus Walleijb02a0662006-04-25 08:05:09 +00002867 if (params->deviceinfo.VendorExtensionID==PTP_VENDOR_CANON)
2868 for (i=0; ptp_device_properties_Canon[i].txt!=NULL; i++)
2869 if (ptp_device_properties_Canon[i].dpc==dpc)
2870 return (ptp_device_properties_Canon[i].txt);
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002871
Linus Walleijb02a0662006-04-25 08:05:09 +00002872 if (params->deviceinfo.VendorExtensionID==PTP_VENDOR_NIKON)
2873 for (i=0; ptp_device_properties_Nikon[i].txt!=NULL; i++)
2874 if (ptp_device_properties_Nikon[i].dpc==dpc)
2875 return (ptp_device_properties_Nikon[i].txt);
2876
Linus Walleijeb8c6fe2006-02-03 09:46:22 +00002877 return NULL;
2878}
2879
Linus Walleijb02a0662006-04-25 08:05:09 +00002880static int64_t
2881_value_to_num(PTPPropertyValue *data, uint16_t dt) {
2882 if (dt == PTP_DTC_STR) {
2883 if (!data->str)
2884 return 0;
2885 return atol(data->str);
2886 }
2887 if (dt & PTP_DTC_ARRAY_MASK) {
2888 return 0;
2889 } else {
2890 switch (dt) {
2891 case PTP_DTC_UNDEF:
2892 return 0;
2893 case PTP_DTC_INT8:
2894 return data->i8;
2895 case PTP_DTC_UINT8:
2896 return data->u8;
2897 case PTP_DTC_INT16:
2898 return data->i16;
2899 case PTP_DTC_UINT16:
2900 return data->u16;
2901 case PTP_DTC_INT32:
2902 return data->i32;
2903 case PTP_DTC_UINT32:
2904 return data->u32;
2905 /*
2906 PTP_DTC_INT64
2907 PTP_DTC_UINT64
2908 PTP_DTC_INT128
2909 PTP_DTC_UINT128
2910 */
2911 default:
2912 return 0;
2913 }
2914 }
2915
2916 return 0;
2917}
2918
2919#define PTP_VAL_BOOL(dpc) {dpc, 0, N_("Off")}, {dpc, 1, N_("On")}
2920#define PTP_VAL_RBOOL(dpc) {dpc, 0, N_("On")}, {dpc, 1, N_("Off")}
2921#define PTP_VAL_YN(dpc) {dpc, 0, N_("No")}, {dpc, 1, N_("Yes")}
2922
2923int
2924ptp_render_property_value(PTPParams* params, uint16_t dpc,
2925 PTPDevicePropDesc *dpd, int length, char *out)
2926{
2927 int i;
2928
2929 struct {
2930 uint16_t dpc;
2931 double coef;
2932 double bias;
2933 const char *format;
2934 } ptp_value_trans[] = {
2935 {PTP_DPC_ExposureIndex, 1.0, 0.0, "ISO %.0f"},
2936 {0, 0.0, 0.0, NULL}
2937 };
2938
2939 struct {
2940 uint16_t dpc;
2941 double coef;
2942 double bias;
2943 const char *format;
2944 } ptp_value_trans_Nikon[] = {
2945 {PTP_DPC_BatteryLevel, 1.0, 0.0, "%.0f%%"},
2946 {PTP_DPC_FNumber, 0.01, 0.0, "f/%.2g"},
2947 {PTP_DPC_FocalLength, 0.01, 0.0, "%.0f mm"},
2948 {PTP_DPC_ExposureTime, 0.00001, 0.0, "%.2g sec"},
2949 {PTP_DPC_ExposureBiasCompensation, 0.001, 0.0, N_("%.1f stops")},
2950 {PTP_DPC_NIKON_LightMeter, 0.08333, 0.0, N_("%.1f stops")},
2951 {PTP_DPC_NIKON_FlashExposureCompensation, 0.16666, 0.0, N_("%.1f stops")},
2952 {PTP_DPC_NIKON_CenterWeightArea, 2.0, 6.0, N_("%.0f mm")},
2953 {PTP_DPC_NIKON_FocalLengthMin, 0.01, 0.0, "%.0f mm"},
2954 {PTP_DPC_NIKON_FocalLengthMax, 0.01, 0.0, "%.0f mm"},
2955 {PTP_DPC_NIKON_MaxApAtMinFocalLength, 0.01, 0.0, "f/%.2g"},
2956 {PTP_DPC_NIKON_MaxApAtMaxFocalLength, 0.01, 0.0, "f/%.2g"},
2957 {0, 0.0, 0.0, NULL}
2958 };
2959
2960 struct {
2961 uint16_t dpc;
2962 int64_t key;
2963 char *value;
2964 } ptp_value_list_Nikon[] = {
2965 {PTP_DPC_CompressionSetting, 0, N_("JPEG Basic")},
2966 {PTP_DPC_CompressionSetting, 1, N_("JPEG Norm")},
2967 {PTP_DPC_CompressionSetting, 2, N_("JPEG Fine")},
2968 {PTP_DPC_CompressionSetting, 4, N_("RAW")},
2969 {PTP_DPC_CompressionSetting, 5, N_("RAW + JPEG Basic")},
2970 {PTP_DPC_WhiteBalance, 2, N_("Auto")},
2971 {PTP_DPC_WhiteBalance, 6, N_("Incandescent")},
2972 {PTP_DPC_WhiteBalance, 5, N_("Fluorescent")},
2973 {PTP_DPC_WhiteBalance, 4, N_("Daylight")},
2974 {PTP_DPC_WhiteBalance, 7, N_("Flash")},
2975 {PTP_DPC_WhiteBalance, 32784, N_("Cloudy")},
2976 {PTP_DPC_WhiteBalance, 32785, N_("Shade")},
2977 {PTP_DPC_WhiteBalance, 32787, N_("Preset")},
2978 {PTP_DPC_FlashMode, 32784, N_("Default")},
2979 {PTP_DPC_FlashMode, 4, N_("Red-eye Reduction")},
2980 {PTP_DPC_FlashMode, 32787, N_("Red-eye Reduction + Slow Sync")},
2981 {PTP_DPC_FlashMode, 32785, N_("Slow Sync")},
2982 {PTP_DPC_FlashMode, 32785, N_("Rear Curtain Sync + Slow Sync")},
2983 {PTP_DPC_FocusMeteringMode, 2, N_("Dynamic Area")},
2984 {PTP_DPC_FocusMeteringMode, 32784, N_("Single Area")},
2985 {PTP_DPC_FocusMeteringMode, 32785, N_("Closest Subject")},
2986 {PTP_DPC_FocusMode, 1, N_("Manual Focus")},
2987 {PTP_DPC_FocusMode, 32784, "AF-S"},
2988 {PTP_DPC_FocusMode, 32785, "AF-C"},
2989 PTP_VAL_BOOL(PTP_DPC_NIKON_ISOAuto),
2990 PTP_VAL_BOOL(PTP_DPC_NIKON_ExposureCompensation),
2991 PTP_VAL_BOOL(PTP_DPC_NIKON_AELockMode),
2992 {PTP_DPC_NIKON_AELAFLMode, 0, N_("AE/AF Lock")},
2993 {PTP_DPC_NIKON_AELAFLMode, 1, N_("AF Lock only")},
2994 {PTP_DPC_NIKON_AELAFLMode, 2, N_("AE Lock only")},
2995 {PTP_DPC_NIKON_AELAFLMode, 3, N_("AF Lock Hold")},
2996 {PTP_DPC_NIKON_AELAFLMode, 4, N_("AF On")},
2997 {PTP_DPC_NIKON_AELAFLMode, 5, N_("Flash Lock")},
2998 {PTP_DPC_ExposureMeteringMode, 2, N_("Center Weighted")},
2999 {PTP_DPC_ExposureMeteringMode, 3, N_("Matrix")},
3000 {PTP_DPC_ExposureMeteringMode, 4, N_("Spot")},
3001 {PTP_DPC_ExposureProgramMode, 1, "M"},
3002 {PTP_DPC_ExposureProgramMode, 3, "A"},
3003 {PTP_DPC_ExposureProgramMode, 4, "S"},
3004 {PTP_DPC_ExposureProgramMode, 2, "P"},
3005 {PTP_DPC_ExposureProgramMode, 32784, N_("Auto")},
3006 {PTP_DPC_ExposureProgramMode, 32785, N_("Portrait")},
3007 {PTP_DPC_ExposureProgramMode, 32786, N_("Landscape")},
3008 {PTP_DPC_ExposureProgramMode, 32787, N_("Macro")},
3009 {PTP_DPC_ExposureProgramMode, 32788, N_("Sports")},
3010 {PTP_DPC_ExposureProgramMode, 32790, N_("Night Landscape")},
3011 {PTP_DPC_ExposureProgramMode, 32789, N_("Night Portrait")},
3012 {PTP_DPC_StillCaptureMode, 1, N_("Single Shot")},
3013 {PTP_DPC_StillCaptureMode, 2, N_("Power Wind")},
3014 {PTP_DPC_StillCaptureMode, 32785, N_("Timer")},
3015 {PTP_DPC_StillCaptureMode, 32787, N_("Remote")},
3016 {PTP_DPC_StillCaptureMode, 32788, N_("Timer + Remote")},
3017 PTP_VAL_BOOL(PTP_DPC_NIKON_AutofocusMode),
3018 PTP_VAL_RBOOL(PTP_DPC_NIKON_AFAssist),
3019 PTP_VAL_RBOOL(PTP_DPC_NIKON_ImageReview),
3020 PTP_VAL_BOOL(PTP_DPC_NIKON_GridDisplay),
3021 {PTP_DPC_NIKON_AFAreaIllumination, 0, N_("Auto")},
3022 {PTP_DPC_NIKON_AFAreaIllumination, 1, N_("Off")},
3023 {PTP_DPC_NIKON_AFAreaIllumination, 2, N_("On")},
3024 {PTP_DPC_NIKON_ColorModel, 0, "sRGB"},
3025 {PTP_DPC_NIKON_ColorModel, 1, "AdobeRGB"},
3026 {PTP_DPC_NIKON_ColorModel, 2, "sRGB"},
3027 {PTP_DPC_NIKON_FlashMode, 0, "iTTL"},
3028 {PTP_DPC_NIKON_FlashMode, 1, N_("Manual")},
3029 {PTP_DPC_NIKON_FlashMode, 2, N_("Commander")},
3030 {PTP_DPC_NIKON_FlashModeManualPower, 0, N_("Full")},
3031 {PTP_DPC_NIKON_FlashModeManualPower, 1, "1/2"},
3032 {PTP_DPC_NIKON_FlashModeManualPower, 2, "1/4"},
3033 {PTP_DPC_NIKON_FlashModeManualPower, 3, "1/8"},
3034 {PTP_DPC_NIKON_FlashModeManualPower, 4, "1/16"},
3035 PTP_VAL_RBOOL(PTP_DPC_NIKON_FlashSign),
3036 {PTP_DPC_NIKON_RemoteTimeout, 0, N_("1 min")},
3037 {PTP_DPC_NIKON_RemoteTimeout, 1, N_("5 mins")},
3038 {PTP_DPC_NIKON_RemoteTimeout, 2, N_("10 mins")},
3039 {PTP_DPC_NIKON_RemoteTimeout, 3, N_("15 mins")},
3040 PTP_VAL_YN(PTP_DPC_NIKON_FlashOpen),
3041 PTP_VAL_YN(PTP_DPC_NIKON_FlashCharged),
3042 PTP_VAL_BOOL(PTP_DPC_NIKON_LongExposureNoiseReduction),
3043 PTP_VAL_BOOL(PTP_DPC_NIKON_FileNumberSequence),
3044 PTP_VAL_BOOL(PTP_DPC_NIKON_ReverseCommandDial),
3045 PTP_VAL_RBOOL(PTP_DPC_NIKON_NoCFCard),
3046 PTP_VAL_RBOOL(PTP_DPC_NIKON_ImageRotation),
3047 PTP_VAL_BOOL(PTP_DPC_NIKON_Bracketing),
3048 {PTP_DPC_NIKON_AutofocusArea, 0, N_("Centre")},
3049 {PTP_DPC_NIKON_AutofocusArea, 1, N_("Top")},
3050 {PTP_DPC_NIKON_AutofocusArea, 2, N_("Bottom")},
3051 {PTP_DPC_NIKON_AutofocusArea, 3, N_("Left")},
3052 {PTP_DPC_NIKON_AutofocusArea, 4, N_("Right")},
3053 {PTP_DPC_NIKON_OptimizeImage, 0, N_("Normal")},
3054 {PTP_DPC_NIKON_OptimizeImage, 1, N_("Vivid")},
3055 {PTP_DPC_NIKON_OptimizeImage, 2, N_("Sharper")},
3056 {PTP_DPC_NIKON_OptimizeImage, 3, N_("Softer")},
3057 {PTP_DPC_NIKON_OptimizeImage, 4, N_("Direct Print")},
3058 {PTP_DPC_NIKON_OptimizeImage, 5, N_("Portrait")},
3059 {PTP_DPC_NIKON_OptimizeImage, 6, N_("Landscape")},
3060 {PTP_DPC_NIKON_OptimizeImage, 7, N_("Custom")},
3061
3062 {PTP_DPC_NIKON_ImageSharpening, 0, N_("Auto")},
3063 {PTP_DPC_NIKON_ImageSharpening, 1, N_("Normal")},
3064 {PTP_DPC_NIKON_ImageSharpening, 2, N_("Low")},
3065 {PTP_DPC_NIKON_ImageSharpening, 3, N_("Medium Low")},
3066 {PTP_DPC_NIKON_ImageSharpening, 4, N_("Medium high")},
3067 {PTP_DPC_NIKON_ImageSharpening, 5, N_("High")},
3068 {PTP_DPC_NIKON_ImageSharpening, 6, N_("None")},
3069
3070 {PTP_DPC_NIKON_ToneCompensation, 0, N_("Auto")},
3071 {PTP_DPC_NIKON_ToneCompensation, 1, N_("Normal")},
3072 {PTP_DPC_NIKON_ToneCompensation, 2, N_("Low contrast")},
3073 {PTP_DPC_NIKON_ToneCompensation, 3, N_("Medium low")},
3074 {PTP_DPC_NIKON_ToneCompensation, 4, N_("Medium high")},
3075 {PTP_DPC_NIKON_ToneCompensation, 5, N_("High control")},
3076 {PTP_DPC_NIKON_ToneCompensation, 6, N_("Custom")},
3077
3078 {PTP_DPC_NIKON_Saturation, 0, N_("Normal")},
3079 {PTP_DPC_NIKON_Saturation, 1, N_("Moderate")},
3080 {PTP_DPC_NIKON_Saturation, 2, N_("Enhanced")},
3081
3082 {PTP_DPC_NIKON_LensID, 0, N_("Unknown")},
3083 {PTP_DPC_NIKON_LensID, 38, "Sigma 70-300mm 1:4-5.6 D APO Macro"},
3084 {PTP_DPC_NIKON_LensID, 83, "AF Nikkor 80-200mm 1:2.8 D ED"},
3085 {PTP_DPC_NIKON_LensID, 118, "AF Nikkor 50mm 1:1.8 D"},
3086 {PTP_DPC_NIKON_LensID, 127, "AF-S Nikkor 18-70mm 1:3.5-4.5G ED DX"},
3087 PTP_VAL_YN(PTP_DPC_NIKON_LowLight),
3088 PTP_VAL_YN(PTP_DPC_NIKON_CSMMenu),
3089 PTP_VAL_RBOOL(PTP_DPC_NIKON_BeepOff),
3090 {0, 0, NULL}
3091 };
Linus Walleijb02a0662006-04-25 08:05:09 +00003092 if (params->deviceinfo.VendorExtensionID==PTP_VENDOR_NIKON) {
3093 int64_t kval;
3094
3095 for (i=0; ptp_value_trans[i].dpc!=0; i++)
3096 if (ptp_value_trans[i].dpc==dpc) {
3097 double value = _value_to_num(&(dpd->CurrentValue), dpd->DataType);
3098
3099 return snprintf(out, length,
3100 _(ptp_value_trans[i].format),
3101 value * ptp_value_trans[i].coef +
3102 ptp_value_trans[i].bias);
3103 }
3104
3105 for (i=0; ptp_value_trans_Nikon[i].dpc!=0; i++)
3106 if (ptp_value_trans_Nikon[i].dpc==dpc) {
3107 double value = _value_to_num(&(dpd->CurrentValue), dpd->DataType);
3108
3109 return snprintf(out, length,
3110 _(ptp_value_trans_Nikon[i].format),
3111 value * ptp_value_trans_Nikon[i].coef +
3112 ptp_value_trans_Nikon[i].bias);
3113 }
3114
3115 kval = _value_to_num(&(dpd->CurrentValue), dpd->DataType);
3116
3117 for (i=0; ptp_value_list_Nikon[i].dpc!=0; i++)
3118 if (ptp_value_list_Nikon[i].dpc==dpc &&
3119 ptp_value_list_Nikon[i].key==kval)
3120 return snprintf(out, length, "%s",
3121 _(ptp_value_list_Nikon[i].value));
3122 }
3123 if (params->deviceinfo.VendorExtensionID==PTP_VENDOR_MICROSOFT) {
3124 switch (dpc) {
Linus Walleij545c7792006-06-13 15:22:30 +00003125 case PTP_DPC_MTP_SynchronizationPartner:
3126 case PTP_DPC_MTP_DeviceFriendlyName:
Linus Walleijb02a0662006-04-25 08:05:09 +00003127 return snprintf(out, length, "%s", dpd->CurrentValue.str);
Linus Walleij545c7792006-06-13 15:22:30 +00003128 case PTP_DPC_MTP_SecureTime:
3129 case PTP_DPC_MTP_DeviceCertificate: {
Linus Walleija823a702006-08-27 21:27:46 +00003130 /* FIXME: Convert to use unicode demux functions */
Linus Walleijb02a0662006-04-25 08:05:09 +00003131 for (i=0;(i<dpd->CurrentValue.a.count) && (i<length);i++)
3132 out[i] = dpd->CurrentValue.a.v[i].u16;
3133 if ( dpd->CurrentValue.a.count &&
3134 (dpd->CurrentValue.a.count < length)) {
3135 out[dpd->CurrentValue.a.count-1] = 0;
3136 return dpd->CurrentValue.a.count-1;
3137 } else {
3138 out[length-1] = 0;
3139 return length;
3140 }
3141 break;
3142 }
3143 default:
3144 break;
3145 }
3146 }
3147
3148 return 0;
3149}
3150
3151struct {
3152 uint16_t ofc;
3153 const char *format;
3154} ptp_ofc_trans[] = {
3155 {PTP_OFC_Undefined,"Undefined Type"},
3156 {PTP_OFC_Association,"Association/Directory"},
3157 {PTP_OFC_Script,"Script"},
3158 {PTP_OFC_Executable,"Executable"},
3159 {PTP_OFC_Text,"Text"},
3160 {PTP_OFC_HTML,"HTML"},
3161 {PTP_OFC_DPOF,"DPOF"},
3162 {PTP_OFC_AIFF,"AIFF"},
3163 {PTP_OFC_WAV,"MS Wave"},
3164 {PTP_OFC_MP3,"MP3"},
3165 {PTP_OFC_AVI,"MS AVI"},
3166 {PTP_OFC_MPEG,"MPEG"},
3167 {PTP_OFC_ASF,"ASF"},
3168 {PTP_OFC_QT,"Apple Quicktime"},
3169 {PTP_OFC_EXIF_JPEG,"JPEG"},
3170 {PTP_OFC_TIFF_EP,"TIFF EP"},
3171 {PTP_OFC_FlashPix,"FlashPix"},
3172 {PTP_OFC_BMP,"BMP"},
3173 {PTP_OFC_CIFF,"CIFF"},
3174 {PTP_OFC_GIF,"GIF"},
3175 {PTP_OFC_JFIF,"JFIF"},
3176 {PTP_OFC_PCD,"PCD"},
3177 {PTP_OFC_PICT,"PICT"},
3178 {PTP_OFC_PNG,"PNG"},
3179 {PTP_OFC_TIFF,"TIFF"},
3180 {PTP_OFC_TIFF_IT,"TIFF_IT"},
3181 {PTP_OFC_JP2,"JP2"},
3182 {PTP_OFC_JPX,"JPX"},
3183};
3184
3185struct {
3186 uint16_t ofc;
3187 const char *format;
3188} ptp_ofc_mtp_trans[] = {
3189 {PTP_OFC_MTP_Firmware,N_("Firmware")},
3190 {PTP_OFC_MTP_WindowsImageFormat,N_("WindowsImageFormat")},
3191 {PTP_OFC_MTP_UndefinedAudio,N_("Undefined Audio")},
3192 {PTP_OFC_MTP_WMA,"WMA"},
3193 {PTP_OFC_MTP_OGG,"OGG"},
Linus Walleijaa4b0752006-07-26 22:21:04 +00003194 {PTP_OFC_MTP_AudibleCodec,N_("Audible.com Codec")},
Linus Walleijb02a0662006-04-25 08:05:09 +00003195 {PTP_OFC_MTP_UndefinedVideo,N_("Undefined Video")},
3196 {PTP_OFC_MTP_WMV,"WMV"},
3197 {PTP_OFC_MTP_MP4,"MP4"},
3198 {PTP_OFC_MTP_UndefinedCollection,N_("Undefined Collection")},
3199 {PTP_OFC_MTP_AbstractMultimediaAlbum,N_("Abstract Multimedia Album")},
3200 {PTP_OFC_MTP_AbstractImageAlbum,N_("Abstract Image Album")},
3201 {PTP_OFC_MTP_AbstractAudioAlbum,N_("Abstract Audio Album")},
3202 {PTP_OFC_MTP_AbstractVideoAlbum,N_("Abstract Video Album")},
3203 {PTP_OFC_MTP_AbstractAudioVideoPlaylist,N_("Abstract Audio Video Playlist")},
3204 {PTP_OFC_MTP_AbstractContactGroup,N_("Abstract Contact Group")},
3205 {PTP_OFC_MTP_AbstractMessageFolder,N_("Abstract Message Folder")},
3206 {PTP_OFC_MTP_AbstractChapteredProduction,N_("Abstract Chaptered Production")},
3207 {PTP_OFC_MTP_WPLPlaylist,N_("WPL Playlist")},
3208 {PTP_OFC_MTP_M3UPlaylist,N_("M3U Playlist")},
3209 {PTP_OFC_MTP_MPLPlaylist,N_("MPL Playlist")},
3210 {PTP_OFC_MTP_ASXPlaylist,N_("ASX Playlist")},
3211 {PTP_OFC_MTP_PLSPlaylist,N_("PLS Playlist")},
3212 {PTP_OFC_MTP_UndefinedDocument,N_("UndefinedDocument")},
3213 {PTP_OFC_MTP_AbstractDocument,N_("AbstractDocument")},
3214 {PTP_OFC_MTP_UndefinedMessage,N_("UndefinedMessage")},
3215 {PTP_OFC_MTP_AbstractMessage,N_("AbstractMessage")},
3216 {PTP_OFC_MTP_UndefinedContact,N_("UndefinedContact")},
3217 {PTP_OFC_MTP_AbstractContact,N_("AbstractContact")},
3218 {PTP_OFC_MTP_vCard2,N_("vCard2")},
3219 {PTP_OFC_MTP_vCard3,N_("vCard3")},
3220 {PTP_OFC_MTP_UndefinedCalendarItem,N_("UndefinedCalendarItem")},
3221 {PTP_OFC_MTP_AbstractCalendarItem,N_("AbstractCalendarItem")},
3222 {PTP_OFC_MTP_vCalendar1,N_("vCalendar1")},
3223 {PTP_OFC_MTP_vCalendar2,N_("vCalendar2")},
3224 {PTP_OFC_MTP_UndefinedWindowsExecutable,N_("Undefined Windows Executable")},
3225};
3226
3227int
3228ptp_render_ofc(PTPParams* params, uint16_t ofc, int spaceleft, char *txt)
3229{
3230 int i;
3231
3232 if (!(ofc & 0x8000)) {
3233 for (i=0;i<sizeof(ptp_ofc_trans)/sizeof(ptp_ofc_trans[0]);i++)
3234 if (ofc == ptp_ofc_trans[i].ofc)
3235 return snprintf(txt, spaceleft,_(ptp_ofc_trans[i].format));
3236 } else {
3237 switch (params->deviceinfo.VendorExtensionID) {
3238 case PTP_VENDOR_EASTMAN_KODAK:
3239 switch (ofc) {
3240 case PTP_OFC_EK_M3U:
3241 return snprintf (txt, spaceleft,_("M3U"));
3242 default:
3243 break;
3244 }
3245 break;
3246 case PTP_VENDOR_MICROSOFT:
3247 for (i=0;i<sizeof(ptp_ofc_mtp_trans)/sizeof(ptp_ofc_mtp_trans[0]);i++)
3248 if (ofc == ptp_ofc_mtp_trans[i].ofc)
3249 return snprintf(txt, spaceleft,_(ptp_ofc_mtp_trans[i].format));
3250 break;
3251 default:break;
3252 }
3253 }
3254 return snprintf (txt, spaceleft,_("Unknown(%04x)"), ofc);
3255}
3256
3257struct {
3258 uint16_t id;
3259 const char *name;
3260} ptp_opc_trans[] = {
3261 {PTP_OPC_StorageID,"StorageID"},
3262 {PTP_OPC_ObjectFormat,"ObjectFormat"},
3263 {PTP_OPC_ProtectionStatus,"ProtectionStatus"},
3264 {PTP_OPC_ObjectSize,"ObjectSize"},
3265 {PTP_OPC_AssociationType,"AssociationType"},
3266 {PTP_OPC_AssociationDesc,"AssociationDesc"},
3267 {PTP_OPC_ObjectFileName,"ObjectFileName"},
3268 {PTP_OPC_DateCreated,"DateCreated"},
3269 {PTP_OPC_DateModified,"DateModified"},
3270 {PTP_OPC_Keywords,"Keywords"},
3271 {PTP_OPC_ParentObject,"ParentObject"},
3272 {PTP_OPC_PersistantUniqueObjectIdentifier,"PersistantUniqueObjectIdentifier"},
3273 {PTP_OPC_SyncID,"SyncID"},
3274 {PTP_OPC_PropertyBag,"PropertyBag"},
3275 {PTP_OPC_Name,"Name"},
3276 {PTP_OPC_CreatedBy,"CreatedBy"},
3277 {PTP_OPC_Artist,"Artist"},
3278 {PTP_OPC_DateAuthored,"DateAuthored"},
3279 {PTP_OPC_Description,"Description"},
3280 {PTP_OPC_URLReference,"URLReference"},
3281 {PTP_OPC_LanguageLocale,"LanguageLocale"},
3282 {PTP_OPC_CopyrightInformation,"CopyrightInformation"},
3283 {PTP_OPC_Source,"Source"},
3284 {PTP_OPC_OriginLocation,"OriginLocation"},
3285 {PTP_OPC_DateAdded,"DateAdded"},
3286 {PTP_OPC_NonConsumable,"NonConsumable"},
3287 {PTP_OPC_CorruptOrUnplayable,"CorruptOrUnplayable"},
3288 {PTP_OPC_RepresentativeSampleFormat,"RepresentativeSampleFormat"},
3289 {PTP_OPC_RepresentativeSampleSize,"RepresentativeSampleSize"},
3290 {PTP_OPC_RepresentativeSampleHeight,"RepresentativeSampleHeight"},
3291 {PTP_OPC_RepresentativeSampleWidth,"RepresentativeSampleWidth"},
3292 {PTP_OPC_RepresentativeSampleDuration,"RepresentativeSampleDuration"},
3293 {PTP_OPC_RepresentativeSampleData,"RepresentativeSampleData"},
3294 {PTP_OPC_Width,"Width"},
3295 {PTP_OPC_Height,"Height"},
3296 {PTP_OPC_Duration,"Duration"},
3297 {PTP_OPC_Rating,"Rating"},
3298 {PTP_OPC_Track,"Track"},
3299 {PTP_OPC_Genre,"Genre"},
3300 {PTP_OPC_Credits,"Credits"},
3301 {PTP_OPC_Lyrics,"Lyrics"},
3302 {PTP_OPC_SubscriptionContentID,"SubscriptionContentID"},
3303 {PTP_OPC_ProducedBy,"ProducedBy"},
3304 {PTP_OPC_UseCount,"UseCount"},
3305 {PTP_OPC_SkipCount,"SkipCount"},
3306 {PTP_OPC_LastAccessed,"LastAccessed"},
3307 {PTP_OPC_ParentalRating,"ParentalRating"},
3308 {PTP_OPC_MetaGenre,"MetaGenre"},
3309 {PTP_OPC_Composer,"Composer"},
3310 {PTP_OPC_EffectiveRating,"EffectiveRating"},
3311 {PTP_OPC_Subtitle,"Subtitle"},
3312 {PTP_OPC_OriginalReleaseDate,"OriginalReleaseDate"},
3313 {PTP_OPC_AlbumName,"AlbumName"},
3314 {PTP_OPC_AlbumArtist,"AlbumArtist"},
3315 {PTP_OPC_Mood,"Mood"},
3316 {PTP_OPC_DRMStatus,"DRMStatus"},
3317 {PTP_OPC_SubDescription,"SubDescription"},
3318 {PTP_OPC_IsCropped,"IsCropped"},
3319 {PTP_OPC_IsColorCorrected,"IsColorCorrected"},
3320 {PTP_OPC_TotalBitRate,"TotalBitRate"},
3321 {PTP_OPC_BitRateType,"BitRateType"},
3322 {PTP_OPC_SampleRate,"SampleRate"},
3323 {PTP_OPC_NumberOfChannels,"NumberOfChannels"},
3324 {PTP_OPC_AudioBitDepth,"AudioBitDepth"},
3325 {PTP_OPC_ScanDepth,"ScanDepth"},
3326 {PTP_OPC_AudioWAVECodec,"AudioWAVECodec"},
3327 {PTP_OPC_AudioBitRate,"AudioBitRate"},
3328 {PTP_OPC_VideoFourCCCodec,"VideoFourCCCodec"},
3329 {PTP_OPC_VideoBitRate,"VideoBitRate"},
3330 {PTP_OPC_FramesPerThousandSeconds,"FramesPerThousandSeconds"},
3331 {PTP_OPC_KeyFrameDistance,"KeyFrameDistance"},
3332 {PTP_OPC_BufferSize,"BufferSize"},
3333 {PTP_OPC_EncodingQuality,"EncodingQuality"},
3334};
3335
3336int
3337ptp_render_mtp_propname(uint16_t propid, int spaceleft, char *txt) {
3338 int i;
3339 for (i=0;i<sizeof(ptp_opc_trans)/sizeof(ptp_opc_trans[0]);i++)
3340 if (propid == ptp_opc_trans[i].id)
3341 return snprintf(txt, spaceleft,ptp_opc_trans[i].name);
3342 return snprintf (txt, spaceleft,"unknown(%04x)", propid);
3343}