comparison rvinterf/old/format_g23.c @ 334:73a2b359b3cd

rvinterf/lowlevel/format_g23.c retired
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Tue, 22 Apr 2014 05:52:38 +0000
parents rvinterf/lowlevel/format_g23.c@05874f1ddacb
children
comparison
equal deleted inserted replaced
333:2ac2f6d88bb2 334:73a2b359b3cd
1 /*
2 * This module implements the decoding of G23 trace packets into
3 * human-readable form - or more precisely, traces, system primitives
4 * and other packets that can be emitted through GPF on targets.
5 * The decoding is based on my (Space Falcon's) understanding
6 * of the packet format, which is in turn based on the GPF sources
7 * available to us, now integrated under gsm-fw/gpf.
8 */
9
10 #include <sys/types.h>
11 #include <ctype.h>
12 #include <stdio.h>
13 #include <string.h>
14 #include <strings.h>
15 #include "../include/pktmux.h"
16 #include "../include/limits.h"
17
18 extern u_char rxpkt[];
19 extern size_t rxpkt_len;
20 extern char fmtbuf[];
21
22 static char *fmtbuf_ptr;
23
24 static int
25 basic_checks()
26 {
27 int i, c;
28
29 if (rxpkt_len < 17)
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 */
39 for (i = 8; i < 16; i++) {
40 c = rxpkt[i];
41 if (c < ' ' || c > '~')
42 return(0);
43 }
44 /* basic checks pass */
45 return(1);
46 }
47
48 static int
49 psprim_extra_checks()
50 {
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;
69 char *dp;
70
71 dp = fmtbuf;
72 strcpy(dp, "G23 UNK:");
73 dp += 8;
74 for (i = 1; i < rxpkt_len; i++) {
75 sprintf(dp, " %02X", rxpkt[i]);
76 dp += 3;
77 }
78 *dp = '\0';
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);
209 }
210
211 void
212 print_g23_trace()
213 {
214 if (!basic_checks()) {
215 print_malformed();
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 }