view calypso/tpinterf.c @ 99:97ba63d9361a

scripts/fcsim1-sst: turn off STK & OTA services In the initial unprogrammed state of the cards from Grcard, SST has services 25 through 29 set to allocated and activated. However, these cards appear to not actually support OTA, ENVELOPE commands do nothing (just return SW 9000), and they were never observed issuing any proactive SIM commands, even after a feature-generous TERMINAL PROFILE. Therefore, let's list these STK & OTA services as allocated, but not activated in our FCSIM1 SST.
author Mychaela Falconia <falcon@freecalypso.org>
date Wed, 05 May 2021 04:26:07 +0000
parents b25d4dfe5798
children
line wrap: on
line source

/*
 * This code is based on loadtools/tpinterf.c from FC host tools,
 * modified for our different application of interfacing between
 * simagent below and fc-simtool above.
 */

#include <sys/types.h>
#include <sys/time.h>
#include <sys/errno.h>
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <stdlib.h>
#include <unistd.h>

extern int errno;

extern int target_fd;

/* definition matches target-utils/libcommon/cmdentry.c */
#define	MAXCMD	527

/*
 * static buffer between tpinterf_make_cmd and tpinterf_send_cmd
 *
 * We store the command with an ending \r\n so we can use it for
 * matching the received echo as well, hence the sizing of the
 * buffer.
 */
static char cmdbuf[MAXCMD+2];
static int cmdlen;

static int
arg_chars_valid(arg)
	char *arg;
{
	char *cp;

	for (cp = arg; *cp; cp++)
		if (*cp < ' ' || *cp > '~')
			return(0);
	return(1);
}

/*
 * This function takes a command for the target in argv form and
 * converts it to a space-separated continuous string which can be
 * passed as tty "keyboard" input to the target, enforcing length
 * and character validity limits in the process.  The output is
 * stored in an internal static buffer for subsequent
 * tpinterf_send_cmd().
 *
 * Return value: 0 if everything OK, or -1 if some constraint is
 * violated.
 */
tpinterf_make_cmd(argv)
	char **argv;
{
	int arglen;
	char **ap, *dp;

	dp = cmdbuf;
	cmdlen = 0;
	for (ap = argv; *ap; ap++) {
		arglen = strlen(*ap);
		if (ap != argv)
			arglen++;	/* separating space */
		if (arglen > MAXCMD - cmdlen)
			return(-1);
		if (!arg_chars_valid(*ap))
			return(-1);
		if (ap != argv)
			*dp++ = ' ';
		strcpy(dp, *ap);
		dp += strlen(*ap);
		cmdlen += arglen;
	}
	*dp++ = '\r';
	*dp = '\n';
	return(0);
}

/*
 * This function sends the previously-constructed command to the target,
 * and collects the expected echo.
 *
 * Return value: 0 if successful, -1 on errors (timeout or wrong response)
 */
tpinterf_send_cmd()
{
	char echobuf[MAXCMD+2];
	fd_set fds;
	struct timeval tv;
	int rcvd, cc;

	write(target_fd, cmdbuf, cmdlen + 1);
	for (rcvd = 0; rcvd < cmdlen + 2; ) {
		FD_ZERO(&fds);
		FD_SET(target_fd, &fds);
		tv.tv_sec = 1;
		tv.tv_usec = 0;
		cc = select(target_fd+1, &fds, NULL, NULL, &tv);
		if (cc < 0) {
			if (errno == EINTR)
				continue;
			printf("back end error: failed select\n");
			return(-1);
		}
		if (cc < 1) {
			printf(
			"back end error: timeout waiting for command echo\n");
			return(-1);
		}
		cc = read(target_fd, echobuf + rcvd, cmdlen + 2 - rcvd);
		if (cc <= 0) {
			printf(
		"back end error: failed read after successful select\n");
			return(-1);
		}
		rcvd += cc;
	}
	if (bcmp(echobuf, cmdbuf, cmdlen + 2)) {
		printf("back end error: command echo mismatch\n");
		return(-1);
	} else
		return(0);
}

/*
 * This functions reads the serial output from the target until a
 * '=' prompt is received.  All intermediate output is passed to
 * stdout, with some hacks specific to this SIM interface back end.
 */
tpinterf_pass_output(timeout)
{
	char buf[1024], *cp;
	fd_set fds;
	struct timeval tv;
	int cc, newline = 1, termflag = 0, finish = 0;
	unsigned goodchar;

	for (goodchar = 0; !finish; ) {
		FD_ZERO(&fds);
		FD_SET(target_fd, &fds);
		tv.tv_sec = timeout;
		tv.tv_usec = 0;
		cc = select(target_fd+1, &fds, NULL, NULL, &tv);
		if (cc < 0) {
			if (errno == EINTR)
				continue;
			printf("back end error: failed select\n");
			return(-1);
		}
		if (cc < 1) {
			printf(
		"back end error: timeout waiting for simagent response\n");
			return(-1);
		}
		cc = read(target_fd, buf + goodchar, sizeof(buf) - goodchar);
		if (cc <= 0) {
			printf(
		"back end error: failed read after successful select\n");
			return(-1);
		}
		for (cp = buf + goodchar; cc; cp++) {
			cc--;
			if (*cp == '=' && newline && !cc) {
				finish = 1;
				break;
			}
			if (*cp == '\n') {
				newline = 1;
				termflag = 1;
				continue;
			}
			newline = 0;
			if (*cp == '\r')
				termflag = 1;
			if (!termflag)
				goodchar++;
			if (goodchar >= 516)
				termflag = 1;
		}
	}
	if (!goodchar) {
		printf("back end error: empty output from simagent\n");
		return(-1);
	}
	buf[goodchar] = '\0';
	puts(buf);
	return(0);
}