view libcommon/backend.c @ 45:9eb5460f51a6

main tools: support both pcsc and serial back ends
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 21 Mar 2021 01:56:49 +0000
parents c9ef9e91dd8e
children
line wrap: on
line source

/*
 * This module is responsible for launching and connecting
 * our SIM card communication back end.
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

extern unsigned calypso_fd, pcsc_reader_num, serial_spenh;
extern int use_pcsc;
extern char *serial_device, *serial_baud;

static char calypso_be_pathname[] = "/opt/freecalypso/bin/fcsim-calypso-be";
static char serial_be_pathname[] = "/opt/freecalypso/bin/fcsim-serial-be";
static char pcsc_be_pathname[] = "/opt/freecalypso/bin/fc-pcsc-backend";

static char *backend_prog, *backend_argv[4], backend_optarg[16];

FILE *cpipeF, *rpipeF;

static void
setup_be_calypso()
{
	backend_prog = calypso_be_pathname;
	backend_argv[0] = "fcsim-calypso-be";
	sprintf(backend_optarg, "-C%u", calypso_fd);
	backend_argv[1] = backend_optarg;
	backend_argv[2] = 0;
}

static void
setup_be_pcsc()
{
	backend_prog = pcsc_be_pathname;
	backend_argv[0] = "fc-pcsc-backend";
	sprintf(backend_optarg, "-p%u", pcsc_reader_num);
	backend_argv[1] = backend_optarg;
	backend_argv[2] = 0;
}

static void
setup_be_serial()
{
	backend_prog = serial_be_pathname;
	backend_argv[0] = "fcsim-serial-be";
	backend_argv[1] = serial_device;
	if (serial_baud)
		backend_argv[2] = serial_baud;
	else if (serial_spenh) {
		sprintf(backend_optarg, "9600,55800,%u", serial_spenh);
		backend_argv[2] = backend_optarg;
	} else
		backend_argv[2] = "9600";
	backend_argv[3] = 0;
}

launch_backend()
{
	int cpipe[2], rpipe[2], rc;

	if (calypso_fd)
		setup_be_calypso();
	else if (use_pcsc)
		setup_be_pcsc();
	else if (serial_device)
		setup_be_serial();
	else {
		fprintf(stderr, "error: no -d or -p target selected\n");
		exit(1);
	}
	if (pipe(cpipe) < 0 || pipe(rpipe) < 0) {
		perror("pipe");
		exit(1);
	}
	rc = vfork();
	if (rc < 0) {
		perror("vfork for launching back end");
		exit(1);
	}
	if (!rc) {
		/* we are in the child - prepare to exec the BE */
		dup2(cpipe[0], 0);
		dup2(rpipe[1], 1);
		close(cpipe[0]);
		close(cpipe[1]);
		close(rpipe[0]);
		close(rpipe[1]);
		/* do the exec */
		execv(backend_prog, backend_argv);
		perror(backend_prog);
		_exit(1);
	}
	close(cpipe[0]);
	close(rpipe[1]);
	cpipeF = fdopen(cpipe[1], "w");
	if (!cpipeF) {
		perror("fdopen");
		exit(1);
	}
	rpipeF = fdopen(rpipe[0], "r");
	if (!rpipeF) {
		perror("fdopen");
		exit(1);
	}
	return(0);
}