view rvinterf/libg23/fmtfunc.c @ 905:546bf873ccc8

tchtools: new program fc-vm2gsmx
author Mychaela Falconia <falcon@freecalypso.org>
date Wed, 28 Dec 2022 09:08:50 +0000
parents e7502631a0f9
children
line wrap: on
line source

/*
 * This libg23 module exports functions for formatting 3 different kinds
 * of GPF packets into human-readable form: traces, system primitives
 * and protocol stack primitives.
 *
 * GPF packets passed to these functions for decoding MUST have already
 * been verified to be well-formed for their respective type.
 */

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

static int
entity_name_well_formed(p)
	char *p;
{
	int i, len;

	if (!isupper(p[0]))
		return(0);
	for (i = 0; i < 4; i++)
		if (!isalnum(p[i]))
			break;
	len = i;
	for (; i < 4; i++)
		if (p[i] != ' ')
			return(0);
	return(len);
}

static void
print_entity_name(raw, outp)
	char *raw, **outp;
{
	int len;

	len = entity_name_well_formed(raw);
	if (len) {
		sprintf(*outp, "%.*s", len, raw);
		*outp += len;
	} else {
		sprintf(*outp, "\"%.4s\"", raw);
		*outp += 6;
	}
}

static void
print_common_hdr(rxpkt, outp, typestr)
	u_char *rxpkt;
	char **outp, *typestr;
{
	sprintf(*outp, "GPF %s id=%02X ts=%02X%02X%02X%02X ", typestr,
		rxpkt[1], rxpkt[7], rxpkt[6], rxpkt[5], rxpkt[4]);
	*outp = index(*outp, '\0');
	print_entity_name(rxpkt + 8, outp);
	*(*outp)++ = '-';
	*(*outp)++ = '>';
	print_entity_name(rxpkt + 12, outp);
	*(*outp)++ = ' ';
}

static void
format_text(rxpkt, rxpkt_len, start_off, outp)
	u_char *rxpkt;
	char *outp;
{
	int i, c;

	*outp++ = '\"';
	for (i = start_off; i < rxpkt_len; i++) {
		c = rxpkt[i];
		if (c & 0x80) {
			*outp++ = 'M';
			*outp++ = '-';
			c &= 0x7F;
		}
		if (c < 0x20) {
			*outp++ = '^';
			*outp++ = c + '@';
		} else if (c == 0x7F) {
			*outp++ = '^';
			*outp++ = '?';
		} else
			*outp++ = c;
	}
	*outp++ = '\"';
	*outp = '\0';
}

static void
format_compressed_trace(rxpkt, rxpkt_len, start_off, outp)
	u_char *rxpkt;
	char *outp;
{
	int i;

	i = start_off + 1;
	sprintf(outp, "%d", rxpkt[i+1] << 8 | rxpkt[i]);
	outp = index(outp, '\0');
	i += 4;
	for (; i < rxpkt_len; i++) {
		sprintf(outp, " %02X", rxpkt[i]);
		outp += 3;
	}
	*outp = '\0';
}

void
format_g23_trace(rxpkt, rxpkt_len, outbuf)
	u_char *rxpkt;
	char *outbuf;
{
	char *outp = outbuf;
	int i;

	print_common_hdr(rxpkt, &outp, "trace");
	i = 16;
	if (rxpkt[i] < 0x20) {
		sprintf(outp, "tc=%02X ", rxpkt[i]);
		outp += 6;
		i++;
	}
	if (rxpkt_len - i >= 5 && rxpkt[i] == '%' &&
	    !rxpkt[i+3] && !rxpkt[i+4])
		format_compressed_trace(rxpkt, rxpkt_len, i, outp);
	else
		format_text(rxpkt, rxpkt_len, i, outp);
}

void
format_g23_sysprim(rxpkt, rxpkt_len, outbuf)
	u_char *rxpkt;
	char *outbuf;
{
	char *outp = outbuf;
	int i;

	print_common_hdr(rxpkt, &outp, "sysprim");
	format_text(rxpkt, rxpkt_len, 16, outp);
}

void
format_g23_psprim(rxpkt, rxpkt_len, outbuf)
	u_char *rxpkt;
	char *outbuf;
{
	char *outp = outbuf;
	int i;

	print_common_hdr(rxpkt, &outp, "PSprim");
	/* original destination */
	*outp++ = '(';
	print_entity_name(rxpkt + 16, &outp);
	*outp++ = ')';
	/* opcode */
	sprintf(outp, " %02X%02X%02X%02X",
		rxpkt[23], rxpkt[22], rxpkt[21], rxpkt[20]);
	outp += 9;
	for (i = 24; i < rxpkt_len; i++) {
		sprintf(outp, " %02X", rxpkt[i]);
		outp += 3;
	}
	*outp = '\0';
}