3 Copyright (c) 2002 Finger Lakes Instrumentation (FLI), L.L.C.
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
10 Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
13 Redistributions in binary form must reproduce the above
14 copyright notice, this list of conditions and the following
15 disclaimer in the documentation and/or other materials
16 provided with the distribution.
18 Neither the name of Finger Lakes Instrumentation (FLI), LLC
19 nor the names of its contributors may be used to endorse or
20 promote products derived from this software without specific
21 prior written permission.
23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27 REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 POSSIBILITY OF SUCH DAMAGE.
36 ======================================================================
38 Finger Lakes Instrumentation, L.L.C. (FLI)
39 web: http://www.fli-cam.com
40 email: support@fli-cam.com
45 #include <sys/types.h>
57 #include "libfli-libfli.h"
58 #include "libfli-debug.h"
59 #include "libfli-mem.h"
60 #include "libfli-camera.h"
61 #include "libfli-filter-focuser.h"
62 #include "libfli-sys.h"
63 #include "libfli-parport.h"
64 #include "libfli-usb.h"
65 #include "libfli-serial.h"
68 #define MIN(a, b) ((a) < (b) ? (a) : (b))
71 static long unix_fli_list_parport(flidomain_t domain
, char ***names
);
72 static long unix_fli_list_usb(flidomain_t domain
, char ***names
);
73 static long unix_fli_list_serial(flidomain_t domain
, char ***names
);
76 long linux_usb_reset(flidev_t dev
);
79 long unix_fli_connect(flidev_t dev
, char *name
, long domain
)
88 /* Lock functions should be set before any other functions used */
89 DEVICE
->fli_lock
= unix_fli_lock
;
90 DEVICE
->fli_unlock
= unix_fli_unlock
;
92 DEVICE
->domain
= domain
& 0x00ff;
93 DEVICE
->devinfo
.type
= domain
& 0xff00;
95 debug(FLIDEBUG_INFO
, "Domain: 0x%04x", DEVICE
->domain
);
96 debug(FLIDEBUG_INFO
, " Type: 0x%04x", DEVICE
->devinfo
.type
);
98 if ((io
= xcalloc(1, sizeof(fli_unixio_t
))) == NULL
)
101 if ((io
->fd
= open(name
, O_RDWR
)) == -1)
107 switch (DEVICE
->domain
)
109 case FLIDOMAIN_PARALLEL_PORT
:
110 DEVICE
->fli_io
= unix_parportio
;
117 if( (r
= unix_usbverifydescriptor(dev
, io
)) != 0)
123 DEVICE
->fli_io
= unix_usbio
;
127 case FLIDOMAIN_SERIAL
:
128 DEVICE
->fli_io
= unix_serialio
;
137 switch (DEVICE
->devinfo
.type
)
139 case FLIDEVICE_CAMERA
:
140 DEVICE
->fli_open
= fli_camera_open
;
141 DEVICE
->fli_close
= fli_camera_close
;
142 DEVICE
->fli_command
= fli_camera_command
;
145 case FLIDEVICE_FOCUSER
:
146 DEVICE
->fli_open
= fli_focuser_open
;
147 DEVICE
->fli_close
= fli_focuser_close
;
148 DEVICE
->fli_command
= fli_focuser_command
;
151 case FLIDEVICE_FILTERWHEEL
:
152 DEVICE
->fli_open
= fli_filter_open
;
153 DEVICE
->fli_close
= fli_filter_close
;
154 DEVICE
->fli_command
= fli_filter_command
;
163 DEVICE
->io_data
= io
;
164 DEVICE
->name
= xstrdup(name
);
165 DEVICE
->io_timeout
= 60 * 1000; /* 1 min. */
170 long unix_fli_disconnect(flidev_t dev
)
178 if ((DEVICE
->domain
& 0x00ff) == FLIDOMAIN_USB
) {
179 debug(FLIDEBUG_INFO
, "Resetting device");
180 linux_usb_reset(dev
);
184 if ((io
= DEVICE
->io_data
) == NULL
)
190 xfree(DEVICE
->io_data
);
192 DEVICE
->io_data
= NULL
;
193 DEVICE
->fli_lock
= NULL
;
194 DEVICE
->fli_unlock
= NULL
;
195 DEVICE
->fli_io
= NULL
;
196 DEVICE
->fli_open
= NULL
;
197 DEVICE
->fli_close
= NULL
;
198 DEVICE
->fli_command
= NULL
;
203 #if defined(_USE_FLOCK_)
205 long unix_fli_lock(flidev_t dev
)
207 fli_unixio_t
*io
= DEVICE
->io_data
;
212 if (flock(io
->fd
, LOCK_EX
) == -1)
218 long unix_fli_unlock(flidev_t dev
)
220 fli_unixio_t
*io
= DEVICE
->io_data
;
225 if (flock(io
->fd
, LOCK_UN
) == -1)
231 #else /* !defined(_USE_FLOCK_) */
233 #define PUBLIC_DIR "/var/spool/uucppublic"
235 long unix_fli_lock(flidev_t dev
)
237 int fd
, err
= 0, locked
= 0, i
;
238 char tmpf
[] = PUBLIC_DIR
"/temp.XXXXXX", lockf
[PATH_MAX
], name
[PATH_MAX
];
240 unsigned int backoff
= 10000;
243 if ((fd
= mkstemp(tmpf
)) == -1)
246 if ((f
= fdopen(fd
, "w")) == NULL
)
252 fprintf(f
, "%d\n", getpid());
255 if (chmod(tmpf
, S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IWGRP
|
256 S_IROTH
| S_IWOTH
) == -1)
262 for (i
= 0; DEVICE
->name
[i
] != '\0' && i
< PATH_MAX
; i
++)
263 name
[i
] = (DEVICE
->name
[i
] == '/') ? '-' : DEVICE
->name
[i
];
265 name
[MIN(i
, PATH_MAX
- 1)] = '\0';
267 if (snprintf(lockf
, PATH_MAX
, PUBLIC_DIR
"/libfli%s.lock",
275 if (link(tmpf
, lockf
) == -1)
285 if ((f
= fopen(lockf
, "r")) == NULL
)
288 r
= fscanf(f
, "%d\n", &pid
);
297 debug(FLIDEBUG_WARN
, "Removing stale lock file");
306 if ((backoff
<<= 2) == 0)
324 long unix_fli_unlock(flidev_t dev
)
326 char lockf
[PATH_MAX
], name
[PATH_MAX
];
331 for (i
= 0; DEVICE
->name
[i
] != '\0' && i
< PATH_MAX
; i
++)
332 name
[i
] = (DEVICE
->name
[i
] == '/') ? '-' : DEVICE
->name
[i
];
334 name
[MIN(i
, PATH_MAX
- 1)] = '\0';
336 if (snprintf(lockf
, PATH_MAX
, PUBLIC_DIR
"/libfli%s.lock",
340 if ((f
= fopen(lockf
, "r")) == NULL
)
342 debug(FLIDEBUG_WARN
, "Trying to unlock `%s' when not locked",
347 if (fscanf(f
, "%d\n", &pid
) != 1)
348 debug(FLIDEBUG_WARN
, "Invalid lock file for `%s'", DEVICE
->name
);
352 if (pid
!= -1 && pid
!= getpid())
353 debug(FLIDEBUG_WARN
, "Forcing unlock of `%s' from process %d",
363 #endif /* defined(_USE_FLOCK_) */
365 long unix_fli_list(flidomain_t domain
, char ***names
)
369 switch (domain
& 0x00ff)
371 case FLIDOMAIN_PARALLEL_PORT
:
372 return unix_fli_list_parport(domain
, names
);
376 return unix_fli_list_usb(domain
, names
);
379 case FLIDOMAIN_SERIAL
:
380 return unix_fli_list_serial(domain
, names
);
391 static long unix_fli_list_glob(char *pattern
, flidomain_t domain
,
394 int retval
, i
, found
= 0;
398 if ((retval
= glob(pattern
, 0, NULL
, &g
)))
401 if (retval
!= GLOB_NOMATCH
)
407 /* retval == GLOB_NOMATCH */
415 if ((list
= xmalloc((g
.gl_pathc
+ 1) * sizeof(char *))) == NULL
)
421 for (i
= 0; i
< (int) g
.gl_pathc
; i
++)
425 if (FLIOpen(&dev
, g
.gl_pathv
[i
], domain
))
428 if ((list
[found
] = xmalloc(strlen(g
.gl_pathv
[i
]) +
429 strlen(DEVICE
->devinfo
.model
) + 2)) == NULL
)
434 for (j
= 0; j
< found
; j
++)
441 sprintf(list
[found
], "%s;%s", g
.gl_pathv
[i
], DEVICE
->devinfo
.model
);
448 /* Terminate the list */
449 list
[found
++] = NULL
;
451 list
= xrealloc(list
, found
* sizeof(char *));
459 static long unix_fli_list_parport(flidomain_t domain
, char ***names
)
461 return unix_fli_list_glob(PARPORT_GLOB
, domain
, names
);
466 static long unix_fli_list_parport(flidomain_t domain
, char ***names
)
473 static long unix_fli_list_usb(flidomain_t domain
, char ***names
)
475 return unix_fli_list_glob(USB_GLOB
, domain
, names
);
478 static long unix_fli_list_serial(flidomain_t domain
, char ***names
)
480 return unix_fli_list_glob(SERIAL_GLOB
, domain
, names
);