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