view rvinterf/old/format_g23.c @ 523:9a478d33b3ca
fc-loadtool: added Samsung K5L33xx_A flash support for GTM900
author |
Mychaela Falconia <falcon@freecalypso.org> |
date |
Sun, 09 Jun 2019 21:51:27 +0000 (2019-06-09) |
parents |
e7502631a0f9 |
children |
|
line source
/*
* This module implements the decoding of G23 trace packets into
* human-readable form - or more precisely, traces, system primitives
* and other packets that can be emitted through GPF on targets.
* The decoding is based on my (Space Falcon's) understanding
* of the packet format, which is in turn based on the GPF sources
* available to us, now integrated under gsm-fw/gpf.
*/
#include <sys/types.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include "../include/pktmux.h"
#include "../include/limits.h"
extern u_char rxpkt[];
extern size_t rxpkt_len;
extern char fmtbuf[];
static char *fmtbuf_ptr;
static int
basic_checks()
{
int i, c;
if (rxpkt_len < 17)
return(0);
/* check version bits in the header byte */
if ((rxpkt[1] & 0xC0) != 0x80)
return(0);
/* check the length */
c = rxpkt[2] | rxpkt[3] << 8;
if (c + 4 != rxpkt_len)
return(0);
/* ensure that the "from" and "to" are printable ASCII */
for (i = 8; i < 16; i++) {
c = rxpkt[i];
if (c < ' ' || c > '~')
return(0);
}
/* basic checks pass */
return(1);
}
static int
psprim_extra_checks()
{
int i, c;
if (rxpkt_len < 24)
return(0);
/* "original rcvr" field needs to be printable ASCII */
for (i = 16; i < 20; i++) {
c = rxpkt[i];
if (c < ' ' || c > '~')
return(0);
}
/* checks pass */
return(1);
}
static void
print_malformed()
{
int i;
char *dp;
dp = fmtbuf;
strcpy(dp, "G23 UNK:");
dp += 8;
for (i = 1; i < rxpkt_len; i++) {
sprintf(dp, " %02X", rxpkt[i]);
dp += 3;
}
*dp = '\0';
output_line(fmtbuf);
}
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)
char *raw;
{
int len;
len = entity_name_well_formed(raw);
if (len)
sprintf(fmtbuf_ptr, "%.*s", len, raw);
else
sprintf(fmtbuf_ptr, "\"%.4s\"", raw);
fmtbuf_ptr = index(fmtbuf_ptr, '\0');
}
static void
print_common_hdr(typestr)
char *typestr;
{
sprintf(fmtbuf, "G23 %s id=%02X ts=%02X%02X%02X%02X ", typestr,
rxpkt[1], rxpkt[7], rxpkt[6], rxpkt[5], rxpkt[4]);
fmtbuf_ptr = index(fmtbuf, '\0');
print_entity_name(rxpkt + 8);
*fmtbuf_ptr++ = '-';
*fmtbuf_ptr++ = '>';
print_entity_name(rxpkt + 12);
*fmtbuf_ptr++ = ' ';
}
static void
format_text(start_off)
{
int i, c;
*fmtbuf_ptr++ = '\"';
for (i = start_off; i < rxpkt_len; i++) {
c = rxpkt[i];
if (c & 0x80) {
*fmtbuf_ptr++ = 'M';
*fmtbuf_ptr++ = '-';
c &= 0x7F;
}
if (c < 0x20) {
*fmtbuf_ptr++ = '^';
*fmtbuf_ptr++ = c + '@';
} else if (c == 0x7F) {
*fmtbuf_ptr++ = '^';
*fmtbuf_ptr++ = '?';
} else
*fmtbuf_ptr++ = c;
}
*fmtbuf_ptr++ = '\"';
*fmtbuf_ptr = '\0';
output_line(fmtbuf);
}
static void
format_compressed_trace(start_off)
{
int i;
i = start_off + 1;
sprintf(fmtbuf_ptr, "%d", rxpkt[i+1] << 8 | rxpkt[i]);
fmtbuf_ptr = index(fmtbuf_ptr, '\0');
i += 4;
for (; i < rxpkt_len; i++) {
sprintf(fmtbuf_ptr, " %02X", rxpkt[i]);
fmtbuf_ptr += 3;
}
*fmtbuf_ptr = '\0';
output_line(fmtbuf);
}
static void
format_trace()
{
int i;
i = 16;
if (rxpkt[i] < 0x20) {
sprintf(fmtbuf_ptr, "tc=%02X ", rxpkt[i]);
fmtbuf_ptr += 6;
i++;
}
if (rxpkt_len - i >= 5 && rxpkt[i] == '%' &&
!rxpkt[i+3] && !rxpkt[i+4])
format_compressed_trace(i);
else
format_text(i);
}
static void
format_psprim()
{
int i;
/* original destination */
*fmtbuf_ptr++ = '(';
print_entity_name(rxpkt + 16);
*fmtbuf_ptr++ = ')';
/* opcode */
sprintf(fmtbuf_ptr, " %02X%02X%02X%02X",
rxpkt[23], rxpkt[22], rxpkt[21], rxpkt[20]);
fmtbuf_ptr += 9;
for (i = 24; i < rxpkt_len; i++) {
sprintf(fmtbuf_ptr, " %02X", rxpkt[i]);
fmtbuf_ptr += 3;
}
*fmtbuf_ptr = '\0';
output_line(fmtbuf);
}
void
print_g23_trace()
{
if (!basic_checks()) {
print_malformed();
return;
}
/* dispatch by type */
switch (rxpkt[1] & 0x30) {
case 0x10:
/* PS primitive */
if (psprim_extra_checks()) {
print_common_hdr("PSprim");
format_psprim();
} else
print_malformed();
return;
case 0x20:
/* trace */
print_common_hdr("trace");
format_trace();
return;
case 0x30:
/* system primitive */
print_common_hdr("sysprim");
format_text(16);
return;
default:
print_malformed();
}
}