1 /* usb.c
2 *
3 * Copyright (C) 2001-2004 Mariusz Woloszyn <emsi@ipartners.pl>
4 * Copyright (C) 2003-2016 Marcus Meissner <marcus@jet.franken.de>
5 * Copyright (C) 2003-2017 Marcus Meissner <marcus@jet.franken.de>
6 * Copyright (C) 2006-2007 Linus Walleij <triad@df.lth.se>
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the
20 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301 USA
22 */
23
24 #define _DEFAULT_SOURCE
25 #include <config.h>
26 #include "ptp.h"
27 #include "ptp-private.h"
28 #include "ptp-bugs.h"
29
30 #include <stdlib.h>
31 #include <stdarg.h>
32 #include <stdio.h>
33 #include <string.h>
34
35 #include <gphoto2/gphoto2-library.h>
36 #include <gphoto2/gphoto2-port-log.h>
37 #include <gphoto2/gphoto2-setting.h>
38
39 #ifdef ENABLE_NLS
40 # include <libintl.h>
41 # undef _
42 # define _(String) dgettext (PACKAGE, String)
43 # ifdef gettext_noop
44 # define N_(String) gettext_noop (String)
45 # else
46 # define N_(String) (String)
47 # endif
48 #else
49 # define textdomain(String) (String)
50 # define gettext(String) (String)
51 # define dgettext(Domain,Message) (Message)
52 # define dcgettext(Domain,Message,Type) (Message)
53 # define bindtextdomain(Domain,Directory) (Domain)
54 # define _(String) (String)
55 # define N_(String) (String)
56 #endif
57
58 #define CONTEXT_BLOCK_SIZE 200000
59
60 #define PTP_CNT_INIT(cnt) {memset(&cnt,0,sizeof(cnt));}
61
62 /* PTP2_FAST_TIMEOUT: how long (in milliseconds) we should wait for
63 * an URB to come back on an interrupt endpoint */
64 /* 100 is not enough for various cameras types. 150 seems to work better */
65 #define PTP2_FAST_TIMEOUT 150
66
67 /* Pack / unpack functions */
68
69 #include "ptp-pack.c"
70
71 /* send / receive functions */
72
73 uint16_t
ptp_usb_sendreq(PTPParams * params,PTPContainer * req,int dataphase)74 ptp_usb_sendreq (PTPParams* params, PTPContainer* req, int dataphase)
75 {
76 int res, towrite, do_retry = TRUE;
77 PTPUSBBulkContainer usbreq;
78 Camera *camera = ((PTPData *)params->data)->camera;
79
80 switch (req->Nparam) {
81 default:
82 case 0: GP_LOG_D ("Sending PTP_OC 0x%0x (%s) request...", req->Code, ptp_get_opcode_name(params, req->Code));
83 break;
84 case 1: GP_LOG_D ("Sending PTP_OC 0x%0x (%s) (0x%x) request...", req->Code, ptp_get_opcode_name(params, req->Code), req->Param1);
85 break;
86 case 2: GP_LOG_D ("Sending PTP_OC 0x%0x (%s) (0x%x,0x%x) request...", req->Code, ptp_get_opcode_name(params, req->Code), req->Param1, req->Param2);
87 break;
88 case 3: GP_LOG_D ("Sending PTP_OC 0x%0x (%s) (0x%x,0x%x,0x%x) request...", req->Code, ptp_get_opcode_name(params, req->Code), req->Param1, req->Param2, req->Param3);
89 break;
90 }
91
92 /* build appropriate USB container */
93 usbreq.length=htod32(PTP_USB_BULK_REQ_LEN-
94 (sizeof(uint32_t)*(5-req->Nparam)));
95 usbreq.type=htod16(PTP_USB_CONTAINER_COMMAND);
96 usbreq.code=htod16(req->Code);
97 usbreq.trans_id=htod32(req->Transaction_ID);
98 usbreq.payload.params.param1=htod32(req->Param1);
99 usbreq.payload.params.param2=htod32(req->Param2);
100 usbreq.payload.params.param3=htod32(req->Param3);
101 usbreq.payload.params.param4=htod32(req->Param4);
102 usbreq.payload.params.param5=htod32(req->Param5);
103 /* send it to responder */
104 towrite = PTP_USB_BULK_REQ_LEN-(sizeof(uint32_t)*(5-req->Nparam));
105 retry:
106 res = gp_port_write (camera->port, (char*)&usbreq, towrite);
107 if (res != towrite) {
108 if (res < 0) {
109 GP_LOG_E ("PTP_OC 0x%04x sending req failed: %s (%d)", req->Code, gp_port_result_as_string(res), res);
110 if (res == GP_ERROR_IO_WRITE && do_retry) {
111 GP_LOG_D ("Clearing halt on OUT EP and retrying once.");
112 gp_port_usb_clear_halt (camera->port, GP_PORT_USB_ENDPOINT_OUT);
113 do_retry = FALSE;
114 goto retry;
115 }
116 } else
117 GP_LOG_E ("PTP_OC 0x%04x sending req failed: wrote only %d of %d bytes", req->Code, res, towrite);
118 return translate_gp_result_to_ptp(res);
119 }
120 return PTP_RC_OK;
121 }
122
123 uint16_t
ptp_usb_senddata(PTPParams * params,PTPContainer * ptp,uint64_t size,PTPDataHandler * handler)124 ptp_usb_senddata (PTPParams* params, PTPContainer* ptp,
125 uint64_t size, PTPDataHandler *handler
126 ) {
127 uint16_t ret = PTP_RC_OK;
128 int res, wlen;
129 unsigned long datawlen;
130 PTPUSBBulkContainer usbdata;
131 unsigned long bytes_left_to_transfer, written;
132 Camera *camera = ((PTPData *)params->data)->camera;
133 unsigned char *bytes;
134 int progressid = 0;
135 int usecontext = (size > CONTEXT_BLOCK_SIZE);
136 GPContext *context = ((PTPData *)params->data)->context;
137
138 GP_LOG_D ("Sending PTP_OC 0x%0x (%s) data...", ptp->Code, ptp_get_opcode_name(params, ptp->Code));
139 /* build appropriate USB container */
140 usbdata.length = htod32(PTP_USB_BULK_HDR_LEN+size);
141 usbdata.type = htod16(PTP_USB_CONTAINER_DATA);
142 usbdata.code = htod16(ptp->Code);
143 usbdata.trans_id= htod32(ptp->Transaction_ID);
144
145 if (params->split_header_data) {
146 datawlen = 0;
147 wlen = PTP_USB_BULK_HDR_LEN;
148 } else {
149 unsigned long gotlen;
150 /* For all camera devices. */
151 datawlen = (size<PTP_USB_BULK_PAYLOAD_LEN_WRITE)?size:PTP_USB_BULK_PAYLOAD_LEN_WRITE;
152 wlen = PTP_USB_BULK_HDR_LEN + datawlen;
153 ret = handler->getfunc(params, handler->priv, datawlen, usbdata.payload.data, &gotlen);
154 if (ret != PTP_RC_OK)
155 return ret;
156 if (gotlen != datawlen)
157 return PTP_RC_GeneralError;
158 }
159 res = gp_port_write (camera->port, (char*)&usbdata, wlen);
160 if (res != wlen) {
161 if (res < 0)
162 GP_LOG_E ("PTP_OC 0x%04x sending data failed: %s (%d)", ptp->Code, gp_port_result_as_string(res), res);
163 else
164 GP_LOG_E ("PTP_OC 0x%04x sending data failed: wrote only %d of %d bytes", ptp->Code, res, wlen);
165 return translate_gp_result_to_ptp(res);
166 }
167 if (size <= datawlen) { /* nothing more to do */
168 written = wlen;
169 goto finalize;
170 }
171 if (usecontext)
172 progressid = gp_context_progress_start (context, (size/CONTEXT_BLOCK_SIZE), _("Uploading..."));
173 bytes = malloc (4096);
174 if (!bytes)
175 return PTP_RC_GeneralError;
176 /* if everything OK send the rest */
177 bytes_left_to_transfer = size-datawlen;
178 ret = PTP_RC_OK;
179 written = 0;
180 while(bytes_left_to_transfer > 0) {
181 unsigned long readlen, toread, oldwritten = written;
182
183 toread = 4096;
184 if (toread > bytes_left_to_transfer)
185 toread = bytes_left_to_transfer;
186 ret = handler->getfunc (params, handler->priv, toread, bytes, &readlen);
187 if (ret != PTP_RC_OK)
188 break;
189 res = gp_port_write (camera->port, (char*)bytes, readlen);
190 if (res < 0) {
191 ret = translate_gp_result_to_ptp(res);
192 break;
193 }
194 bytes_left_to_transfer -= res;
195 written += res;
196 if (usecontext && (oldwritten/CONTEXT_BLOCK_SIZE < written/CONTEXT_BLOCK_SIZE))
197 gp_context_progress_update (context, progressid, written/CONTEXT_BLOCK_SIZE);
198 #if 0 /* Does not work this way... Hmm. */
199 if (gp_context_cancel(context) == GP_CONTEXT_FEEDBACK_CANCEL) {
200 ret = ptp_usb_control_cancel_request (params,ptp->Transaction_ID);
201 if (ret == PTP_RC_OK)
202 ret = PTP_ERROR_CANCEL;
203 break;
204 }
205 #endif
206 }
207 if (usecontext)
208 gp_context_progress_stop (context, progressid);
209 free (bytes);
210 finalize:
211 if ((ret == PTP_RC_OK) && ((written % params->maxpacketsize) == 0))
212 gp_port_write (camera->port, "x", 0);
213 if ((ret!=PTP_RC_OK) && (ret!=PTP_ERROR_CANCEL))
214 ret = PTP_ERROR_IO;
215 return ret;
216 }
217
218 static uint16_t
ptp_usb_getpacket(PTPParams * params,PTPUSBBulkContainer * packet,uint32_t maxsize,uint32_t * rlen)219 ptp_usb_getpacket(PTPParams *params, PTPUSBBulkContainer *packet, uint32_t maxsize, uint32_t *rlen)
220 {
221 int tries = 0, result;
222 Camera *camera = ((PTPData *)params->data)->camera;
223
224 /* read the header and potentially the first data */
225 if (params->response_packet_size > 0) {
226 GP_LOG_D ("Returning previously buffered response packet.");
227 /* If there is a buffered packet, just use it. */
228
229 if (params->response_packet_size > maxsize)
230 params->response_packet_size = maxsize;
231
232 memcpy(packet, params->response_packet, params->response_packet_size);
233 *rlen = params->response_packet_size;
234 free(params->response_packet);
235 params->response_packet = NULL;
236 params->response_packet_size = 0;
237 /* Here this signifies a "virtual read" */
238 return PTP_RC_OK;
239 }
240 retry:
241 /* A packet should come in a single read always. */
242 result = gp_port_read (camera->port, (char*)packet, maxsize);
243 /* This might be a left over zero-write of the device at the end of the previous transmission */
244 if (result == 0)
245 result = gp_port_read (camera->port, (char*)packet, maxsize);
246 if (result > 0) {
247 *rlen = result;
248 return PTP_RC_OK;
249 }
250 if (result == GP_ERROR_IO_READ) {
251 GP_LOG_D ("Clearing halt on IN EP and retrying once.");
252 gp_port_usb_clear_halt (camera->port, GP_PORT_USB_ENDPOINT_IN);
253 /* retrying only makes sense if we did not read anything yet */
254 if (tries++ < 1)
255 goto retry;
256 }
257 return translate_gp_result_to_ptp(result);
258 }
259
260 #define READLEN 512*1024 /* read blob size, mostly to avoid reading all of it at once. */
261
262 uint16_t
ptp_usb_getdata(PTPParams * params,PTPContainer * ptp,PTPDataHandler * handler)263 ptp_usb_getdata (PTPParams* params, PTPContainer* ptp, PTPDataHandler *handler)
264 {
265 uint16_t ret;
266 PTPUSBBulkContainer usbdata;
267 unsigned char *data = NULL;
268 uint32_t bytes_to_read, bytes_read;
269 Camera *camera = ((PTPData *)params->data)->camera;
270 int report_progress, progress_id = 0, do_retry = TRUE, res = GP_OK;
271 GPContext *context = ((PTPData *)params->data)->context;
272
273 GP_LOG_D ("Reading PTP_OC 0x%0x (%s) data...", ptp->Code, ptp_get_opcode_name(params, ptp->Code));
274 PTP_CNT_INIT(usbdata);
275
276 ret = ptp_usb_getpacket (params, &usbdata, sizeof(usbdata), &bytes_read);
277 if (ret != PTP_RC_OK)
278 goto exit;
279
280 if (bytes_read < PTP_USB_BULK_HDR_LEN) {
281 GP_LOG_E ("Read short bulk packet in data phase %d vs %d vs min len %d", bytes_read, dtoh32(usbdata.length), (uint32_t)PTP_USB_BULK_HDR_LEN);
282 ret = PTP_ERROR_IO;
283 goto exit;
284 }
285
286 if (dtoh16(usbdata.type) != PTP_USB_CONTAINER_DATA) {
287 /* We might have got a response instead. On error for instance. */
288 if (dtoh16(usbdata.type) == PTP_USB_CONTAINER_RESPONSE) {
289 /* responses are short and we should have it as-is right now */
290 if (bytes_read != dtoh32(usbdata.length)) {
291 GP_LOG_E ("Read broken ptp response in data phase, read %d vs %d", bytes_read, dtoh32(usbdata.length));
292 ret = PTP_ERROR_IO;
293 goto exit;
294 }
295 if (dtoh32(usbdata.length) > sizeof(usbdata)) {
296 GP_LOG_E ("Read too large ptp response in data phase, packet %d bytes large", dtoh32(usbdata.length));
297 ret = PTP_ERROR_IO;
298 goto exit;
299 }
300 /* FIXME: maximum size of response packet perhaps ? */
301 params->response_packet = malloc(dtoh32(usbdata.length));
302 if (!params->response_packet) return PTP_RC_GeneralError;
303 memcpy(params->response_packet, (uint8_t *) &usbdata, dtoh32(usbdata.length));
304 params->response_packet_size = dtoh32(usbdata.length);
305 ret = PTP_RC_OK;
306 } else {
307 ret = PTP_ERROR_DATA_EXPECTED;
308 }
309 goto exit;
310 }
311 if (dtoh16(usbdata.code)!=ptp->Code) {
312 /* A creative Zen device breaks down here, by leaving out
313 * Code and Transaction ID */
314 if (MTP_ZEN_BROKEN_HEADER(params)) {
315 GP_LOG_D ("Read broken PTP header (Code is %04x vs %04x), compensating.",
316 dtoh16(usbdata.code), ptp->Code);
317 usbdata.code = dtoh16(ptp->Code);
318 usbdata.trans_id = htod32(ptp->Transaction_ID);
319 } else {
320 GP_LOG_E ("Read broken PTP header (Code is %04x vs %04x).",
321 dtoh16(usbdata.code), ptp->Code );
322
323 ret = PTP_ERROR_IO;
324
325 /* if this is a valid packet that came late, drain it to allow reestablishing */
326
327 if (bytes_read >= dtoh32(usbdata.length))
328 goto exit;
329
330 bytes_to_read = dtoh32(usbdata.length) - bytes_read;
331 bytes_read -= PTP_USB_BULK_HDR_LEN;
332
333 data = malloc(READLEN);
334 if (!data) goto exit;
335 while (bytes_to_read > 0) {
336 unsigned long chunk_to_read = bytes_to_read;
337
338 /* if in read-until-short-packet mode, read one packet at a time */
339 /* else read in large blobs */
340 /* else read all but the last short packet depending on EP packetsize. */
341 if (chunk_to_read > READLEN)
342 chunk_to_read = READLEN;
343 else if (chunk_to_read > params->maxpacketsize)
344 chunk_to_read = chunk_to_read - (chunk_to_read % params->maxpacketsize);
345 res = gp_port_read (camera->port, (char*)data, chunk_to_read);
346 if (res == GP_ERROR_IO_READ)
347 break;
348 if (res <= 0)
349 break;
350 bytes_to_read -= res;
351 bytes_read += res;
352 }
353 free (data);
354 data = NULL;
355 goto exit;
356 }
357 }
358 if (bytes_read > dtoh32(usbdata.length)) {
359 /*
360 * Buffer the surplus response packet if it is >=
361 * PTP_USB_BULK_HDR_LEN
362 * (i.e. it is probably an entire package)
363 * else discard it as erroneous surplus data.
364 * This will even work if more than 2 packets appear
365 * in the same transaction, they will just be handled
366 * iteratively.
367 *
368 * Marcus observed stray bytes on iRiver devices;
369 * these are still discarded.
370 */
371 uint32_t surplen = bytes_read - dtoh32(usbdata.length);
372
373 if (surplen >= PTP_USB_BULK_HDR_LEN) {
374 params->response_packet = malloc(surplen);
375 if (!params->response_packet) return PTP_RC_GeneralError;
376 memcpy(params->response_packet, (uint8_t *) &usbdata + dtoh32(usbdata.length), surplen);
377 params->response_packet_size = surplen;
378 } else {
379 GP_LOG_D ("Read %ld bytes too much, expect problems!",
380 (long)(bytes_read - dtoh32(usbdata.length)));
381 }
382 bytes_read = dtoh32(usbdata.length);
383 }
384
385 /* For most PTP devices rlen is 512 == sizeof(usbdata)
386 * here. For MTP devices splitting header and data it might
387 * be PTP_USB_BULK_HDR_LEN (12).
388 */
389 /* autodetect split header/data MTP devices */
390 if (dtoh32(usbdata.length) > PTP_USB_BULK_HDR_LEN && (bytes_read==PTP_USB_BULK_HDR_LEN))
391 params->split_header_data = 1;
392
393 /* Copy the payload bytes we already read (with the first usb packet) */
394 ret = handler->putfunc (params, handler->priv, bytes_read - PTP_USB_BULK_HDR_LEN, usbdata.payload.data);
395 if (ret != PTP_RC_OK)
396 goto exit;
397
398 /* Check if we are done already... */
399 if (bytes_read >= dtoh32(usbdata.length))
400 goto exit;
401
402 /* If not read the rest of it. */
403 /* Make bytes_to_read contain the number of remaining payload-bytes to read. */
404 bytes_to_read = dtoh32(usbdata.length) - bytes_read;
405 /* Make bytes_read contain the number of payload-bytes already read. */
406 bytes_read -= PTP_USB_BULK_HDR_LEN;
407
408 data = malloc(READLEN);
409 if (!data) return PTP_RC_GeneralError;
410
411 report_progress = (bytes_to_read > 2*CONTEXT_BLOCK_SIZE) && (dtoh32(usbdata.length) != 0xffffffffU);
412
413 /* On partial reads, do not report progress, this might lead to flickering progress bars.
414 * FIXME: would be better to pass in a flag
415 */
416 if ( (ptp->Code == PTP_OC_GetPartialObject) ||
417 ( (params->deviceinfo.VendorExtensionID == PTP_VENDOR_CANON) &&
418 ( (ptp->Code == PTP_OC_CANON_EOS_GetPartialObject) ||
419 (ptp->Code == PTP_OC_CANON_EOS_GetPartialObject64) ||
420 (ptp->Code == PTP_OC_CANON_EOS_GetPartialObjectEx) ||
421 (ptp->Code == PTP_OC_CANON_EOS_GetPartialObjectEX64)
422 )
423 ) ||
424 (ptp->Code == PTP_OC_ANDROID_GetPartialObject64)
425 )
426 report_progress = 0;
427
428 if (report_progress)
429 progress_id = gp_context_progress_start (context, (bytes_to_read/CONTEXT_BLOCK_SIZE), _("Downloading..."));
430 while (bytes_to_read > 0) {
431 unsigned long chunk_to_read = bytes_to_read;
432
433 /* if in read-until-short-packet mode, read one packet at a time */
434 /* else read in large blobs */
435 /* else read all but the last short packet depending on EP packetsize. */
436 if (dtoh32(usbdata.length) == 0xffffffffU)
437 chunk_to_read = PTP_USB_BULK_HS_MAX_PACKET_LEN_READ;
438 else if (chunk_to_read > READLEN)
439 chunk_to_read = READLEN;
440 else if (chunk_to_read > params->maxpacketsize)
441 chunk_to_read = chunk_to_read - (chunk_to_read % params->maxpacketsize);
442 res = gp_port_read (camera->port, (char*)data, chunk_to_read);
443 if (res == GP_ERROR_IO_READ && do_retry) {
444 GP_LOG_D ("Clearing halt on IN EP and retrying once.");
445 gp_port_usb_clear_halt (camera->port, GP_PORT_USB_ENDPOINT_IN);
446 /* retrying only once and only if we did not read anything yet */
447 do_retry = FALSE;
448 continue;
449 } else if (res <= 0) {
450 ret = translate_gp_result_to_ptp(res);
451 break;
452 } else
453 do_retry = FALSE; /* once we have successfully read any data, don't try again */
454 ret = handler->putfunc (params, handler->priv, res, data);
455 if (ret != PTP_RC_OK)
456 break;
457 if (dtoh32(usbdata.length) == 0xffffffffU) {
458 /* once we have read a short packet, we are done. */
459 if (res < PTP_USB_BULK_HS_MAX_PACKET_LEN_READ)
460 bytes_to_read = 0;
461 } else
462 bytes_to_read -= res;
463 bytes_read += res;
464 if (report_progress && ((bytes_read-res)/CONTEXT_BLOCK_SIZE < bytes_read/CONTEXT_BLOCK_SIZE))
465 gp_context_progress_update (context, progress_id, bytes_read/CONTEXT_BLOCK_SIZE);
466 /* Only cancel transfers larger than 1MB. as
467 * canceling did not work on eos_get_viewfinder of 200kb */
468 if ((bytes_read > 1024*1024) && gp_context_cancel(context) == GP_CONTEXT_FEEDBACK_CANCEL) {
469 ret = PTP_ERROR_CANCEL;
470 break;
471 }
472 }
473 if (report_progress)
474 gp_context_progress_stop (context, progress_id);
475
476 exit:
477 free (data);
478
479 if ((ret!=PTP_RC_OK) && (ret!=PTP_ERROR_CANCEL)) {
480 GP_LOG_E ("PTP_OC 0x%04x receiving data failed: %s (0x%04x)", ptp->Code, ptp_strerror(ret, params->deviceinfo.VendorExtensionID), ret);
481 return PTP_ERROR_IO;
482 }
483 return ret;
484 }
485
486 uint16_t
ptp_usb_getresp(PTPParams * params,PTPContainer * resp)487 ptp_usb_getresp (PTPParams* params, PTPContainer* resp)
488 {
489 uint16_t ret;
490 uint32_t rlen;
491 PTPUSBBulkContainer usbresp;
492 /*GPContext *context = ((PTPData *)params->data)->context;*/
493
494 GP_LOG_D ("Reading PTP_OC 0x%0x (%s) response...", resp->Code, ptp_get_opcode_name(params, resp->Code));
495 PTP_CNT_INIT(usbresp);
496 /* read response, it should never be longer than sizeof(usbresp) */
497 ret = ptp_usb_getpacket(params, &usbresp, sizeof(usbresp), &rlen);
498
499 if (ret!=PTP_RC_OK) {
500 ret = PTP_ERROR_IO;
501 } else
502 if (rlen < 12) {
503 ret = PTP_ERROR_IO;
504 } else
505 if (rlen != dtoh32(usbresp.length)) {
506 ret = PTP_ERROR_IO;
507 } else
508 if (dtoh16(usbresp.type)!=PTP_USB_CONTAINER_RESPONSE) {
509 ret = PTP_ERROR_RESP_EXPECTED;
510 } else
511 if (dtoh16(usbresp.code)!=resp->Code) {
512 ret = dtoh16(usbresp.code);
513 }
514 if (ret!=PTP_RC_OK) {
515 GP_LOG_E ("PTP_OC 0x%04x receiving resp failed: %s (0x%04x)", resp->Code, ptp_strerror(ret, params->deviceinfo.VendorExtensionID), ret);
516 return ret;
517 }
518 /* build an appropriate PTPContainer */
519 resp->Code=dtoh16(usbresp.code);
520 resp->SessionID=params->session_id;
521 resp->Transaction_ID=dtoh32(usbresp.trans_id);
522 if (resp->Transaction_ID != params->transaction_id - 1) {
523 if (MTP_ZEN_BROKEN_HEADER(params)) {
524 GP_LOG_D ("Read broken PTP header (transid is %08x vs %08x), compensating.",
525 resp->Transaction_ID, params->transaction_id - 1
526 );
527 resp->Transaction_ID=params->transaction_id-1;
528 }
529 /* else will be handled by ptp.c as error. */
530 }
531 resp->Nparam=(rlen-12)/4;
532 resp->Param1=dtoh32(usbresp.payload.params.param1);
533 resp->Param2=dtoh32(usbresp.payload.params.param2);
534 resp->Param3=dtoh32(usbresp.payload.params.param3);
535 resp->Param4=dtoh32(usbresp.payload.params.param4);
536 resp->Param5=dtoh32(usbresp.payload.params.param5);
537 return ret;
538 }
539
540 /* Event handling functions */
541
542 /* PTP Events wait for or check mode */
543 #define PTP_EVENT_CHECK 0x0000 /* waits for */
544 #define PTP_EVENT_CHECK_FAST 0x0001 /* checks */
545 #define PTP_EVENT_CHECK_QUEUE 0x0002 /* just looks in the queue */
546
547 static inline uint16_t
ptp_usb_event(PTPParams * params,PTPContainer * event,int wait)548 ptp_usb_event (PTPParams* params, PTPContainer* event, int wait)
549 {
550 int result, timeout, fasttimeout;
551 unsigned long rlen;
552 PTPUSBEventContainer usbevent;
553 Camera *camera = ((PTPData *)params->data)->camera;
554
555 if (params->deviceinfo.VendorExtensionID == PTP_VENDOR_CANON)
556 fasttimeout = PTP2_FAST_TIMEOUT*2;
557 else
558 fasttimeout = PTP2_FAST_TIMEOUT;
559
560 PTP_CNT_INIT(usbevent);
561
562 if (event==NULL)
563 return PTP_ERROR_BADPARAM;
564
565 switch(wait) {
566 case PTP_EVENT_CHECK:
567 result = gp_port_check_int (camera->port, (char*)&usbevent, sizeof(usbevent));
568 if (result <= 0) result = gp_port_check_int (camera->port, (char*)&usbevent, sizeof(usbevent));
569 break;
570 case PTP_EVENT_CHECK_FAST:
571 gp_port_get_timeout (camera->port, &timeout);
572 gp_port_set_timeout (camera->port, fasttimeout);
573 result = gp_port_check_int (camera->port, (char*)&usbevent, sizeof(usbevent));
574 if (result <= 0) result = gp_port_check_int (camera->port, (char*)&usbevent, sizeof(usbevent));
575 gp_port_set_timeout (camera->port, timeout);
576 break;
577 case PTP_EVENT_CHECK_QUEUE:
578 gp_port_get_timeout (camera->port, &timeout);
579 gp_port_set_timeout (camera->port, 0); /* indicates no waiting at all */
580 result = gp_port_check_int (camera->port, (char*)&usbevent, sizeof(usbevent));
581 gp_port_set_timeout (camera->port, timeout);
582 break;
583 default:
584 return PTP_ERROR_BADPARAM;
585 }
586 if (result < 0) {
587 if ((result != GP_ERROR_TIMEOUT) || (wait != PTP_EVENT_CHECK_FAST))
588 GP_LOG_E ("Reading PTP event failed: %s (%d)", gp_port_result_as_string(result), result);
589 return translate_gp_result_to_ptp(result);
590 }
591 if (result == 0) {
592 GP_LOG_E ("Reading PTP event failed: a 0 read occurred, assuming timeout.");
593 return PTP_ERROR_TIMEOUT;
594 }
595 rlen = result;
596 if (rlen < 8) {
597 GP_LOG_E ("Reading PTP event failed: only %ld bytes read", rlen);
598 return PTP_ERROR_IO;
599 }
600
601 /* Only do the additional reads for "events". Canon IXUS 2 likes to
602 * send unrelated data.
603 */
604 if ( (dtoh16(usbevent.type) == PTP_USB_CONTAINER_EVENT) &&
605 (dtoh32(usbevent.length) > rlen)
606 ) {
607 GP_LOG_D ("Canon incremental read (done: %ld, todo: %d)", rlen, dtoh32(usbevent.length));
608 gp_port_get_timeout (camera->port, &timeout);
609 gp_port_set_timeout (camera->port, PTP2_FAST_TIMEOUT);
610 while (dtoh32(usbevent.length) > rlen) {
611 result = gp_port_check_int (camera->port, ((char*)&usbevent)+rlen, sizeof(usbevent)-rlen);
612 if (result <= 0)
613 break;
614 rlen += result;
615 }
616 gp_port_set_timeout (camera->port, timeout);
617 }
618 /* if we read anything over interrupt endpoint it must be an event */
619 /* build an appropriate PTPContainer */
620 event->Nparam = (rlen-12)/4;
621 event->Code = dtoh16(usbevent.code);
622 event->SessionID=params->session_id;
623 event->Transaction_ID=dtoh32(usbevent.trans_id);
624 event->Param1 = dtoh32(usbevent.param1);
625 event->Param2 = dtoh32(usbevent.param2);
626 event->Param3 = dtoh32(usbevent.param3);
627 return PTP_RC_OK;
628 }
629
630 uint16_t
ptp_usb_event_check_queue(PTPParams * params,PTPContainer * event)631 ptp_usb_event_check_queue (PTPParams* params, PTPContainer* event) {
632
633 return ptp_usb_event (params, event, PTP_EVENT_CHECK_QUEUE);
634 }
635
636 uint16_t
ptp_usb_event_check(PTPParams * params,PTPContainer * event)637 ptp_usb_event_check (PTPParams* params, PTPContainer* event) {
638
639 return ptp_usb_event (params, event, PTP_EVENT_CHECK_FAST);
640 }
641
642 uint16_t
ptp_usb_event_wait(PTPParams * params,PTPContainer * event)643 ptp_usb_event_wait (PTPParams* params, PTPContainer* event) {
644
645 return ptp_usb_event (params, event, PTP_EVENT_CHECK);
646 }
647
648 uint16_t
ptp_usb_control_get_extended_event_data(PTPParams * params,char * buffer,int * size)649 ptp_usb_control_get_extended_event_data (PTPParams *params, char *buffer, int *size) {
650 Camera *camera = ((PTPData *)params->data)->camera;
651 int ret;
652
653 GP_LOG_D ("Getting extended event data.");
654 ret = gp_port_usb_msg_class_read (camera->port, 0x65, 0x0000, 0x0000, buffer, *size);
655 if (ret < GP_OK)
656 return PTP_ERROR_IO;
657 *size = ret;
658 return PTP_RC_OK;
659 }
660
661 uint16_t
ptp_usb_control_device_reset_request(PTPParams * params)662 ptp_usb_control_device_reset_request (PTPParams *params) {
663 Camera *camera = ((PTPData *)params->data)->camera;
664 int ret;
665
666 GP_LOG_D ("Sending usb device reset request.");
667 ret = gp_port_usb_msg_class_write (camera->port, 0x66, 0x0000, 0x0000, NULL, 0);
668 if (ret < GP_OK)
669 return PTP_ERROR_IO;
670 return PTP_RC_OK;
671 }
672
673 uint16_t
ptp_usb_control_get_device_status(PTPParams * params,char * buffer,int * size)674 ptp_usb_control_get_device_status (PTPParams *params, char *buffer, int *size) {
675 Camera *camera = ((PTPData *)params->data)->camera;
676 int ret;
677
678 ret = gp_port_usb_msg_class_read (camera->port, 0x67, 0x0000, 0x0000, buffer, *size);
679 if (ret < GP_OK)
680 return PTP_ERROR_IO;
681 *size = ret;
682 return PTP_RC_OK;
683 }
684
685 uint16_t
ptp_usb_control_cancel_request(PTPParams * params,uint32_t transactionid)686 ptp_usb_control_cancel_request (PTPParams *params, uint32_t transactionid) {
687 Camera *camera = ((PTPData *)params->data)->camera;
688 int ret;
689 unsigned char buffer[6];
690
691 htod16a(&buffer[0],PTP_EC_CancelTransaction);
692 htod32a(&buffer[2],transactionid);
693 ret = gp_port_usb_msg_class_write (camera->port, 0x64, 0x0000, 0x0000, (char*)buffer, sizeof (buffer));
694 if (ret < GP_OK)
695 return PTP_ERROR_IO;
696 return PTP_RC_OK;
697 }
698