comparison rvinterf/lowlevel/format_g23.c @ 327:05874f1ddacb

rvinterf & rvtdump: new decoding of G23/GPF packets
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Sun, 20 Apr 2014 20:39:53 +0000
parents 2f285f20d617
children
comparison
equal deleted inserted replaced
326:7e878e6b9cf7 327:05874f1ddacb
1 /* 1 /*
2 * This module implements the decoding of G23 trace packets into 2 * This module implements the decoding of G23 trace packets into
3 * human-readable form. Because I have not yet reached the point 3 * human-readable form - or more precisely, traces, system primitives
4 * of integrating the target-side code that generates these packets, 4 * and other packets that can be emitted through GPF on targets.
5 * I do not yet have the proper understanding of their format. 5 * The decoding is based on my (Space Falcon's) understanding
6 * Therefore, the current decoding logic implemented here is based 6 * of the packet format, which is in turn based on the GPF sources
7 * on a heuristic examination of what the packets look like to an 7 * available to us, now integrated under gsm-fw/gpf.
8 * uninitiated eye.
9 */ 8 */
10 9
11 #include <sys/types.h> 10 #include <sys/types.h>
11 #include <ctype.h>
12 #include <stdio.h> 12 #include <stdio.h>
13 #include <string.h> 13 #include <string.h>
14 #include <strings.h> 14 #include <strings.h>
15 #include "../include/pktmux.h" 15 #include "../include/pktmux.h"
16 #include "../include/limits.h" 16 #include "../include/limits.h"
17 17
18 extern u_char rxpkt[]; 18 extern u_char rxpkt[];
19 extern size_t rxpkt_len; 19 extern size_t rxpkt_len;
20 extern char fmtbuf[];
21
22 static char *fmtbuf_ptr;
20 23
21 static int 24 static int
22 is_well_formed() 25 basic_checks()
23 { 26 {
24 int i, c; 27 int i, c;
25 28
26 if (rxpkt_len < 17) 29 if (rxpkt_len < 17)
27 return(0); 30 return(0);
31 /* check version bits in the header byte */
32 if ((rxpkt[1] & 0xC0) != 0x80)
33 return(0);
34 /* check the length */
35 c = rxpkt[2] | rxpkt[3] << 8;
36 if (c + 4 != rxpkt_len)
37 return(0);
38 /* ensure that the "from" and "to" are printable ASCII */
28 for (i = 8; i < 16; i++) { 39 for (i = 8; i < 16; i++) {
29 c = rxpkt[i]; 40 c = rxpkt[i];
30 if (c < ' ' || c > '~') 41 if (c < ' ' || c > '~')
31 return(0); 42 return(0);
32 } 43 }
44 /* basic checks pass */
33 return(1); 45 return(1);
34 } 46 }
35 47
36 static void 48 static int
37 print_well_formed() 49 psprim_extra_checks()
38 { 50 {
39 char buf[MAX_PKT_FROM_TARGET*4];
40 int i, c; 51 int i, c;
52
53 if (rxpkt_len < 24)
54 return(0);
55 /* "original rcvr" field needs to be printable ASCII */
56 for (i = 16; i < 20; i++) {
57 c = rxpkt[i];
58 if (c < ' ' || c > '~')
59 return(0);
60 }
61 /* checks pass */
62 return(1);
63 }
64
65 static void
66 print_malformed()
67 {
68 int i;
41 char *dp; 69 char *dp;
42 70
43 dp = buf; 71 dp = fmtbuf;
44 strcpy(dp, "G23:");
45 dp += 4;
46 for (i = 1; i <= 7; i++) {
47 sprintf(dp, " %02X", rxpkt[i]);
48 dp += 3;
49 }
50 sprintf(dp, " \"%.4s\" \"%.4s\" ", rxpkt+8, rxpkt+12);
51 dp += 15;
52 i = 16;
53 if (rxpkt[i] < 0x20) {
54 sprintf(dp, "%02X ", rxpkt[i]);
55 dp += 3;
56 i++;
57 }
58 if (rxpkt_len - i == 5 && rxpkt[i] == '%' &&
59 !rxpkt[i+3] && !rxpkt[i+4]) {
60 sprintf(dp, "%d", rxpkt[i+2] << 8 | rxpkt[i+1]);
61 output_line(buf);
62 return;
63 }
64 *dp++ = '\"';
65 for (; i < rxpkt_len; i++) {
66 c = rxpkt[i];
67 if (c & 0x80) {
68 *dp++ = 'M';
69 *dp++ = '-';
70 c &= 0x7F;
71 }
72 if (c < 0x20) {
73 *dp++ = '^';
74 *dp++ = c + '@';
75 } else if (c == 0x7F) {
76 *dp++ = '^';
77 *dp++ = '?';
78 } else
79 *dp++ = c;
80 }
81 *dp++ = '\"';
82 *dp = '\0';
83 output_line(buf);
84 }
85
86 static void
87 print_malformed()
88 {
89 char buf[MAX_PKT_FROM_TARGET*3+6];
90 int i;
91 char *dp;
92
93 dp = buf;
94 strcpy(dp, "G23 UNK:"); 72 strcpy(dp, "G23 UNK:");
95 dp += 8; 73 dp += 8;
96 for (i = 1; i < rxpkt_len; i++) { 74 for (i = 1; i < rxpkt_len; i++) {
97 sprintf(dp, " %02X", rxpkt[i]); 75 sprintf(dp, " %02X", rxpkt[i]);
98 dp += 3; 76 dp += 3;
99 } 77 }
100 *dp = '\0'; 78 *dp = '\0';
101 output_line(buf); 79 output_line(fmtbuf);
80 }
81
82 static int
83 entity_name_well_formed(p)
84 char *p;
85 {
86 int i, len;
87
88 if (!isupper(p[0]))
89 return(0);
90 for (i = 0; i < 4; i++)
91 if (!isalnum(p[i]))
92 break;
93 len = i;
94 for (; i < 4; i++)
95 if (p[i] != ' ')
96 return(0);
97 return(len);
98 }
99
100 static void
101 print_entity_name(raw)
102 char *raw;
103 {
104 int len;
105
106 len = entity_name_well_formed(raw);
107 if (len)
108 sprintf(fmtbuf_ptr, "%.*s", len, raw);
109 else
110 sprintf(fmtbuf_ptr, "\"%.4s\"", raw);
111 fmtbuf_ptr = index(fmtbuf_ptr, '\0');
112 }
113
114 static void
115 print_common_hdr(typestr)
116 char *typestr;
117 {
118 sprintf(fmtbuf, "G23 %s id=%02X ts=%02X%02X%02X%02X ", typestr,
119 rxpkt[1], rxpkt[7], rxpkt[6], rxpkt[5], rxpkt[4]);
120 fmtbuf_ptr = index(fmtbuf, '\0');
121 print_entity_name(rxpkt + 8);
122 *fmtbuf_ptr++ = '-';
123 *fmtbuf_ptr++ = '>';
124 print_entity_name(rxpkt + 12);
125 *fmtbuf_ptr++ = ' ';
126 }
127
128 static void
129 format_text(start_off)
130 {
131 int i, c;
132
133 *fmtbuf_ptr++ = '\"';
134 for (i = start_off; i < rxpkt_len; i++) {
135 c = rxpkt[i];
136 if (c & 0x80) {
137 *fmtbuf_ptr++ = 'M';
138 *fmtbuf_ptr++ = '-';
139 c &= 0x7F;
140 }
141 if (c < 0x20) {
142 *fmtbuf_ptr++ = '^';
143 *fmtbuf_ptr++ = c + '@';
144 } else if (c == 0x7F) {
145 *fmtbuf_ptr++ = '^';
146 *fmtbuf_ptr++ = '?';
147 } else
148 *fmtbuf_ptr++ = c;
149 }
150 *fmtbuf_ptr++ = '\"';
151 *fmtbuf_ptr = '\0';
152 output_line(fmtbuf);
153 }
154
155 static void
156 format_compressed_trace(start_off)
157 {
158 int i;
159
160 i = start_off + 1;
161 sprintf(fmtbuf_ptr, "%d", rxpkt[i+1] << 8 | rxpkt[i]);
162 fmtbuf_ptr = index(fmtbuf_ptr, '\0');
163 i += 4;
164 for (; i < rxpkt_len; i++) {
165 sprintf(fmtbuf_ptr, " %02X", rxpkt[i]);
166 fmtbuf_ptr += 3;
167 }
168 *fmtbuf_ptr = '\0';
169 output_line(fmtbuf);
170 }
171
172 static void
173 format_trace()
174 {
175 int i;
176
177 i = 16;
178 if (rxpkt[i] < 0x20) {
179 sprintf(fmtbuf_ptr, "tc=%02X ", rxpkt[i]);
180 fmtbuf_ptr += 6;
181 i++;
182 }
183 if (rxpkt_len - i >= 5 && rxpkt[i] == '%' &&
184 !rxpkt[i+3] && !rxpkt[i+4])
185 format_compressed_trace(i);
186 else
187 format_text(i);
188 }
189
190 static void
191 format_psprim()
192 {
193 int i;
194
195 /* original destination */
196 *fmtbuf_ptr++ = '(';
197 print_entity_name(rxpkt + 16);
198 *fmtbuf_ptr++ = ')';
199 /* opcode */
200 sprintf(fmtbuf_ptr, " %02X%02X%02X%02X",
201 rxpkt[23], rxpkt[22], rxpkt[21], rxpkt[20]);
202 fmtbuf_ptr += 9;
203 for (i = 24; i < rxpkt_len; i++) {
204 sprintf(fmtbuf_ptr, " %02X", rxpkt[i]);
205 fmtbuf_ptr += 3;
206 }
207 *fmtbuf_ptr = '\0';
208 output_line(fmtbuf);
102 } 209 }
103 210
104 void 211 void
105 print_g23_trace() 212 print_g23_trace()
106 { 213 {
107 if (is_well_formed()) 214 if (!basic_checks()) {
108 print_well_formed();
109 else
110 print_malformed(); 215 print_malformed();
111 } 216 return;
217 }
218 /* dispatch by type */
219 switch (rxpkt[1] & 0x30) {
220 case 0x10:
221 /* PS primitive */
222 if (psprim_extra_checks()) {
223 print_common_hdr("PSprim");
224 format_psprim();
225 } else
226 print_malformed();
227 return;
228 case 0x20:
229 /* trace */
230 print_common_hdr("trace");
231 format_trace();
232 return;
233 case 0x30:
234 /* system primitive */
235 print_common_hdr("sysprim");
236 format_text(16);
237 return;
238 default:
239 print_malformed();
240 }
241 }