This source file includes following definitions.
- get_code_2_str
- get_bits
- sngisdn_trace_q921
- sngisdn_trace_q931
- sngisdn_decode_ie
- print_hex_dump
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 #include "ftmod_sangoma_isdn.h"
36 #include "ftmod_sangoma_isdn_trace.h"
37
38 #define OCTET(x) (ieData[x-1] & 0xFF)
39
40 void print_hex_dump(char* str, uint32_t *str_len, uint8_t* data, uint32_t index_start, uint32_t index_end);
41 void sngisdn_trace_q921(char* str, uint8_t* data, uint32_t data_len);
42 void sngisdn_trace_q931(char* str, uint8_t* data, uint32_t data_len);
43 uint32_t sngisdn_decode_ie(char *str, uint32_t *str_len, uint8_t current_codeset, uint8_t *data, uint16_t index_start);
44
45 uint8_t get_bits(uint8_t octet, uint8_t bitLo, uint8_t bitHi);
46 char* get_code_2_str(int code, struct code2str *pCodeTable);
47
48 char* get_code_2_str(int code, struct code2str *pCodeTable)
49 {
50 struct code2str* pCode2txt;
51 pCode2txt = pCodeTable;
52 while(pCode2txt) {
53 if(pCode2txt->code >= 0) {
54 if (pCode2txt->code == code) {
55 return pCode2txt->text;
56 }
57 pCode2txt++;
58 } else {
59
60 return pCode2txt->text;
61 }
62 }
63 return (char*)"unknown";
64 }
65
66
67 uint8_t get_bits(uint8_t octet, uint8_t bitLo, uint8_t bitHi)
68 {
69 if (!bitLo || !bitHi) {
70 return 0;
71 }
72 if (bitLo > bitHi) {
73 return 0;
74 }
75
76 bitLo--;
77 bitHi--;
78
79 switch(bitHi - bitLo) {
80 case 0:
81 return (octet >> bitLo) & 0x01;
82 case 1:
83 return (octet >> bitLo) & 0x03;
84 case 2:
85 return (octet >> bitLo) & 0x07;
86 case 3:
87 return (octet >> bitLo) & 0x0F;
88 case 4:
89 return (octet >> bitLo) & 0x1F;
90 case 5:
91 return (octet >> bitLo) & 0x3F;
92 case 6:
93 return (octet >> bitLo) & 0x7F;
94 case 7:
95 return (octet >> bitLo) & 0xFF;
96 }
97 return 0;
98 }
99
100 void sngisdn_trace_q921(char* str, uint8_t* data, uint32_t data_len)
101 {
102 int str_len;
103 int i;
104 uint8_t sapi, cr, ea, tei, ns, nr, pf, p, cmd;
105 uint8_t frame_format = 0;
106
107 str_len = 0;
108
109 if(data_len >= 2) {
110 switch ((int)data[2] & 0x03) {
111 case 0: case 2:
112 frame_format = I_FRAME;
113 break;
114 case 1:
115 frame_format = S_FRAME;
116 break;
117 case 3:
118 frame_format = U_FRAME;
119 break;
120 }
121 }
122
123 str_len+= sprintf(&str[str_len], " format: %s\n",
124 get_code_2_str(frame_format, dcodQ921FrameFormatTable));
125
126 for(i=0; i < data_len; i++) {
127 switch(i) {
128 case 0:
129 sapi = (uint8_t)((data[i]>>2) & 0x3F);
130 cr = (uint8_t)((data[i]>>1) & 0x1);
131 ea = (uint8_t)(data[i] & 0x1);
132 str_len+= sprintf(&str[str_len], " sapi: %03d c/r: %01d ea: %01d\n", sapi, cr, ea);
133 break;
134 case 1:
135 tei = (uint8_t)((data[i]>>1) & 0x7F);
136 ea = (uint8_t)(data[i] & 0x1);
137 str_len+= sprintf(&str[str_len], " tei: %03d ea: %01d\n", tei, ea);
138 break;
139 case 2:
140 switch(frame_format) {
141 case I_FRAME:
142 ns = (uint8_t)((data[i]>>1) & 0x7F);
143 nr = (uint8_t)((data[i+1]>>1) & 0x7F);
144 p = (uint8_t)(data[i+1] & 0x01);
145 str_len+= sprintf(&str[str_len], " n(s): %03d\n n(r): %03d p: %01d\n", ns, nr, p);
146 break;
147 case S_FRAME:
148 nr = (uint8_t)((data[i+1]>>1) & 0x7F);
149 pf = (uint8_t)(data[i+1] & 0x01);
150 str_len+= sprintf(&str[str_len], " n(r): %03d p/f: %01d\n", nr, pf);
151
152 cmd = (uint8_t)((data[i]>>2) & 0x03);
153 str_len+= sprintf(&str[str_len], " cmd: %s\n", get_code_2_str(cmd, dcodQ921SupervisoryCmdTable));
154
155 break;
156 case U_FRAME:
157 pf = (uint8_t)((data[i]>>4) & 0x01);
158 str_len+= sprintf(&str[str_len], " p/f: %01d\n", pf);
159
160 cmd = (uint8_t)((data[i]>>2) & 0x03);
161 cmd |= (uint8_t)((data[i]>>5) & 0x07);
162
163 str_len+= sprintf(&str[str_len], " cmd: %s\n", get_code_2_str(cmd, dcodQ921UnnumberedCmdTable));
164 break;
165 }
166 break;
167 }
168 }
169 return;
170 }
171
172 void sngisdn_trace_q931(char* str, uint8_t* data, uint32_t data_len)
173 {
174 uint32_t str_len;
175 uint8_t prot_disc, callRefFlag;
176 uint16_t lenCallRef, c, i;
177 uint8_t current_codeset = 0;
178
179 str_len = 0;
180
181
182 prot_disc = (uint8_t)data[0];
183 str_len += sprintf(&str[str_len], " Prot Disc:%s (0x%02x)\n", get_code_2_str(prot_disc, dcodQ931ProtDiscTable), prot_disc);
184
185
186
187
188
189 lenCallRef = (uint8_t) (data[1] & 0x0F);
190
191 str_len += sprintf(&str[str_len], " Call Ref:");
192 c=2;
193 callRefFlag = get_bits(data[c], 8,8);
194 for(i=0; i<(2*lenCallRef);i++) {
195 if(i==0) {
196 str_len += sprintf(&str[str_len], "%s%s",
197 get_code_2_str((uint8_t)(data[c] & 0x70), dcodQ931CallRefHiTable),
198 get_code_2_str((uint8_t)(data[c] & 0x0F), dcodQ931CallRefLoTable));
199 } else {
200 str_len += sprintf(&str[str_len], "%s%s",
201 get_code_2_str((uint8_t)(data[c] & 0xF0), dcodQ931CallRefHiTable),
202 get_code_2_str((uint8_t)(data[c] & 0x0F), dcodQ931CallRefLoTable));
203 }
204
205 i=i+1;
206 c=c+1;
207 }
208 str_len += sprintf(&str[str_len], " (%s side)\n", callRefFlag?"Destination":"Originating");
209
210
211 str_len+= sprintf(&str[str_len], " Type:%s (0x%x)\n", get_code_2_str((int)(data[2+lenCallRef] & 0xFF), dcodQ931MsgTypeTable), (int)(data[2+lenCallRef] & 0xFF));
212
213
214 for(i=3+lenCallRef; i < data_len; i++) {
215 switch (data[i] & 0xF8) {
216 case Q931_LOCKING_SHIFT:
217 current_codeset = (data[i] & 0x7);
218 str_len+= sprintf(&str[str_len], "Codeset shift to %d (locking)\n", current_codeset);
219 continue;
220 case Q931_NON_LOCKING_SHIFT:
221 current_codeset = (data[i] & 0x7);
222 str_len+= sprintf(&str[str_len], "Codeset shift to %d (non-locking)\n", current_codeset);
223 continue;
224 }
225 i+= sngisdn_decode_ie(str, &str_len, current_codeset, data, i);
226 }
227 print_hex_dump(str, &str_len, (uint8_t*) data, 0, data_len);
228 return;
229 }
230
231 uint32_t sngisdn_decode_ie(char *str, uint32_t *str_len, uint8_t current_codeset, uint8_t *data, uint16_t index_start)
232 {
233 unsigned char* ieData;
234 uint8_t ieId;
235 uint32_t len = 0;
236 int index_end;
237
238 ieData = (unsigned char*) &data[index_start];
239
240 ieId = OCTET(1);
241 len = OCTET(2);
242 index_end = index_start+len+1;
243
244 *str_len += sprintf(&str[*str_len], " %s:", get_code_2_str(data[index_start], dcodQ931IEIDTable));
245 switch(ieId) {
246 case PROT_Q931_IE_BEARER_CAP:
247 {
248 uint8_t codingStandard, infTransferCap, transferMode, infTransferRate, usrL1Prot;
249
250 codingStandard = get_bits(OCTET(3),6,7);
251 infTransferCap = get_bits(OCTET(3),1,5);
252 transferMode = get_bits(OCTET(4),6,7);
253 infTransferRate = get_bits(OCTET(4),1,5);
254 usrL1Prot = get_bits(OCTET(5),1,5);
255
256 *str_len+= sprintf(&str[*str_len], "Coding:%s(%d) TransferCap:%s(%d) TransferRate:%s(%d) L1Prot:%s(%d)\n",
257 get_code_2_str(codingStandard, dcodQ931BcCodingStandardTable), codingStandard,
258 get_code_2_str(infTransferCap, dcodQ931BcInfTransferCapTable), infTransferCap,
259 get_code_2_str(infTransferRate, dcodQ931BcInfTransferRateTable), infTransferRate,
260 get_code_2_str(usrL1Prot, dcodQ931BcusrL1ProtTable), usrL1Prot);
261 }
262 break;
263 case PROT_Q931_IE_CAUSE:
264 {
265 uint8_t codingStandard, location, cause,diagOct = 5;
266 codingStandard = get_bits(OCTET(3),6,7);
267 location = get_bits(OCTET(3),1,4);
268
269 cause = get_bits(OCTET(4),1,7);
270
271 *str_len+= sprintf(&str[*str_len], "coding:%s(%d) location:%s(%d) val:%s(%d)\n",
272 get_code_2_str(codingStandard, dcodQ931BcCodingStandardTable), codingStandard,
273 get_code_2_str(location,dcodQ931IelocationTable), location,
274 get_code_2_str(cause, dcodQ931CauseCodeTable),
275 cause);
276 switch(cause) {
277 case PROT_Q931_RELEASE_CAUSE_IE_NOT_EXIST:
278 while(diagOct++ < len) {
279 *str_len+= sprintf(&str[*str_len], " %d:IE %s(0x%02x)\n",
280 diagOct,
281 get_code_2_str(OCTET(diagOct), dcodQ931IEIDTable),
282 OCTET(diagOct));
283 }
284 break;
285 case PROT_Q931_RELEASE_CAUSE_WRONG_CALL_STATE:
286 while(diagOct++ < len) {
287 *str_len+= sprintf(&str[*str_len], " %d:Message %s(0x%02x)\n",
288 diagOct,
289 get_code_2_str(OCTET(diagOct), dcodQ931MsgTypeTable),
290 OCTET(diagOct));
291 }
292 break;
293 case PROT_Q931_RECOVERY_ON_TIMER_EXPIRE:
294 *str_len+= sprintf(&str[*str_len], " Timer T\n");
295 while(diagOct++ < len) {
296 if(OCTET(diagOct) >= ' ' && OCTET(diagOct) < 0x7f) {
297 *str_len+= sprintf(&str[*str_len], "%c", OCTET(diagOct));
298 } else {
299 *str_len+= sprintf(&str[*str_len], ".");
300 }
301 }
302 break;
303 default:
304 while(diagOct++ < len) {
305 *str_len+= sprintf(&str[*str_len], " %d: 0x%02x\n",
306 diagOct,
307 OCTET(diagOct));
308 }
309 break;
310 }
311 }
312 break;
313 case PROT_Q931_IE_CHANNEL_ID:
314 {
315 uint8_t infoChannelSelection=0;
316 uint8_t prefExclusive=0;
317 uint8_t ifaceIdPresent=0;
318 uint8_t ifaceIdentifier = 0;
319 uint8_t chanType=0, numberMap=0, codingStandard=0;
320 uint8_t channelNo = 0;
321
322 infoChannelSelection = get_bits(OCTET(3),1,2);
323 prefExclusive = get_bits(OCTET(3),4,4);
324 ifaceIdPresent = get_bits(OCTET(3),7,7);
325
326 if (ifaceIdPresent) {
327 ifaceIdentifier= get_bits(OCTET(4),1,7);
328 chanType = get_bits(OCTET(5),1,4);
329 numberMap = get_bits(OCTET(5),5,5);
330 codingStandard = get_bits(OCTET(5),6,7);
331 channelNo = get_bits(OCTET(6),1,7);
332 } else {
333 chanType = get_bits(OCTET(4),1,4);
334 numberMap = get_bits(OCTET(4),5,5);
335 codingStandard = get_bits(OCTET(4),6,7);
336 channelNo = get_bits(OCTET(5),1,7);
337 }
338
339 if (numberMap) {
340 *str_len+= sprintf(&str[*str_len], " MAP:%s ", get_code_2_str(infoChannelSelection, dcodQ931InfoChannelSelTable));
341 } else {
342 *str_len+= sprintf(&str[*str_len], "No:%d ", channelNo);
343 }
344
345 *str_len+= sprintf(&str[*str_len], "Type:%s(%d) %s ", get_code_2_str(chanType,dcodQ931ChanTypeTable), chanType, (numberMap)? "Map":"");
346 *str_len+= sprintf(&str[*str_len], "%s/%s \n",
347 (prefExclusive)? "Exclusive":"Preferred",
348 (ifaceIdPresent)? "Explicit":"Implicit");
349 }
350 break;
351 case PROT_Q931_IE_CALLING_PARTY_NUMBER:
352 {
353 uint8_t plan, type, screening = 0, presentation = 0, callingNumOct, j;
354 uint8_t screeningEnabled = 0, presentationEnabled = 0;
355 char callingNumDigits[32];
356 memset(callingNumDigits, 0, sizeof(callingNumDigits));
357
358 plan = get_bits(OCTET(3),1,4);
359 type = get_bits(OCTET(3),5,7);
360
361 if(!get_bits(OCTET(3),8,8)) {
362 screening = get_bits(OCTET(4),1,2);
363 presentation = get_bits(OCTET(4),6,7);
364 screeningEnabled = 1;
365 presentationEnabled = 1;
366 callingNumOct = 4;
367 } else {
368 callingNumOct = 3;
369 }
370 if(len >= sizeof(callingNumDigits)) {
371 len = sizeof(callingNumDigits)-1;
372 }
373 j = 0;
374 while(callingNumOct++ <= len+1) {
375 callingNumDigits[j++]=ia5[get_bits(OCTET(callingNumOct),1,4)][get_bits(OCTET(callingNumOct),5,8)];
376 }
377 callingNumDigits[j]='\0';
378 *str_len+= sprintf(&str[*str_len], "%s(l:%d) plan:%s(%d) type:%s(%d)",
379
380 callingNumDigits, j,
381 get_code_2_str(plan, dcodQ931NumberingPlanTable), plan,
382 get_code_2_str(type, dcodQ931TypeofNumberTable), type);
383
384 if (presentationEnabled||screeningEnabled) {
385 *str_len+= sprintf(&str[*str_len], "scr:%s(%d) pres:%s(%d)\n",
386 get_code_2_str(screening, dcodQ931ScreeningTable), screening,
387 get_code_2_str(presentation, dcodQ931PresentationTable), presentation);
388 } else {
389 *str_len+= sprintf(&str[*str_len], "\n");
390 }
391 }
392 break;
393
394 case PROT_Q931_IE_CALLED_PARTY_NUMBER:
395 {
396 uint8_t plan, type, calledNumOct,j;
397 char calledNumDigits[32];
398 memset(calledNumDigits, 0, sizeof(calledNumDigits));
399 plan = get_bits(OCTET(3),1,4);
400 type = get_bits(OCTET(3),5,7);
401
402 if(len >= sizeof(calledNumDigits)) {
403 len = sizeof(calledNumDigits)-1;
404 }
405 calledNumOct = 3;
406 j = 0;
407 while(calledNumOct++ <= len+1) {
408 calledNumDigits[j++]=ia5[get_bits(OCTET(calledNumOct),1,4)][get_bits(OCTET(calledNumOct),5,8)];
409 }
410 calledNumDigits[j]='\0';
411 *str_len+= sprintf(&str[*str_len], "%s(l:%d) plan:%s(%d) type:%s(%d)\n",
412 calledNumDigits, j,
413 get_code_2_str(plan, dcodQ931NumberingPlanTable), plan,
414 get_code_2_str(type, dcodQ931TypeofNumberTable), type);
415 }
416 break;
417 case PROT_Q931_IE_REDIRECTING_NUMBER:
418 {
419 uint8_t plan, type, screening = 0, presentation = 0, reason = 0, rdnisOct,j;
420 uint8_t screeningEnabled = 0, presentationEnabled = 0, reasonEnabled = 0;
421 char rdnis_string[32];
422 memset(rdnis_string, 0, sizeof(rdnis_string));
423 rdnisOct = 5;
424 plan = get_bits(OCTET(3),1,4);
425 type = get_bits(OCTET(3),5,7);
426
427 if(!get_bits(OCTET(3),8,8)) {
428 rdnisOct++;
429 screening = get_bits(OCTET(4),1,2);
430 presentation = get_bits(OCTET(4),6,7);
431 screeningEnabled = 1;
432 presentationEnabled = 1;
433 if (!get_bits(OCTET(4),8,8)) {
434 rdnisOct++;
435 reason = get_bits(OCTET(5),1,4);
436 reasonEnabled = 1;
437 }
438 }
439
440 if(len >= sizeof(rdnis_string)) {
441 len = sizeof(rdnis_string)-1;
442 }
443
444 j = 0;
445 while(rdnisOct++ <= len+1) {
446 rdnis_string[j++]=ia5[get_bits(OCTET(rdnisOct),1,4)][get_bits(OCTET(rdnisOct),5,8)];
447 }
448
449 rdnis_string[j]='\0';
450 *str_len+= sprintf(&str[*str_len], "%s(l:%d) plan:%s(%d) type:%s(%d)",
451 rdnis_string, j,
452 get_code_2_str(plan, dcodQ931NumberingPlanTable), plan,
453 get_code_2_str(type, dcodQ931TypeofNumberTable), type);
454
455 if(presentationEnabled || screeningEnabled) {
456 *str_len+= sprintf(&str[*str_len], "scr:%s(%d) pres:%s(%d)",
457 get_code_2_str(screening, dcodQ931ScreeningTable), screening,
458 get_code_2_str(presentation, dcodQ931PresentationTable), presentation);
459 }
460
461 if(reasonEnabled) {
462 *str_len+= sprintf(&str[*str_len], "reason:%s(%d)",
463 get_code_2_str(reason, dcodQ931ReasonTable), reason);
464 }
465 *str_len+= sprintf(&str[*str_len], "\n");
466 }
467 break;
468 case PROT_Q931_IE_USER_USER:
469 {
470 uint8_t protDiscr = 0x00, j, uui_stringOct;
471 char uui_string[32];
472 memset(uui_string, 0, sizeof(uui_string));
473 protDiscr = OCTET(3);
474 uui_stringOct = 3;
475 if (protDiscr != 0x04) {
476 *str_len+= sprintf(&str[*str_len], "%s (0x%02x)\n",
477 get_code_2_str(protDiscr, dcodQ931UuiProtDiscrTable), protDiscr);
478 } else {
479 j = 0;
480
481 if(len >= sizeof(uui_string)) {
482 len = sizeof(uui_string)-1;
483 }
484 while(uui_stringOct++ <= len+1) {
485 uui_string[j++]=ia5[get_bits(OCTET(uui_stringOct),1,4)][get_bits(OCTET(uui_stringOct),5,8)];
486 }
487 uui_string[j]='\0';
488 *str_len+= sprintf(&str[*str_len], " %s (0x%02x) <%s>\n",
489 get_code_2_str(protDiscr, dcodQ931UuiProtDiscrTable), protDiscr,
490 uui_string);
491 }
492 }
493 break;
494 case PROT_Q931_IE_DISPLAY:
495 {
496 uint8_t displayStrOct=2, j;
497 char displayStr[82];
498 memset(displayStr, 0, sizeof(displayStr));
499
500 if(get_bits(OCTET(3),8,8)) {
501 displayStrOct++;
502 }
503 j = 0;
504 if(len >= sizeof(displayStr)) {
505 len = sizeof(displayStr)-1;
506 }
507 while(displayStrOct++ <= len+1) {
508 displayStr[j++]=ia5[get_bits(OCTET(displayStrOct),1,4)][get_bits(OCTET(displayStrOct),5,8)];
509 }
510 displayStr[j]='\0';
511 *str_len+= sprintf(&str[*str_len], "%s(l:%d)\n",
512 displayStr, len);
513 }
514 break;
515 case PROT_Q931_IE_RESTART_IND:
516 {
517 uint8_t indClass;
518 indClass = get_bits(OCTET(3),1,3);
519 *str_len+= sprintf(&str[*str_len], "class:%s(%d)\n",
520 get_code_2_str(indClass,dcodQ931RestartIndClassTable), indClass);
521 }
522 break;
523 case PROT_Q931_IE_PROGRESS_IND:
524 {
525 uint8_t codingStandard, location, progressDescr;
526 codingStandard = get_bits(OCTET(3),6,7);
527 location = get_bits(OCTET(3),1,4);
528 progressDescr = get_bits(OCTET(4),1,7);
529 *str_len+= sprintf(&str[*str_len], "coding:%s(%d) location:%s(%d) descr:%s(%d)\n",
530 get_code_2_str(codingStandard,dcodQ931BcCodingStandardTable), codingStandard,
531 get_code_2_str(location,dcodQ931IelocationTable), location,
532 get_code_2_str(progressDescr,dcodQ931IeprogressDescrTable), progressDescr);
533 }
534 break;
535 case PROT_Q931_IE_KEYPAD_FACILITY:
536 {
537 uint8_t keypadFacilityStrOct = 3, j;
538 char keypadFacilityStr[82];
539 memset(keypadFacilityStr, 0, sizeof(keypadFacilityStr));
540
541 j = 0;
542 if(len >= sizeof(keypadFacilityStr)) {
543 len = sizeof(keypadFacilityStr)-1;
544 }
545 while(keypadFacilityStrOct++ < len+1) {
546 keypadFacilityStr[j++]=ia5[get_bits(OCTET(keypadFacilityStrOct),1,4)][get_bits(OCTET(keypadFacilityStrOct),5,8)];
547 }
548 keypadFacilityStr[j]='\0';
549 *str_len+= sprintf(&str[*str_len], " digits:%s(l:%d)\n",
550 keypadFacilityStr, len);
551 }
552 break;
553 case PROT_Q931_IE_FACILITY:
554 {
555 uint8_t protProfile;
556 protProfile = get_bits(OCTET(3),1,5);
557 *str_len+= sprintf(&str[*str_len], "Prot profile:%s(%d)\n",
558 get_code_2_str(protProfile,dcodQ931IeFacilityProtProfileTable), protProfile);
559 }
560 break;
561 case PROT_Q931_IE_GENERIC_DIGITS:
562 {
563 uint8_t encoding,type;
564 int value = 0;
565
566 encoding = get_bits(OCTET(3),6,8);
567 type = get_bits(OCTET(3),1,5);
568
569 *str_len+= sprintf(&str[*str_len], "encoding:%s(%d) type:%s(%d) ",
570 get_code_2_str(encoding,dcodQ931GenDigitsEncodingTable), encoding,
571 get_code_2_str(encoding,dcodQ931GenDigitsTypeTable), type);
572
573 if (len > 1) {
574 uint32_t j=0;
575
576 while(++j < len) {
577 switch(encoding) {
578 case 0:
579 case 1:
580 {
581 uint8_t byte = OCTET(j+3);
582 value = (get_bits(byte,1,4)*10) + get_bits(byte,5,8) + (value*10);
583 }
584 break;
585 case 2:
586 value = value*10 + OCTET(j+3)-'0';
587 *str_len+= sprintf(&str[*str_len], "%c", OCTET(j+3));
588 break;
589 case 3:
590
591 *str_len+= sprintf(&str[*str_len], "Binary encoded");
592 break;
593 }
594 }
595 *str_len+= sprintf(&str[*str_len], " ");
596 switch(type) {
597 case 4:
598 *str_len+= sprintf(&str[*str_len], "ani2:%s(%d)", get_code_2_str(value,dcodQ931LineInfoTable), value);
599 break;
600 case 5:
601 *str_len+= sprintf(&str[*str_len], "Caller ID not implemented\n");
602 break;
603 }
604 }
605 *str_len+= sprintf(&str[*str_len], "\n");
606 print_hex_dump(str, str_len, (uint8_t*) data, index_start, index_end);
607 }
608 break;
609 case PROT_Q931_IE_SENDING_COMPLETE:
610
611
612 *str_len+= sprintf(&str[*str_len], "\n");
613 return 0;
614 break;
615 case PROT_Q931_IE_CALLED_PARTY_SUBADDRESS:
616 case PROT_Q931_IE_REDIRECTION_NUMBER:
617 case PROT_Q931_IE_NOTIFICATION_IND:
618 case PROT_Q931_IE_DATE_TIME:
619 case PROT_Q931_IE_INFORMATION_REQUEST:
620 case PROT_Q931_IE_SIGNAL:
621 case PROT_Q931_IE_SWITCHOOK:
622 case PROT_Q931_IE_FEATURE_ACT:
623 case PROT_Q931_IE_FEATURE_IND:
624 case PROT_Q931_IE_INFORMATION_RATE:
625 case PROT_Q931_IE_END_TO_END_TRANSIT_DELAY:
626 case PROT_Q931_IE_TRANSIT_DELAY_SELECT_IND:
627 case PROT_Q931_IE_PACKET_LAYER_BINARY_PARAMS:
628 case PROT_Q931_IE_PACKET_LAYER_WINDOW_SIZE:
629 case PROT_Q931_IE_PACKET_LAYER_SIZE:
630 case PROT_Q931_IE_TRANSIT_NETWORK_SELECTION:
631 case PROT_Q931_IE_LOW_LAYER_COMPAT:
632 case PROT_Q931_IE_HIGH_LAYER_COMPAT:
633 case PROT_Q931_IE_ESCAPE_FOR_EXTENSION:
634 case PROT_Q931_IE_CALL_IDENTITY:
635 case PROT_Q931_IE_CALL_STATE:
636 case PROT_Q931_IE_SEGMENTED_MESSAGE:
637 case PROT_Q931_IE_NETWORK_SPF_FACILITY:
638 case PROT_Q931_IE_CALLING_PARTY_SUBADDRESS:
639 default:
640 {
641 *str_len += sprintf(&str[*str_len], "Undecoded");
642 print_hex_dump((char*)str, str_len, data, index_start, index_end);
643 }
644 break;
645 }
646
647 return len+1;
648 }
649
650 void print_hex_dump(char* str, uint32_t *str_len, uint8_t* data, uint32_t index_start, uint32_t index_end)
651 {
652 int k;
653 *str_len += sprintf(&str[*str_len], " [ ");
654 for(k=index_start; k <= index_end; k++) {
655 if (k && !(k%32)) {
656 *str_len += sprintf(&str[*str_len], "\n ");
657 }
658 *str_len += sprintf(&str[*str_len], "%02x ", data[k]);
659 }
660 *str_len += sprintf(&str[*str_len], "]\n");
661 return;
662 }
663
664