view simtool/smsp_set.c @ 53:fbedb67d234f

serial: fix parity for inverse coding convention Important note: it is my (Mother Mychaela's) understanding that SIM cards with inverse coding convention are extremely rare, and I have never seen such a card. Therefore, our support for the inverse coding convention will likely remain forever untested.
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 21 Mar 2021 20:46:09 +0000
parents ddd767f6e15b
children
line wrap: on
line source

/*
 * This module implements the user-oriented smsp-set and smsp-set-tag commands.
 */

#include <sys/types.h>
#include <ctype.h>
#include <string.h>
#include <strings.h>
#include <stdio.h>
#include <stdlib.h>
#include "curfile.h"

static
set_param_da(arg, fixp)
	char *arg;
	u_char *fixp;
{
	int rc;

	rc = encode_phone_number_arg(arg, fixp + 1, 1);
	if (rc < 0)
		return(rc);
	fixp[0] &= 0xFE;
	return(0);
}

static
set_param_sc(arg, fixp)
	char *arg;
	u_char *fixp;
{
	int rc;

	rc = encode_phone_number_arg(arg, fixp + 13, 0);
	if (rc < 0)
		return(rc);
	fixp[0] &= 0xFD;
	return(0);
}

static
set_param_pid(arg, fixp)
	char *arg;
	u_char *fixp;
{
	char *endp;

	if (!isdigit(*arg)) {
inv:		fprintf(stderr, "error: invalid PID= parameter\n");
		return(-1);
	}
	fixp[25] = strtoul(arg, &endp, 0);
	if (*endp)
		goto inv;
	fixp[0] &= 0xFB;
	return(0);
}

static
set_param_dcs(arg, fixp)
	char *arg;
	u_char *fixp;
{
	char *endp;

	if (!isdigit(*arg)) {
inv:		fprintf(stderr, "error: invalid DCS= parameter\n");
		return(-1);
	}
	fixp[26] = strtoul(arg, &endp, 0);
	if (*endp)
		goto inv;
	fixp[0] &= 0xF7;
	return(0);
}

static
set_param_vp(arg, fixp)
	char *arg;
	u_char *fixp;
{
	char *endp;

	if (!isdigit(*arg)) {
inv:		fprintf(stderr, "error: invalid VP= parameter\n");
		return(-1);
	}
	fixp[27] = strtoul(arg, &endp, 0);
	if (*endp)
		goto inv;
	fixp[0] &= 0xEF;
	return(0);
}

static
set_param(arg, fixp)
	char *arg;
	u_char *fixp;
{
	if (!strncasecmp(arg, "DA=", 3))
		return set_param_da(arg + 3, fixp);
	if (!strncasecmp(arg, "SC=", 3))
		return set_param_sc(arg + 3, fixp);
	if (!strncasecmp(arg, "PID=", 4))
		return set_param_pid(arg + 4, fixp);
	if (!strncasecmp(arg, "DCS=", 4))
		return set_param_dcs(arg + 4, fixp);
	if (!strncasecmp(arg, "VP=", 3))
		return set_param_vp(arg + 3, fixp);
	fprintf(stderr, "error: non-understood parameter \"%s\"\n", arg);
	return(-1);
}

cmd_smsp_set(argc, argv)
	char **argv;
{
	int rc;
	unsigned recno;
	u_char record[255], *fixp;
	char **ap;

	rc = select_ef_smsp();
	if (rc < 0)
		return(rc);
	recno = strtoul(argv[1], 0, 0);
	if (recno < 1 || recno > curfile_record_count) {
		fprintf(stderr, "error: specified record number is invalid\n");
		return(-1);
	}
	memset(record, 0xFF, curfile_record_len);
	fixp = record + curfile_record_len - 28;
	for (ap = argv + 2; *ap; ap++) {
		rc = set_param(*ap, fixp);
		if (rc < 0)
			return(rc);
	}
	return update_rec_op(recno, 0x04, record, curfile_record_len);
}

cmd_smsp_set_tag(argc, argv)
	char **argv;
{
	int rc;
	unsigned recno;
	u_char record[255], *fixp;
	char **ap;

	rc = select_ef_smsp();
	if (rc < 0)
		return(rc);
	recno = strtoul(argv[1], 0, 0);
	if (recno < 1 || recno > curfile_record_count) {
		fprintf(stderr, "error: specified record number is invalid\n");
		return(-1);
	}
	memset(record, 0xFF, curfile_record_len);
	rc = qstring_arg_to_gsm7(argv[2], record, curfile_record_len - 28);
	if (rc < 0)
		return(rc);
	fixp = record + curfile_record_len - 28;
	for (ap = argv + 3; *ap; ap++) {
		rc = set_param(*ap, fixp);
		if (rc < 0)
			return(rc);
	}
	return update_rec_op(recno, 0x04, record, curfile_record_len);
}