FreeCalypso > hg > freecalypso-tools
diff rvinterf/old/format_g23.c @ 0:e7502631a0f9
initial import from freecalypso-sw rev 1033:5ab737ac3ad7
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sat, 11 Jun 2016 00:13:35 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rvinterf/old/format_g23.c Sat Jun 11 00:13:35 2016 +0000 @@ -0,0 +1,241 @@ +/* + * 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(); + } +}