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