FreeCalypso > hg > freecalypso-sw
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 } |