1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2 /** \file
3  *
4  * \author Copyright 2001 Lutz Mueller <lutz@users.sf.net>
5  * \author Copyright 1999 Scott Fritzinger <scottf@unr.edu>
6  *
7  * \par License
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  * \par
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * \par
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with this library; if not, write to the
22  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23  * Boston, MA  02110-1301  USA
24  */
25 
26 #define _DEFAULT_SOURCE
27 
28 #include "config.h"
29 
30 #include <stdarg.h>
31 #include <stdlib.h>
32 #include <stdio.h>
33 #include <string.h>
34 
35 #include <ltdl.h>
36 
37 #include <gphoto2/gphoto2-port-result.h>
38 #include <gphoto2/gphoto2-port-library.h>
39 #include <gphoto2/gphoto2-port-log.h>
40 
41 #include "gphoto2-port-info.h"
42 
43 #ifdef ENABLE_NLS
44 #  include <libintl.h>
45 #  undef _
46 #  define _(String) dgettext (GETTEXT_PACKAGE, String)
47 #  ifdef gettext_noop
48 #      define N_(String) gettext_noop (String)
49 #  else
50 #      define N_(String) (String)
51 #  endif
52 #else
53 #  define _(String) (String)
54 #  define N_(String) (String)
55 #  define ngettext(String1,String2,Count) ((Count==1)?String1:String2)
56 #endif
57 
58 #define CHECK_RESULT(result) {int r=(result); if (r<0) return (r);}
59 #define CHECK_SUPP(p,t,o) {if (!(o)) {gp_port_set_error ((p), _("The operation '%s' is not supported by this device"), (t)); return (GP_ERROR_NOT_SUPPORTED);}}
60 #define CHECK_INIT(p) {if (!(p)->pc->ops) {gp_port_set_error ((p), _("The port has not yet been initialized")); return (GP_ERROR_BAD_PARAMETERS);}}
61 
62 #define LOG_DATA(DATA, SIZE, EXPECTED, MSG_PRE, MSG_POST, ...) \
63 	if (SIZE != EXPECTED) \
64 		GP_LOG_DATA (DATA, SIZE, MSG_PRE " %i = 0x%x out of %i bytes " MSG_POST, SIZE, SIZE, EXPECTED, ##__VA_ARGS__); \
65 	else \
66 		GP_LOG_DATA (DATA, SIZE, MSG_PRE " %i = 0x%x bytes " MSG_POST, SIZE, SIZE, ##__VA_ARGS__)
67 
68 
69 /**
70  * \brief Internal private libgphoto2_port data.
71  * This structure contains private data.
72  **/
73 struct _GPPortPrivateCore {
74 	char error[2048];	/**< Internal kept error message. */
75 
76 	struct _GPPortInfo info;	/**< Internal port information of this port. */
77 	GPPortOperations *ops;	/**< Internal port operations. */
78 	lt_dlhandle lh;		/**< Internal libtool library handle. */
79 };
80 
81 /**
82  * \brief Create new GPPort
83  *
84  * Allocate and initialize the memory for a new #GPPort.
85  *
86  * After you called this function,
87  * you probably want to call #gp_port_set_info in order to make the newly
88  * created port functional.
89  *
90  * \param port Pointer the #GPPort* pointer
91  * \return a gphoto2 error code
92  **/
93 int
gp_port_new(GPPort ** port)94 gp_port_new (GPPort **port)
95 {
96 	C_PARAMS (port);
97 
98         GP_LOG_D ("Creating new device...");
99 
100 	C_MEM (*port = calloc (1, sizeof (GPPort)));
101 
102 	(*port)->pc = calloc (1, sizeof (GPPortPrivateCore));
103 	if (!(*port)->pc) {
104 		gp_port_free (*port);
105 		return (GP_ERROR_NO_MEMORY);
106 	}
107 
108         return (GP_OK);
109 }
110 
111 static int
gp_port_init(GPPort * port)112 gp_port_init (GPPort *port)
113 {
114 	C_PARAMS (port);
115 	CHECK_INIT (port);
116 
117 	if (port->pc->ops->init)
118 		CHECK_RESULT (port->pc->ops->init (port));
119 
120 	return (GP_OK);
121 }
122 
123 static int
gp_port_exit(GPPort * port)124 gp_port_exit (GPPort *port)
125 {
126 	C_PARAMS (port);
127 	CHECK_INIT (port);
128 
129 	if (port->pc->ops->exit)
130 		CHECK_RESULT (port->pc->ops->exit (port));
131 
132 	return (GP_OK);
133 }
134 
135 /**
136  * \brief Configure a port
137  *
138  * Makes a port functional by passing in the necessary path
139  * information (from the serial:/dev/ttyS0 or similar variables).
140  * After calling this function, you can access the port using for
141  * example gp_port_open().
142  *
143  * \param port a GPPort
144  * \param info the GPPortInfo to set
145  *
146  * \return a gphoto2 error code
147  **/
148 int
gp_port_set_info(GPPort * port,GPPortInfo info)149 gp_port_set_info (GPPort *port, GPPortInfo info)
150 {
151 	int ret;
152 
153 	GPPortLibraryOperations ops_func;
154 
155 	C_PARAMS (port);
156 
157 	free (port->pc->info.name);
158 	C_MEM (port->pc->info.name = strdup (info->name));
159 	free (port->pc->info.path);
160 	C_MEM (port->pc->info.path = strdup (info->path));
161 	port->pc->info.type = info->type;
162 	free (port->pc->info.library_filename);
163 	C_MEM (port->pc->info.library_filename = strdup (info->library_filename));
164 
165 	port->type = info->type;
166 
167 	/* Clean up */
168 	if (port->pc->ops) {
169 		gp_port_exit (port);
170 		free (port->pc->ops);
171 		port->pc->ops = NULL;
172 	}
173 	if (port->pc->lh) {
174 #if !defined(VALGRIND)
175 		lt_dlclose (port->pc->lh);
176 		lt_dlexit ();
177 #endif
178 	}
179 
180 	lt_dlinit ();
181 	port->pc->lh = lt_dlopenext (info->library_filename);
182 	if (!port->pc->lh) {
183 		GP_LOG_E ("Could not load '%s' ('%s').", info->library_filename, lt_dlerror ());
184 		lt_dlexit ();
185 		return (GP_ERROR_LIBRARY);
186 	}
187 
188 	/* Load the operations */
189 	ops_func = lt_dlsym (port->pc->lh, "gp_port_library_operations");
190 	if (!ops_func) {
191 		GP_LOG_E ("Could not find 'gp_port_library_operations' in '%s' ('%s')",
192 			  info->library_filename, lt_dlerror ());
193 		lt_dlclose (port->pc->lh);
194 		lt_dlexit ();
195 		port->pc->lh = NULL;
196 		return (GP_ERROR_LIBRARY);
197 	}
198 	port->pc->ops = ops_func ();
199 	gp_port_init (port);
200 
201 	/* Initialize the settings to some default ones */
202 	switch (info->type) {
203 	case GP_PORT_SERIAL:
204 		port->settings.serial.speed = 0;
205 		port->settings.serial.bits = 8;
206 		port->settings.serial.parity = 0;
207 		port->settings.serial.stopbits = 1;
208 		gp_port_set_timeout (port, 500);
209 		break;
210 	case GP_PORT_USB:
211 		if (sizeof (port->settings.usb.port) <= strlen(info->path)) {
212 			GP_LOG_E ("Path is too long for static buffer '%s'.", info->path);
213 			return GP_ERROR_LIBRARY;
214 		}
215 		strncpy (port->settings.usb.port, info->path,
216 			 sizeof (port->settings.usb.port));
217 		port->settings.usb.inep = -1;
218 		port->settings.usb.outep = -1;
219 		port->settings.usb.config = -1;
220 		port->settings.usb.interface = 0;
221 		port->settings.usb.altsetting = -1;
222 		gp_port_set_timeout (port, 5000);
223 		break;
224 	case GP_PORT_USB_DISK_DIRECT:
225 		snprintf(port->settings.usbdiskdirect.path,
226 			 sizeof(port->settings.usbdiskdirect.path), "%s",
227 			 strchr(info->path, ':') + 1);
228 		break;
229 	case GP_PORT_USB_SCSI:
230 		snprintf(port->settings.usbscsi.path,
231 			 sizeof(port->settings.usbscsi.path), "%s",
232 			 strchr(info->path, ':') + 1);
233 		break;
234 	default:
235 		/* Nothing in here */
236 		break;
237 	}
238 	ret = gp_port_set_settings (port, port->settings);
239 	if (ret != GP_ERROR_NOT_SUPPORTED)
240 		CHECK_RESULT (ret);
241 
242 	return GP_OK;
243 }
244 
245 /**
246  * \brief Retreives information about the port.
247  *
248  * Retrieves the informations set by gp_port_set_info().
249  *
250  * \param port a GPPort
251  * \param info GPPortInfo
252  * \return a gphoto2 error code
253  **/
254 int
gp_port_get_info(GPPort * port,GPPortInfo * info)255 gp_port_get_info (GPPort *port, GPPortInfo *info)
256 {
257 	C_PARAMS (port && info);
258 
259 	*info = &port->pc->info;
260 	return (GP_OK);
261 }
262 
263 /**
264  * \brief Open a port.
265  * \param port a #GPPort
266  *
267  * Opens a port which should have been created with #gp_port_new and
268  * configured with #gp_port_set_info and #gp_port_set_settings
269  *
270  * \return a gphoto2 error code
271  **/
272 int
gp_port_open(GPPort * port)273 gp_port_open (GPPort *port)
274 {
275 	C_PARAMS (port);
276 	CHECK_INIT (port);
277 
278 	GP_LOG_D ("Opening %s port...",
279 		  port->type == GP_PORT_SERIAL ? "SERIAL" : (port->type == GP_PORT_USB ? "USB" : ""));
280 
281 	CHECK_SUPP (port, "open", port->pc->ops->open);
282 	CHECK_RESULT (port->pc->ops->open (port));
283 
284 	return GP_OK;
285 }
286 
287 /**
288  * \brief Close a port.
289  * \param port a #GPPort
290  *
291  * Closes a port temporarily. It can afterwards be reopened using
292  * #gp_port_open.
293  *
294  * \return a gphoto2 error code
295  **/
296 int
gp_port_close(GPPort * port)297 gp_port_close (GPPort *port)
298 {
299 	GP_LOG_D ("Closing port...");
300 
301 	C_PARAMS (port);
302 	CHECK_INIT (port);
303 
304 	CHECK_SUPP (port, "close", port->pc->ops->close);
305         CHECK_RESULT (port->pc->ops->close(port));
306 
307 	return (GP_OK);
308 }
309 
310 /**
311  * \brief Reset a port.
312  * \param port a #GPPort
313  *
314  * Resets a port. Device will likely reconnect and appear under a new id.
315  *
316  * \return a gphoto2 error code
317  **/
318 int
gp_port_reset(GPPort * port)319 gp_port_reset (GPPort *port)
320 {
321 	GP_LOG_D ("Resetting port...");
322 
323 	C_PARAMS (port);
324 	CHECK_INIT (port);
325 
326 	CHECK_SUPP (port, "reset", port->pc->ops->reset);
327         CHECK_RESULT (port->pc->ops->reset(port));
328 
329 	return (GP_OK);
330 }
331 
332 /**
333  * \brief Free the port structure
334  * \param port a #GPPort
335  *
336  * Closes the port and frees the memory.
337  *
338  * \return a gphoto2 error code
339  **/
340 int
gp_port_free(GPPort * port)341 gp_port_free (GPPort *port)
342 {
343 	GP_LOG_D ("Freeing port...");
344 
345 	C_PARAMS (port);
346 
347 	if (port->pc) {
348 		if (port->pc->ops) {
349 
350 			/* We don't care for return values */
351 			gp_port_close (port);
352 			gp_port_exit (port);
353 
354 			free (port->pc->ops);
355 			port->pc->ops = NULL;
356 		}
357 
358 		if (port->pc->lh) {
359 #if !defined(VALGRIND)
360 			lt_dlclose (port->pc->lh);
361 			lt_dlexit ();
362 #endif
363 			port->pc->lh = NULL;
364 		}
365 
366 		free (port->pc->info.name);
367 		free (port->pc->info.path);
368 		free (port->pc->info.library_filename);
369 
370 		free (port->pc);
371 		port->pc = NULL;
372 	}
373 
374         free (port);
375 
376         return GP_OK;
377 }
378 
379 /**
380  * \brief Writes a specified amount of data to a port.
381 
382  * \param port a #GPPort
383  * \param data the data to write to the port
384  * \param size the number of bytes to write to the port
385  *
386  * Writes data to the port. On non-serial ports the amount of data
387  * written is returned (and not just GP_OK).
388  *
389  * \return a negative gphoto2 error code or the amount of data written.
390  **/
391 int
gp_port_write(GPPort * port,const char * data,int size)392 gp_port_write (GPPort *port, const char *data, int size)
393 {
394 	int retval;
395 
396         gp_log (GP_LOG_DATA, __func__, "Writing %i = 0x%x bytes to port...", size, size);
397 
398  	C_PARAMS (port && data);
399 	CHECK_INIT (port);
400 
401 	/* Check if we wrote all bytes */
402 	CHECK_SUPP (port, "write", port->pc->ops->write);
403 	retval = port->pc->ops->write (port, data, size);
404 	if (retval < 0) {
405 		GP_LOG_E ("Writing %i = 0x%x bytes to port failed: %s (%d)",
406 			  size, size, gp_port_result_as_string(retval), retval);
407 		return retval;
408 	}
409 	LOG_DATA (data, retval, size, "Wrote  ", "to port:");
410 
411 	return (retval);
412 }
413 
414 /**
415  * \brief Read data from port
416  *
417  * \param port a #GPPort
418  * \param data a pointer to an allocated buffer
419  * \param size the number of bytes that should be read
420  *
421  * Reads a specified number of bytes from the port into the supplied buffer.
422  * It returns the number of bytes read or a negative error code.
423  *
424  * \return a gphoto2 error code or the amount of data read
425  **/
426 int
gp_port_read(GPPort * port,char * data,int size)427 gp_port_read (GPPort *port, char *data, int size)
428 {
429         int retval;
430 
431 	gp_log (GP_LOG_DATA, __func__, "Reading %i = 0x%x bytes from port...", size, size);
432 
433 	C_PARAMS (port);
434 	CHECK_INIT (port);
435 
436 	/* Check if we read as many bytes as expected */
437 	CHECK_SUPP (port, "read", port->pc->ops->read);
438 	retval = port->pc->ops->read (port, data, size);
439 	if (retval < 0) {
440 		GP_LOG_E ("Reading %i = 0x%x bytes from port failed: %s (%d)",
441 			  size, size, gp_port_result_as_string(retval), retval);
442 		return retval;
443 	}
444 	LOG_DATA (data, retval, size, "Read   ", "from port:");
445 
446 	return (retval);
447 }
448 
449 /**
450  * \brief Check for intterupt.
451  *
452  * \param port a GPPort
453  * \param data a pointer to an allocated buffer
454  * \param size the number of bytes that should be read
455  *
456  * Reads a specified number of bytes from the interrupt endpoint
457  * into the supplied buffer.
458  * Function waits port->timeout miliseconds for data on interrupt endpoint.
459  *
460  * \return a gphoto2 error code
461  **/
462 int
gp_port_check_int(GPPort * port,char * data,int size)463 gp_port_check_int (GPPort *port, char *data, int size)
464 {
465         int retval;
466 
467 	gp_log (GP_LOG_DATA, __func__, "Reading %i = 0x%x bytes from interrupt endpoint...", size, size);
468 
469 	C_PARAMS (port);
470 	CHECK_INIT (port);
471 
472 	/* Check if we read as many bytes as expected */
473 	CHECK_SUPP (port, "check_int", port->pc->ops->check_int);
474 	retval = port->pc->ops->check_int (port, data, size, port->timeout);
475 	CHECK_RESULT (retval);
476 	LOG_DATA (data, retval, size, "Read   ", "from interrupt endpoint:");
477 
478 	return (retval);
479 }
480 
481 /** The timeout in milliseconds for fast interrupt reads. */
482 #define FAST_TIMEOUT	50
483 /**
484  * \brief Check for interrupt without wait
485  * \param port a GPPort
486  * \param data a pointer to an allocated buffer
487  * \param size the number of bytes that should be read
488  *
489  * Reads a specified number of bytes from the inerrupt endpoint
490  * into the supplied buffer.
491  * Function waits 50 miliseconds for data on interrupt endpoint.
492  *
493  * \return a gphoto2 error code
494  **/
495 int
gp_port_check_int_fast(GPPort * port,char * data,int size)496 gp_port_check_int_fast (GPPort *port, char *data, int size)
497 {
498         int retval;
499 
500         gp_log (GP_LOG_DATA, __func__, "Reading %i = 0x%x bytes from interrupt endpoint...", size, size);
501 
502 	C_PARAMS (port);
503 	CHECK_INIT (port);
504 
505 	/* Check if we read as many bytes as expected */
506 	CHECK_SUPP (port, "check_int", port->pc->ops->check_int);
507 	retval = port->pc->ops->check_int (port, data, size, FAST_TIMEOUT);
508 	CHECK_RESULT (retval);
509 
510 #ifdef IGNORE_EMPTY_INTR_READS
511 	/* For Canon cameras, we will make lots of
512 	   reads that will return zero length. Don't
513 	   bother to log them as errors. */
514 	if (retval != 0 )
515 #endif
516 		LOG_DATA (data, retval, size, "Read   ", "from interrupt endpoint (fast):");
517 
518 	return (retval);
519 }
520 
521 
522 /**
523  * \brief Set timeout of port
524  * \param port a #GPPort
525  * \param timeout the timeout
526  *
527  * Sets the timeout of a port. #gp_port_read will wait timeout milliseconds
528  * for data. If no data will be received in that period, %GP_ERROR_TIMEOUT
529  * will be returned.
530  *
531  * \return a gphoto2 error code
532  **/
533 int
gp_port_set_timeout(GPPort * port,int timeout)534 gp_port_set_timeout (GPPort *port, int timeout)
535 {
536 	C_PARAMS (port);
537 
538         GP_LOG_D ("Setting port timeout to %i milliseconds.", timeout);
539         port->timeout = timeout;
540 
541         return GP_OK;
542 }
543 
544 /** Deprecated */
545 int gp_port_timeout_set (GPPort *, int);
gp_port_timeout_set(GPPort * port,int timeout)546 int gp_port_timeout_set (GPPort *port, int timeout)
547 {
548 	return (gp_port_set_timeout (port, timeout));
549 }
550 
551 /** Deprecated */
552 int gp_port_timeout_get (GPPort *, int *);
gp_port_timeout_get(GPPort * port,int * timeout)553 int gp_port_timeout_get (GPPort *port, int *timeout)
554 {
555 	return (gp_port_get_timeout (port, timeout));
556 }
557 
558 /**
559  * \brief Get the current port timeout.
560  * \param port a #GPPort
561  * \param timeout pointer to timeout
562  *
563  * Retreives the current timeout of the port.
564  *
565  * \return a gphoto2 error code
566  **/
567 int
gp_port_get_timeout(GPPort * port,int * timeout)568 gp_port_get_timeout (GPPort *port, int *timeout)
569 {
570 	C_PARAMS (port);
571 
572 	GP_LOG_D ("Current port timeout is %i milliseconds.", port->timeout);
573         *timeout = port->timeout;
574 
575         return GP_OK;
576 }
577 
578 /**
579  * \brief Set port settings
580  * \param port a #GPPort
581  * \param settings the #GPPortSettings to be set
582  *
583  * Adjusts the settings of a port. You should always call
584  * #gp_port_get_settings, adjust the values depending on the type of the port,
585  * and then call #gp_port_set_settings.
586  *
587  * \return a gphoto2 error code
588  **/
589 int
gp_port_set_settings(GPPort * port,GPPortSettings settings)590 gp_port_set_settings (GPPort *port, GPPortSettings settings)
591 {
592 	GP_LOG_D ("Setting settings...");
593 
594 	C_PARAMS (port);
595 	CHECK_INIT (port);
596 
597         /*
598 	 * We copy the settings to settings_pending and call update on the
599 	 * port.
600 	 */
601         memcpy (&port->settings_pending, &settings,
602 		sizeof (port->settings_pending));
603 	CHECK_SUPP (port, "update", port->pc->ops->update);
604         CHECK_RESULT (port->pc->ops->update (port));
605 
606         return (GP_OK);
607 }
608 
609 /** Deprecated */
610 int gp_port_settings_get (GPPort *, GPPortSettings *);
gp_port_settings_get(GPPort * port,GPPortSettings * settings)611 int gp_port_settings_get (GPPort *port, GPPortSettings *settings)
612 {
613 	return (gp_port_get_settings (port, settings));
614 }
615 /** Deprecated */
616 int gp_port_settings_set (GPPort *, GPPortSettings);
gp_port_settings_set(GPPort * port,GPPortSettings settings)617 int gp_port_settings_set (GPPort *port, GPPortSettings settings)
618 {
619 	return (gp_port_set_settings (port, settings));
620 }
621 
622 /**
623  * \brief Get the current port settings.
624  * \param port a #GPPort
625  * \param settings pointer to the retrieved settings
626  *
627  * Retreives the current settings of a port.
628  *
629  * \return a gphoto2 error code
630  **/
631 int
gp_port_get_settings(GPPort * port,GPPortSettings * settings)632 gp_port_get_settings (GPPort *port, GPPortSettings *settings)
633 {
634 	C_PARAMS (port);
635 
636         memcpy (settings, &(port->settings), sizeof (gp_port_settings));
637 
638         return GP_OK;
639 }
640 
641 /**
642  * \brief Get setting of specific serial PIN
643  *
644  * \param port a GPPort
645  * \param pin the serial pin to be retrieved
646  * \param level the setting of the pin
647  *
648  * \return a gphoto2 error code
649  */
650 int
gp_port_get_pin(GPPort * port,GPPin pin,GPLevel * level)651 gp_port_get_pin (GPPort *port, GPPin pin, GPLevel *level)
652 {
653 	GP_LOG_D ("Getting level of pin %i...", pin);
654 
655 	C_PARAMS (port && level);
656 	CHECK_INIT (port);
657 
658 	CHECK_SUPP (port, "get_pin", port->pc->ops->get_pin);
659         CHECK_RESULT (port->pc->ops->get_pin (port, pin, level));
660 
661 	GP_LOG_D ("Level of pin %i: %i", pin, *level);
662 
663 	return (GP_OK);
664 }
665 
666 static struct {
667 	GPPin pin;
668 	unsigned char number;
669 	const char *description_short;
670 	const char *description_long;
671 } PinTable[] = {
672 	/* we do not translate these technical terms ... for now */
673 	{GP_PIN_RTS , 7, "RTS" , "Request To Send"    },
674 	{GP_PIN_DTR , 4, "DTR" , "Data Terminal Ready"},
675 	{GP_PIN_CTS , 8, "CTS" , "Clear To Send"      },
676 	{GP_PIN_DSR , 6, "DSR" , "Data Set Ready"     },
677 	{GP_PIN_CD  , 1, "CD"  , "Carrier Detect"     },
678 	{GP_PIN_RING, 9, "RING", "Ring Indicator"     },
679 	{0, 0, NULL, NULL}
680 };
681 
682 static struct {
683 	GPLevel level;
684 	const char *description;
685 } LevelTable[] = {
686 	{GP_LEVEL_LOW, N_("low")},
687 	{GP_LEVEL_HIGH, N_("high")},
688 	{0, NULL}
689 };
690 
691 /**
692  * \brief Set specified serial PIN to value
693  *
694  * \param port a GPPort
695  * \param pin the serial pin to be retrieved
696  * \param level the setting of the pin
697  *
698  * Pulls the specified pin of a serial port to the specified level.
699  *
700  * \return a gphoto2 error code
701  */
702 int
gp_port_set_pin(GPPort * port,GPPin pin,GPLevel level)703 gp_port_set_pin (GPPort *port, GPPin pin, GPLevel level)
704 {
705 	unsigned int i, j;
706 
707 	for (i = 0; PinTable[i].description_short; i++)
708 		if (PinTable[i].pin == pin)
709 			break;
710 	for (j = 0; LevelTable[j].description; j++)
711 		if (LevelTable[j].level == level)
712 			break;
713 	GP_LOG_D ("Setting pin %i (%s: '%s') to '%s'...",
714 		PinTable[i].number, PinTable[i].description_short,
715 		PinTable[i].description_long, _(LevelTable[j].description));
716 
717 	C_PARAMS (port);
718 	CHECK_INIT (port);
719 
720 	CHECK_SUPP (port, "set_pin", port->pc->ops->set_pin);
721 	CHECK_RESULT (port->pc->ops->set_pin (port, pin, level));
722 
723 	return (GP_OK);
724 }
725 
726 /**
727  * \brief Send a break over a serial port
728  *
729  * \param port a GPPort
730  * \param duration duration of break in milliseconds
731  *
732  * Sends a break with the specified duration in milliseconds.
733  *
734  * \return a gphoto2 error code
735  */
736 int
gp_port_send_break(GPPort * port,int duration)737 gp_port_send_break (GPPort *port, int duration)
738 {
739 	GP_LOG_D ("Sending break (%i milliseconds)...", duration);
740 
741 	C_PARAMS (port);
742 	CHECK_INIT (port);
743 
744         CHECK_SUPP (port, "send_break", port->pc->ops->send_break);
745         CHECK_RESULT (port->pc->ops->send_break (port, duration));
746 
747 	return (GP_OK);
748 }
749 
750 /**
751  * \brief Flush data on serial port
752  *
753  * \param port a GPPort
754  * \param direction the direction of the flush
755  *
756  * Flushes the serial output or input (depending on direction)
757  * of the serial port.
758  *
759  * \return a gphoto2 error code
760  */
761 int
gp_port_flush(GPPort * port,int direction)762 gp_port_flush (GPPort *port, int direction)
763 {
764 	GP_LOG_D ("Flushing port...");
765 
766 	C_PARAMS (port);
767 
768 	CHECK_SUPP (port, "flush", port->pc->ops->flush);
769 	CHECK_RESULT (port->pc->ops->flush (port, direction));
770 
771         return (GP_OK);
772 }
773 
774 
775 /* USB-specific functions */
776 /* ------------------------------------------------------------------ */
777 
778 /**
779  * \brief Find USB device by vendor/product
780  *
781  * \param port a GPPort
782  * \param idvendor USB vendor id
783  * \param idproduct USB product id
784  *
785  * Find the USB device with the specified vendor:product id pair.
786  *
787  * \return a gphoto2 error code
788  */
789 int
gp_port_usb_find_device(GPPort * port,int idvendor,int idproduct)790 gp_port_usb_find_device (GPPort *port, int idvendor, int idproduct)
791 {
792 	C_PARAMS (port);
793 	CHECK_INIT (port);
794 
795 	CHECK_SUPP (port, "find_device", port->pc->ops->find_device);
796 	CHECK_RESULT (port->pc->ops->find_device (port, idvendor, idproduct));
797 
798         return (GP_OK);
799 }
800 
801 /**
802  * \brief Find USB device by interface class
803  *
804  * \param port a GPPort
805  * \param mainclass the USB interface class
806  * \param subclass the USB interface subclass
807  * \param protocol the USB interface protocol
808  *
809  * Find the USB device with the specified vendor:product id pair.
810  *
811  * \return a gphoto2 error code
812  */
813 int
gp_port_usb_find_device_by_class(GPPort * port,int mainclass,int subclass,int protocol)814 gp_port_usb_find_device_by_class (GPPort *port, int mainclass, int subclass, int protocol)
815 {
816 	C_PARAMS (port);
817 	CHECK_INIT (port);
818 
819 	CHECK_SUPP (port, "find_device_by_class", port->pc->ops->find_device_by_class);
820 	CHECK_RESULT (port->pc->ops->find_device_by_class (port, mainclass, subclass, protocol));
821 
822         return (GP_OK);
823 }
824 
825 /**
826  * \brief Clear USB endpoint HALT condition
827  *
828  * \param port a GPPort
829  * \param ep endpoint to clear HALT
830  *
831  * Clears the HALT (stall?) endpoint condition of the specified endpoint.
832  *
833  * \return a gphoto2 error code
834  */
835 int
gp_port_usb_clear_halt(GPPort * port,int ep)836 gp_port_usb_clear_halt (GPPort *port, int ep)
837 {
838 	GP_LOG_D ("Clear USB halt...");
839 
840 	C_PARAMS (port);
841 	CHECK_INIT (port);
842 
843 	CHECK_SUPP (port, "clear_halt", port->pc->ops->clear_halt);
844         CHECK_RESULT (port->pc->ops->clear_halt (port, ep));
845 
846         return (GP_OK);
847 }
848 
849 /**
850  * \brief Send a USB control message with output data
851  *
852  * \param port a GPPort
853  * \param request control request code
854  * \param value control value
855  * \param index control index
856  * \param bytes pointer to data
857  * \param size size of the data
858  *
859  * Sends a specific USB control command and write associated data.
860  *
861  * \return a gphoto2 error code
862  */
863 int
gp_port_usb_msg_write(GPPort * port,int request,int value,int index,char * bytes,int size)864 gp_port_usb_msg_write (GPPort *port, int request, int value, int index,
865 	char *bytes, int size)
866 {
867         int retval;
868 
869 	GP_LOG_DATA (bytes, size, "Writing message (request=0x%x value=0x%x index=0x%x size=%i=0x%x):",
870 		     request, value, index, size, size);
871 
872 	C_PARAMS (port);
873 	CHECK_INIT (port);
874 
875 	CHECK_SUPP (port, "msg_write", port->pc->ops->msg_write);
876         retval = port->pc->ops->msg_write(port, request, value, index, bytes, size);
877 	CHECK_RESULT (retval);
878 
879         return (retval);
880 }
881 
882 /**
883  * \brief Send a USB control message with input data
884  *
885  * \param port a GPPort
886  * \param request control request code
887  * \param value control value
888  * \param index control index
889  * \param bytes pointer to data
890  * \param size size of the data
891  *
892  * Sends a specific USB interface control command and read associated data.
893  *
894  * \return a gphoto2 error code
895  */
896 int
gp_port_usb_msg_read(GPPort * port,int request,int value,int index,char * bytes,int size)897 gp_port_usb_msg_read (GPPort *port, int request, int value, int index,
898 	char *bytes, int size)
899 {
900         int retval;
901 
902 	gp_log (GP_LOG_DATA, __func__, "Reading message (request=0x%x value=0x%x index=0x%x size=%i=0x%x)...",
903 		request, value, index, size, size);
904 
905 	C_PARAMS (port);
906 	CHECK_INIT (port);
907 
908 	CHECK_SUPP (port, "msg_read", port->pc->ops->msg_read);
909         retval = port->pc->ops->msg_read (port, request, value, index, bytes, size);
910 	CHECK_RESULT (retval);
911 
912 	LOG_DATA (bytes, retval, size, "Read", "USB message (request=0x%x value=0x%x index=0x%x size=%i=0x%x)",
913 		  request, value, index, size, size);
914 
915         return (retval);
916 }
917 
918 /*
919  * The next two functions handle the request types 0x41 for write
920  * and 0xc1 for read.
921  */
922 /**
923  * \brief Send a USB interface control message with output data
924  *
925  * \param port a GPPort
926  * \param request control request code
927  * \param value control value
928  * \param index control index
929  * \param bytes pointer to data
930  * \param size size of the data
931  *
932  * Sends a specific USB interface control command and write associated data.
933  *
934  * \return a gphoto2 error code
935  */
936 int
gp_port_usb_msg_interface_write(GPPort * port,int request,int value,int index,char * bytes,int size)937 gp_port_usb_msg_interface_write (GPPort *port, int request,
938 	int value, int index, char *bytes, int size)
939 {
940         int retval;
941 
942 	GP_LOG_DATA (bytes, size, "Writing message (request=0x%x value=0x%x index=0x%x size=%i=0x%x)...",
943 		     request, value, index, size, size);
944 
945 	C_PARAMS (port);
946 	CHECK_INIT (port);
947 
948 	CHECK_SUPP (port, "msg_build", port->pc->ops->msg_interface_write);
949         retval = port->pc->ops->msg_interface_write(port, request,
950         		value, index, bytes, size);
951 	CHECK_RESULT (retval);
952 
953         return (retval);
954 }
955 
956 
957 /**
958  * \brief Send a USB interface control message with input data
959  *
960  * \param port a GPPort
961  * \param request control request code
962  * \param value control value
963  * \param index control index
964  * \param bytes pointer to data
965  * \param size size of the data
966  *
967  * Sends a specific USB control command and read associated data.
968  *
969  * \return a gphoto2 error code
970  */
971 int
gp_port_usb_msg_interface_read(GPPort * port,int request,int value,int index,char * bytes,int size)972 gp_port_usb_msg_interface_read (GPPort *port, int request, int value, int index,
973 	char *bytes, int size)
974 {
975         int retval;
976 
977 	gp_log (GP_LOG_DATA, __func__, "Reading message (request=0x%x value=0x%x index=0x%x size=%i=0x%x)...",
978 		request, value, index, size, size);
979 
980 	C_PARAMS (port);
981 	CHECK_INIT (port);
982 
983 	CHECK_SUPP (port, "msg_read", port->pc->ops->msg_interface_read);
984         retval = port->pc->ops->msg_interface_read (port, request,
985         		value, index, bytes, size);
986 	CHECK_RESULT (retval);
987 
988 	LOG_DATA (bytes, retval, size, "Read", "USB message (request=0x%x value=0x%x index=0x%x size=%i=0x%x)",
989 		  request, value, index, size, size);
990 
991         return (retval);
992 }
993 
994 
995 /*
996  * The next two functions handle the request types 0x21 for write
997  * and 0xa1 for read.
998  */
999 
1000 /**
1001  * \brief Send a USB class control message with output data
1002  *
1003  * \param port a GPPort
1004  * \param request control request code
1005  * \param value control value
1006  * \param index control index
1007  * \param bytes pointer to data
1008  * \param size size of the data
1009  *
1010  * Sends a specific USB class control command and write associated data.
1011  *
1012  * \return a gphoto2 error code
1013  */
1014 int
gp_port_usb_msg_class_write(GPPort * port,int request,int value,int index,char * bytes,int size)1015 gp_port_usb_msg_class_write (GPPort *port, int request,
1016 	int value, int index, char *bytes, int size)
1017 {
1018         int retval;
1019 
1020 	GP_LOG_DATA (bytes, size, "Writing message (request=0x%x value=0x%x index=0x%x size=%i=0x%x):",
1021 		     request, value, index, size, size);
1022 
1023 	C_PARAMS (port);
1024 	CHECK_INIT (port);
1025 
1026 	CHECK_SUPP (port, "msg_build", port->pc->ops->msg_class_write);
1027         retval = port->pc->ops->msg_class_write(port, request,
1028         		value, index, bytes, size);
1029 	CHECK_RESULT (retval);
1030 
1031         return (retval);
1032 }
1033 
1034 
1035 /**
1036  * \brief Send a USB class control message with input data
1037  *
1038  * \param port a GPPort
1039  * \param request control request code
1040  * \param value control value
1041  * \param index control index
1042  * \param bytes pointer to data
1043  * \param size size of the data
1044  *
1045  * Sends a specific USB class control command and read associated data.
1046  *
1047  * \return a gphoto2 error code
1048  */
1049 int
gp_port_usb_msg_class_read(GPPort * port,int request,int value,int index,char * bytes,int size)1050 gp_port_usb_msg_class_read (GPPort *port, int request, int value, int index,
1051 	char *bytes, int size)
1052 {
1053         int retval;
1054 
1055 	gp_log (GP_LOG_DATA, __func__, "Reading message (request=0x%x value=0x%x index=0x%x size=%i=0x%x)...",
1056 		request, value, index, size, size);
1057 
1058 	C_PARAMS (port);
1059 	CHECK_INIT (port);
1060 
1061 	CHECK_SUPP (port, "msg_read", port->pc->ops->msg_class_read);
1062         retval = port->pc->ops->msg_class_read (port, request,
1063         		value, index, bytes, size);
1064 	CHECK_RESULT (retval);
1065 
1066 	LOG_DATA (bytes, retval, size, "Read", "USB message (request=0x%x value=0x%x index=0x%x size=%i=0x%x)",
1067 		  request, value, index, size, size);
1068 
1069         return (retval);
1070 }
1071 
1072 /**
1073  * \brief Seek on a port (for usb disk direct ports)
1074  *
1075  * \param port a #GPPort
1076  * \param offset offset to seek to
1077  * \param whence the underlying lseek call whence parameter
1078  *
1079  * Seeks to a specific offset on the usb disk
1080  *
1081  * \return a gphoto2 error code
1082  **/
1083 int
gp_port_seek(GPPort * port,int offset,int whence)1084 gp_port_seek (GPPort *port, int offset, int whence)
1085 {
1086 	int retval;
1087 
1088 	GP_LOG_D ("Seeking to: %d whence: %d", offset, whence);
1089 
1090 	C_PARAMS (port);
1091 	CHECK_INIT (port);
1092 
1093 	CHECK_SUPP (port, "seek", port->pc->ops->seek);
1094 	retval = port->pc->ops->seek (port, offset, whence);
1095 
1096 	GP_LOG_D ("Seek result: %d", retval);
1097 
1098 	return retval;
1099 }
1100 
1101 /**
1102  * \brief Send a SCSI command to a port (for usb scsi ports)
1103  *
1104  * \param port a #GPPort
1105  * \param to_dev data direction, set to 1 for a scsi cmd which sends
1106  *        data to the device, set to 0 for cmds which read data from the dev.
1107  * \param cmd buffer holding the command to send
1108  * \param cmd_size sizeof cmd buffer
1109  * \param sense buffer for returning scsi sense information
1110  * \param sense_size sizeof sense buffer
1111  * \param data buffer containing informatino to write to the device
1112  *        (to_dev is 1), or to store data read from the device (to_dev 0).
1113  *
1114  * Send a SCSI command to a usb scsi port attached device.
1115  *
1116  * \return a gphoto2 error code
1117  **/
gp_port_send_scsi_cmd(GPPort * port,int to_dev,char * cmd,int cmd_size,char * sense,int sense_size,char * data,int data_size)1118 int gp_port_send_scsi_cmd (GPPort *port, int to_dev,
1119 				char *cmd, int cmd_size,
1120 				char *sense, int sense_size,
1121 				char *data, int data_size)
1122 {
1123 	int retval;
1124 
1125 	GP_LOG_DATA (cmd, cmd_size, "Sending scsi cmd:");
1126 	if (to_dev && data_size)
1127 		GP_LOG_DATA (data, data_size, "with scsi cmd data:");
1128 
1129 	C_PARAMS (port);
1130 	CHECK_INIT (port);
1131 
1132 	memset (sense, 0, sense_size);
1133 	CHECK_SUPP (port, "send_scsi_cmd", port->pc->ops->send_scsi_cmd);
1134 	retval = port->pc->ops->send_scsi_cmd (port, to_dev, cmd, cmd_size,
1135 					sense, sense_size, data, data_size);
1136 
1137 	GP_LOG_D ("scsi cmd result: %d", retval);
1138 
1139 	if (sense[0] != 0) {
1140 		GP_LOG_DATA (sense, sense_size, "sense data:");
1141 		/* https://secure.wikimedia.org/wikipedia/en/wiki/Key_Code_Qualifier */
1142 		GP_LOG_D ("sense decided:");
1143 		if ((sense[0]&0x7f)!=0x70) {
1144 			GP_LOG_D ("\tInvalid header.");
1145 		}
1146 		GP_LOG_D ("\tCurrent command read filemark: %s",(sense[2]&0x80)?"yes":"no");
1147 		GP_LOG_D ("\tEarly warning passed: %s",(sense[2]&0x40)?"yes":"no");
1148 		GP_LOG_D ("\tIncorrect blocklengt: %s",(sense[2]&0x20)?"yes":"no");
1149 		GP_LOG_D ("\tSense Key: %d",sense[2]&0xf);
1150 		if (sense[0]&0x80)
1151 			GP_LOG_D ("\tResidual Length: %d",sense[3]*0x1000000+sense[4]*0x10000+sense[5]*0x100+sense[6]);
1152 		GP_LOG_D ("\tAdditional Sense Length: %d",sense[7]);
1153 		GP_LOG_D ("\tAdditional Sense Code: %d",sense[12]);
1154 		GP_LOG_D ("\tAdditional Sense Code Qualifier: %d",sense[13]);
1155 		if (sense[15]&0x80) {
1156 			GP_LOG_D ("\tIllegal Param is in %s",(sense[15]&0x40)?"the CDB":"the Data Out Phase");
1157 			if (sense[15]&0x8) {
1158 				GP_LOG_D ("Pointer at %d, bit %d",sense[16]*256+sense[17],sense[15]&0x7);
1159 			}
1160 		}
1161 	}
1162 
1163 	if (!to_dev && data_size)
1164 		GP_LOG_DATA (data, data_size, "scsi cmd data:");
1165 
1166 	return retval;
1167 }
1168 
1169 /**
1170  * \brief Set verbose port error message
1171  * \param port a #GPPort
1172  * \param format printf style format string
1173  * \param ... variable arguments depending on format string
1174  *
1175  * Sets an error message that can later be retrieved using #gp_port_get_error.
1176  *
1177  * \return a gphoto2 error code
1178  **/
1179 int
gp_port_set_error(GPPort * port,const char * format,...)1180 gp_port_set_error (GPPort *port, const char *format, ...)
1181 {
1182 	va_list args;
1183 
1184 	C_PARAMS (port);
1185 
1186 	if (format) {
1187 		va_start (args, format);
1188 		vsnprintf (port->pc->error, sizeof (port->pc->error),
1189 			   _(format), args);
1190 		GP_LOG_E ("%s", port->pc->error);
1191 		va_end (args);
1192 	} else
1193 		port->pc->error[0] = '\0';
1194 
1195 	return (GP_OK);
1196 }
1197 
1198 /**
1199  * \brief Get verbose port error message
1200  * \param port a #GPPort
1201  *
1202  * Retrieves an error message from a port. If you want to make sure that
1203  * you get correct error messages, you need to call #gp_port_set_error with
1204  * an error message of %NULL each time before calling another port-related
1205  * function of which you want to check the return value.
1206  *
1207  * \return a translated error message
1208  **/
1209 const char *
gp_port_get_error(GPPort * port)1210 gp_port_get_error (GPPort *port)
1211 {
1212 	if (port && port->pc && strlen (port->pc->error))
1213 		return (port->pc->error);
1214 
1215 	return _("No error description available");
1216 }
1217