Commit 81ab9630 authored by Éric Thiébaut's avatar Éric Thiébaut
Browse files

Add server for FLI cameras

The functions in `fli-core.c` must however be completed to have a fully
functional server...
parent 01200164
// fli-server.c -
//
// Image server forFinger Lakes Instrumentation cameras.
//
//-----------------------------------------------------------------------------
//
// This file if part of TAO real-time software licensed under the MIT license
// (https://git-cral.univ-lyon1.fr/tao/tao-rt).
#include "tao-fli-cameras.h"
#include "tao-errors.h"
#include "tao-camera-servers.h"
#include "tao-cameras-private.h"
#include <stdlib.h>
#include <string.h>
static int format_owner(
char* dst,
long dst_size,
const char* str,
int devnum)
{
long nstr = TAO_STRLEN(str);
long k = 0; // number of consecutive '%'
char buf[32];
sprintf(buf, "%d", devnum);
long nbuf = TAO_STRLEN(buf);
long j = 0;
long j1 = dst_size - 1;
long j2 = dst_size - nbuf;
for (long i = 0; i < nstr; ++i) {
int c = str[i];
if (c == '%') {
if (++k == 2) {
if (j >= j1) {
return -2;
}
dst[j++] = '%';
k = 0;
}
} else if (k == 1) {
if (c != 'd') {
return -1;
}
if (j >= j2) {
return -2;
}
for (long l = 0; l < nbuf; ++l) {
dst[j+l] = buf[l];
}
j += nbuf;
k = 0;
} else {
if (j >= j1) {
return -2;
}
dst[j++] = c;
}
}
if (k != 0 || j < 1) {
return -1;
}
dst[j] = '\0';
return 0;
}
int main(
int argc,
char* argv[])
{
// Determine program name.
const char* progname = tao_basename(argv[0]);
// Parse arguments.
char owner[TAO_OWNER_SIZE];
char const* name = "Fli%d";
bool debug = false;
bool fancy = true;
long devnum = -1;
long nbufs = 20;
unsigned int perms = 0077;
const char* usage = "Usage: %s [OPTIONS ...] [--] DEV [NAME]\n";
bool opt = true;
int nargs = 0; // # of parsed positional arguments
for (int iarg = 1; iarg < argc; ++iarg) {
char dummy;
if (opt) {
// Argument may be an option.
if (argv[iarg][0] != '-') {
opt = false;
} else if (argv[iarg][1] == '-' && argv[iarg][2] == '\0') {
opt = false;
continue;
}
}
if (!opt) {
// Positional argument.
++nargs;
if (nargs == 1) {
if (tao_parse_long(argv[iarg], &devnum, 0) != TAO_OK ||
devnum < 0) {
fprintf(stderr, "%s: Invalid device number %s\n",
progname, argv[iarg]);
return EXIT_FAILURE;
}
continue;
}
if (nargs == 2) {
name = argv[iarg];
continue;
}
fprintf(stderr, "%s: Too many arguments\n", progname);
bad_usage:
fprintf(stderr, usage, progname);
return EXIT_FAILURE;
}
// Argument is an option.
if (strcmp(argv[iarg], "-h") == 0
|| strcmp(argv[iarg], "-help") == 0
|| strcmp(argv[iarg], "--help") == 0) {
printf("\n");
printf(usage, progname);
printf("\n");
printf("Launch a server for a Finger Lakes Instrumentation (FLI) "
"camera.\n");
printf("\n");
printf("Arguments:\n");
printf(" DEV Camera device number.\n");
printf(" NAME Name of server (may have a %%d to "
"insert device\n"
" number) [%s].\n", name);
printf("\n");
printf("Options:\n");
printf(" -nbufs NBUFS Number of output buffers [%ld].\n",
nbufs);
printf(" -perms BITS Bitwise mask of permissions [0%o].\n",
perms);
printf(" -nofancy Do not use colors nor set window "
"title.\n");
printf(" -debug Debug mode [%s].\n",
(debug ? "true" : "false"));
printf(" -h, -help, --help Print this help.\n");
printf("\n");
return EXIT_SUCCESS;
}
if (strcmp(argv[iarg], "-nbufs") == 0) {
if (iarg + 1 >= argc) {
fprintf(stderr, "%s: Missing argument for option %s\n",
progname, argv[iarg]);
return EXIT_FAILURE;
}
if (sscanf(argv[iarg+1], "%ld %c", &nbufs, &dummy) != 1
|| nbufs < 2) {
fprintf(stderr, "%s: Invalid value \"%s\" for option %s\n",
progname, argv[iarg+1], argv[iarg]);
return EXIT_FAILURE;
}
++iarg;
continue;
}
if (strcmp(argv[iarg], "-perms") == 0) {
if (iarg + 1 >= argc) {
fprintf(stderr, "%s: Missing argument for option %s\n",
progname, argv[iarg]);
return EXIT_FAILURE;
}
if (sscanf(argv[iarg+1], "%iarg %c", (int*)&perms, &dummy) != 1) {
fprintf(stderr, "%s: Invalid value \"%s\" for option %s\n",
progname, argv[iarg+1], argv[iarg]);
return EXIT_FAILURE;
}
perms &= 0777;
++iarg;
continue;
}
if (strcmp(argv[iarg], "-nofancy") == 0) {
fancy = false;
continue;
}
if (strcmp(argv[iarg], "-debug") == 0) {
debug = true;
continue;
}
fprintf(stderr, "%s: Unknown option %s\n", progname, argv[iarg]);
return EXIT_FAILURE;
}
if (nargs < 1) {
fprintf(stderr, "%s: Missing device number\n", progname);
goto bad_usage;
}
int rv = format_owner(owner, TAO_OWNER_SIZE, name, devnum);
if (rv != 0) {
if (rv == -2) {
fprintf(stderr, "%s: Owner name too long\n", progname);
} else {
fprintf(stderr, "%s: Invalid owner name\n", progname);
}
return EXIT_FAILURE;
}
// Value returned on exit and created resources.
int retval = EXIT_SUCCESS;
tao_camera* dev = NULL;
tao_camera_server* srv = NULL;
// Open the camera device. The camera state is set to "initializing" until
// the worker thread has started.
dev = tao_fli_camera_open(devnum);
if (dev == NULL) {
fprintf(stderr, "%s: Failed to open Finger Lakes Instrumentation "
"camera device %ld\n", progname, devnum);
goto error;
}
if (debug) {
fprintf(stderr, "%s: Camera device %ld now open\n", progname, devnum);
}
// Retrieve initial configuration. Make sure to synchronize the actual
// configuration after any changes in case some parameters are not exactly
// the requested ones.
tao_camera_config cfg;
if (tao_camera_update_configuration(dev) != TAO_OK ||
tao_camera_get_configuration(dev, &cfg) != TAO_OK) {
fprintf(stderr, "%s: Failed to retrieve camera configuration\n",
progname);
goto error;
}
if (debug) {
// Apply the current configuration, this should not change anything
// (this is just for debugging purposes).
fprintf(stdout, "%s: Initial camera configuration:\n", progname);
tao_camera_info_print(stdout, &dev->info);
fprintf(stdout, "\n");
if (tao_camera_set_configuration(dev, &cfg) != TAO_OK) {
fprintf(stderr, "%s: Failed to restore camera configuration\n",
progname);
goto error;
}
if (tao_camera_update_configuration(dev) != TAO_OK) {
fprintf(stderr, "%s: Failed to update camera configuration\n",
progname);
goto error;
}
if (tao_camera_get_configuration(dev, &cfg) != TAO_OK) {
fprintf(stderr, "%s: Failed to retrieve camera configuration\n",
progname);
goto error;
}
fprintf(stdout, "%s: Camera configuration has been retrieved\n",
progname);
fprintf(stdout, "%s: Restored camera configuration:\n", progname);
tao_camera_info_print(stdout, &dev->info);
fprintf(stdout, "\n");
}
// Create the camera server.
srv = tao_camera_server_create(owner, dev, nbufs, perms);
if (srv == NULL) {
fprintf(stderr, "%s: Failed to create the camera server\n",
progname);
goto error;
}
if (debug) {
fprintf(stderr,
"%s: Camera server \"%s\" created with %ld buffers\n",
progname, tao_camera_server_get_owner(srv), nbufs);
}
if (debug) {
srv->loglevel = TAO_MESG_DEBUG;
} else {
srv->loglevel = TAO_MESG_INFO;
}
srv->fancy = fancy;
// Run the server loop and destroy the server.
if (tao_camera_server_run_loop(srv) != TAO_OK) {
fprintf(stderr, "%s: Failed to create the camera server\n",
progname);
goto error;
}
done:
// Destroy the server.
if (srv != NULL && tao_camera_server_destroy(srv) != TAO_OK) {
fprintf(stderr, "%s: Failed to destroy the camera server\n",
progname);
retval = EXIT_FAILURE;
}
// Close the camera device.
if (dev != NULL && tao_camera_destroy(dev) != TAO_OK) {
fprintf(stderr, "%s: Failed to destroy the camera device\n",
progname);
retval = EXIT_FAILURE;
}
if (tao_any_errors(NULL)) {
tao_report_error();
retval = EXIT_FAILURE;
}
return retval;
error:
retval = EXIT_FAILURE;
goto done;
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment