view simtool/alpha_valid.c @ 149:451ed3bbfe96

fc-simtool: grcard1-set-adm[12] commands implemented
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 07 Feb 2021 00:01:55 +0000
parents 90eff13a72fd
children
line wrap: on
line source

/*
 * This module contains functions for validating alpha fields
 * that exist in various SIM files.
 */

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

static
validate_classic_gsm(data, nbytes, textlenp)
	u_char *data;
	unsigned nbytes, *textlenp;
{
	u_char *dp;
	unsigned n;

	dp = data;
	for (n = 0; n < nbytes; n++) {
		if (*dp == 0xFF)
			break;
		if (*dp & 0x80)
			return(-1);
		dp++;
	}
	if (textlenp)
		*textlenp = n;
	for (; n < nbytes; n++)
		if (*dp++ != 0xFF)
			return(-1);
	return(0);
}

static
validate_ucs2_80(data, nbytes, textlenp)
	u_char *data;
	unsigned nbytes, *textlenp;
{
	u_char *dp, *endp;

	if (nbytes < 3)
		return(-1);
	dp = data + 1;
	endp = data + nbytes;
	while (dp < endp) {
		if (dp + 1 == endp) {
			if (*dp != 0xFF)
				return(-1);
			if (textlenp)
				*textlenp = dp - data;
			return(0);
		}
		if (dp[0] == 0xFF && dp[1] == 0xFF)
			break;
		dp += 2;
	}
	if (textlenp)
		*textlenp = dp - data;
	while (dp < endp)
		if (*dp++ != 0xFF)
			return(-1);
	return(0);
}

static
validate_ucs2_81(data, nbytes, textlenp)
	u_char *data;
	unsigned nbytes, *textlenp;
{
	u_char *dp, *endp;
	unsigned textlen;

	if (nbytes < 4)
		return(-1);
	if (!data[1])
		return(-1);
	textlen = data[1] + 3;
	if (textlen > nbytes)
		return(-1);
	if (textlenp)
		*textlenp = textlen;
	dp = data + textlen;
	endp = data + nbytes;
	while (dp < endp)
		if (*dp++ != 0xFF)
			return(-1);
	return(0);
}

static
validate_ucs2_82(data, nbytes, textlenp)
	u_char *data;
	unsigned nbytes, *textlenp;
{
	u_char *dp, *endp;
	unsigned textlen;

	if (nbytes < 5)
		return(-1);
	if (!data[1])
		return(-1);
	textlen = data[1] + 4;
	if (textlen > nbytes)
		return(-1);
	if (textlenp)
		*textlenp = textlen;
	dp = data + textlen;
	endp = data + nbytes;
	while (dp < endp)
		if (*dp++ != 0xFF)
			return(-1);
	return(0);
}

static
validate_empty(data, nbytes, textlenp)
	u_char *data;
	unsigned nbytes, *textlenp;
{
	u_char *dp;
	unsigned n;

	dp = data;
	for (n = 0; n < nbytes; n++)
		if (*dp++ != 0xFF)
			return(-1);
	if (textlenp)
		*textlenp = 0;
	return(0);
}

validate_alpha_field(data, nbytes, textlenp)
	u_char *data;
	unsigned nbytes, *textlenp;
{
	if (data[0] < 0x80)
		return validate_classic_gsm(data, nbytes, textlenp);
	switch (data[0]) {
	case 0x80:
		return validate_ucs2_80(data, nbytes, textlenp);
	case 0x81:
		return validate_ucs2_81(data, nbytes, textlenp);
	case 0x82:
		return validate_ucs2_82(data, nbytes, textlenp);
	case 0xFF:
		return validate_empty(data, nbytes, textlenp);
	default:
		return -1;
	}
}