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