No empty .Rs/.Re
[netbsd-mini2440.git] / usr.sbin / isdn / isdntrace / q932_fac.c
blobdad5b6fb80808ff2161a03885341df7e5a352401
1 /*
2 * Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23 * SUCH DAMAGE.
25 *---------------------------------------------------------------------------
27 * q932_fac.c - decode Q.932 facilities
28 * ------------------------------------
30 * $Id: q932_fac.c,v 1.4 2009/04/16 05:56:33 lukem Exp $
32 * $FreeBSD$
34 * last edit-date: [Thu Feb 24 17:36:47 2000]
36 *---------------------------------------------------------------------------
38 * - Q.932 (03/93) Generic Procedures for the Control of
39 * ISDN Supplementaty Services
40 * - Q.950 (03/93) Supplementary Services Protocols, Structure and
41 * General Principles
42 * - ETS 300 179 (10/92) Advice Of Charge: charging information during
43 * the call (AOC-D) supplementary service Service description
44 * - ETS 300 180 (10/92) Advice Of Charge: charging information at the
45 * end of call (AOC-E) supplementary service Service description
46 * - ETS 300 181 (04/93) Advice Of Charge (AOC) supplementary service
47 * Functional capabilities and information flows
48 * - ETS 300 182 (04/93) Advice Of Charge (AOC) supplementary service
49 * Digital Subscriber Signalling System No. one (DSS1) protocol
50 * - X.208 Specification of Abstract Syntax Notation One (ASN.1)
51 * - X.209 Specification of Basic Encoding Rules for
52 * Abstract Syntax Notation One (ASN.1)
53 * - "ASN.1 Abstract Syntax Notation One", Walter Gora, DATACOM-Verlag
54 * 1992, 3rd Edition (ISBN 3-89238-062-7) (german !)
56 *---------------------------------------------------------------------------*/
58 #include "trace.h"
59 #include "q932_fac.h"
61 static int do_component(int length, char *pbuf);
62 static const char *uni_str(int code);
63 static const char *opval_str(int val);
64 static const char *bid_str(int val);
65 static void next_state(char *pbuf, int class, int form, int code, int val);
67 static void object_id(int comp_length, unsigned char *pbuf);
69 static int byte_len;
70 static unsigned char *byte_buf;
71 static int state;
73 /*---------------------------------------------------------------------------*
74 * decode Q.931/Q.932 facility info element
75 *---------------------------------------------------------------------------*/
76 int
77 q932_facility(char *pbuf, unsigned char *buf)
79 int len;
81 sprintf((pbuf+strlen(pbuf)), "[facility (Q.932): ");
83 buf++; /* length */
85 len = *buf;
87 buf++; /* protocol profile */
89 sprintf((pbuf+strlen(pbuf)), "Protocol=");
91 switch (*buf & 0x1f)
93 case FAC_PROTO_ROP:
94 sprintf((pbuf+strlen(pbuf)), "Remote Operations Protocol\n");
95 break;
97 case FAC_PROTO_CMIP:
98 sprintf((pbuf+strlen(pbuf)), "CMIP Protocol (Q.941), UNSUPPORTED!\n");
99 return(len+2);
100 break;
102 case FAC_PROTO_ACSE:
103 sprintf((pbuf+strlen(pbuf)), "ACSE Protocol (X.217/X.227), UNSUPPORTED!\n");
104 return(len+2);
105 break;
107 default:
108 sprintf((pbuf+strlen(pbuf)), "Unknown Protocol (val = 0x%x), UNSUPPORTED!\n", *buf & 0x1f);
109 return(len+2);
110 break;
113 /* next byte */
115 buf++;
116 len--;
118 /* initialize variables for do_component */
120 byte_len = 0;
121 byte_buf = buf;
122 state = ST_EXP_COMP_TYP;
124 /* decode facility */
126 do_component(len, pbuf);
128 sprintf((pbuf+(strlen(pbuf)-1)), "]"); /* XXX replace last newline */
130 return(len+3);
133 /*---------------------------------------------------------------------------*
134 * handle a component recursively
135 *---------------------------------------------------------------------------*/
136 static int
137 do_component(int length, char *pbuf)
139 int comp_tag_class; /* component tag class */
140 int comp_tag_form; /* component form: constructor or primitive */
141 int comp_tag_code; /* component code depending on class */
142 int comp_length = 0; /* component length */
144 #ifdef FAC_DEBUG
145 sprintf((pbuf+strlen(pbuf)), "ENTER - comp_length = %d, byte_len = %d, length =%d\n", comp_length, byte_len, length);
146 #endif
148 again:
150 #ifdef FAC_DEBUG
151 sprintf((pbuf+strlen(pbuf)), "AGAIN - comp_length = %d, byte_len = %d, length =%d\n", comp_length, byte_len, length);
152 #endif
154 /*----------------------------------------*/
155 /* first component element: component tag */
156 /*----------------------------------------*/
158 /* tag class bits */
160 sprintf((pbuf+strlen(pbuf)), "\t0x%02x Tag: ", *byte_buf);
162 comp_tag_class = (*byte_buf & 0xc0) >> 6;
164 switch (comp_tag_class)
166 case FAC_TAGCLASS_UNI:
167 sprintf((pbuf+strlen(pbuf)), "Universal");
168 break;
169 case FAC_TAGCLASS_APW:
170 sprintf((pbuf+strlen(pbuf)), "Applic-wide");
171 break;
172 case FAC_TAGCLASS_COS:
173 sprintf((pbuf+strlen(pbuf)), "Context-spec");
174 break;
175 case FAC_TAGCLASS_PRU:
176 sprintf((pbuf+strlen(pbuf)), "Private");
177 break;
180 /* tag form bit */
182 comp_tag_form = (*byte_buf & 0x20) > 5;
184 sprintf((pbuf+strlen(pbuf)), ", ");
186 if (comp_tag_form == FAC_TAGFORM_CON)
188 sprintf((pbuf+strlen(pbuf)), "Constructor");
190 else
192 sprintf((pbuf+strlen(pbuf)), "Primitive");
195 /* tag code bits */
197 comp_tag_code = *byte_buf & 0x1f;
199 sprintf((pbuf+strlen(pbuf)), ", ");
201 if (comp_tag_code == 0x1f)
203 comp_tag_code = 0;
205 byte_buf++;
206 byte_len++;
208 while(*byte_buf & 0x80)
210 comp_tag_code += (*byte_buf & 0x7f);
211 byte_buf++;
212 byte_len++;
214 comp_tag_code += (*byte_buf & 0x7f);
215 sprintf((pbuf+strlen(pbuf)), "%d (ext)\n", comp_tag_code);
217 else
219 comp_tag_code = (*byte_buf & 0x1f);
221 if (comp_tag_class == FAC_TAGCLASS_UNI)
223 sprintf((pbuf+strlen(pbuf)), "%s (%d)\n", uni_str(comp_tag_code), comp_tag_code);
225 else
227 sprintf((pbuf+strlen(pbuf)), "code = %d\n", comp_tag_code);
231 byte_buf++;
232 byte_len++;
234 /*--------------------------------------------*/
235 /* second component element: component length */
236 /*--------------------------------------------*/
238 sprintf((pbuf+strlen(pbuf)), "\t0x%02x Len: ", *byte_buf);
240 comp_length = 0;
242 if (*byte_buf & 0x80)
244 int i = *byte_buf & 0x7f;
246 byte_len += i;
248 for (;i > 0;i++)
250 byte_buf++;
251 comp_length += (*byte_buf * (i*256));
253 sprintf((pbuf+strlen(pbuf)), "%d (long form)\n", comp_length);
255 else
257 comp_length = *byte_buf & 0x7f;
258 sprintf((pbuf+strlen(pbuf)), "%d (short form)\n", comp_length);
261 next_state(pbuf, comp_tag_class, comp_tag_form, comp_tag_code, -1);
263 byte_len++;
264 byte_buf++;
266 if (comp_length)
269 /*---------------------------------------------*/
270 /* third component element: component contents */
271 /*---------------------------------------------*/
273 if (comp_tag_form) /* == constructor */
275 do_component(comp_length, pbuf);
277 else
279 int val = 0;
280 if (comp_tag_class == FAC_TAGCLASS_UNI)
282 switch (comp_tag_code)
284 case FAC_CODEUNI_INT:
285 case FAC_CODEUNI_ENUM:
286 case FAC_CODEUNI_BOOL:
287 if (comp_length)
289 int i;
291 sprintf((pbuf+strlen(pbuf)), "\t");
293 for (i = comp_length-1; i >= 0; i--)
295 sprintf((pbuf+strlen(pbuf)), "0x%02x ", *byte_buf);
296 val += (*byte_buf + (i*255));
297 byte_buf++;
298 byte_len++;
299 if (i)
300 sprintf((pbuf+strlen(pbuf)), "\n\t");
302 sprintf((pbuf+strlen(pbuf)), "Val: %d\n", val);
304 break;
306 case FAC_CODEUNI_OBJI: /* object id */
308 if (comp_length)
309 object_id(comp_length, pbuf);
310 break;
312 default:
313 if (comp_length)
315 int i;
317 sprintf((pbuf+strlen(pbuf)), "\t");
319 for (i = comp_length-1; i >= 0; i--)
321 sprintf((pbuf+strlen(pbuf)), "0x%02x = %d", *byte_buf, *byte_buf);
322 if (isprint(*byte_buf))
323 sprintf((pbuf+strlen(pbuf)), " = '%c'", *byte_buf);
324 byte_buf++;
325 byte_len++;
326 if (i)
327 sprintf((pbuf+strlen(pbuf)), "\n\t");
330 break;
334 else /* comp_tag_class != FAC_TAGCLASS_UNI */
336 if (comp_length)
338 int i;
340 sprintf((pbuf+strlen(pbuf)), "\t");
342 for (i = comp_length-1; i >= 0; i--)
344 sprintf((pbuf+strlen(pbuf)), "0x%02x", *byte_buf);
345 val += (*byte_buf + (i*255));
346 byte_buf++;
347 byte_len++;
348 if (i)
349 sprintf((pbuf+strlen(pbuf)), "\n\t");
351 sprintf((pbuf+strlen(pbuf)), "\n");
354 next_state(pbuf, comp_tag_class, comp_tag_form, comp_tag_code, val);
358 #ifdef FAC_DEBUG
359 sprintf((pbuf+strlen(pbuf)), "PREGOTO - comp_length = %d, byte_len = %d, length =%d\n", comp_length, byte_len, length);
360 #endif
361 if (byte_len < length)
362 goto again;
363 #ifdef FAC_DEBUG
364 sprintf((pbuf+strlen(pbuf)), "RETURN - comp_length = %d, byte_len = %d, length =%d\n", comp_length, byte_len, length);
365 #endif
366 return(byte_len);
369 /*---------------------------------------------------------------------------*
370 * print universal id type
371 *---------------------------------------------------------------------------*/
372 static const char *uni_str(int code)
374 static const char *tbl[] = {
375 "BOOLEAN",
376 "INTEGER",
377 "BIT STRING",
378 "OCTET STRING",
379 "NULL",
380 "OBJECT IDENTIFIER",
381 "OBJECT DESCRIPTOR",
382 "EXTERNAL",
383 "REAL",
384 "ENUMERATED",
385 "RESERVED11",
386 "RESERVED12",
387 "RESERVED13",
388 "RESERVED14",
389 "RESERVED15",
390 "SEQUENCE",
391 "SET",
392 "NUMERIC STRING",
393 "PRINTABLE STRING",
394 "TELETEX STRING",
395 "ISO646 STRING",
396 "IA5 STRING",
397 "U TIME",
398 "G TIME",
399 "GRAPHIC STRING",
400 "VISUAL STRING",
401 "GENERAL STRING"
404 if (code >= 1 && code <= (int)(sizeof(tbl) / sizeof(tbl[0])))
405 return(tbl[code-1]);
406 else
407 return("ERROR, Value out of Range!");
410 /*---------------------------------------------------------------------------*
411 * print operation value
412 *---------------------------------------------------------------------------*/
413 static const char *opval_str(int val)
415 static char buffer[80];
416 const char *r;
418 switch (val)
420 case FAC_OPVAL_UUS:
421 r = "uUs";
422 break;
423 case FAC_OPVAL_CUG:
424 r = "cUGCall";
425 break;
426 case FAC_OPVAL_MCID:
427 r = "mCIDRequest";
428 break;
429 case FAC_OPVAL_BTPY:
430 r = "beginTPY";
431 break;
432 case FAC_OPVAL_ETPY:
433 r = "endTPY";
434 break;
435 case FAC_OPVAL_ECT:
436 r = "eCTRequest";
437 break;
438 case FAC_OPVAL_DIV_ACT:
439 r = "activationDiversion";
440 break;
441 case FAC_OPVAL_DIV_DEACT:
442 r = "deactivationDiversion";
443 break;
444 case FAC_OPVAL_DIV_ACTSN:
445 r = "activationStatusNotificationDiv";
446 break;
447 case FAC_OPVAL_DIV_DEACTSN:
448 r = "deactivationStatusNotificationDiv";
449 break;
450 case FAC_OPVAL_DIV_INTER:
451 r = "interrogationDiversion";
452 break;
453 case FAC_OPVAL_DIV_INFO:
454 r = "diversionInformation";
455 break;
456 case FAC_OPVAL_DIV_CALLDEF:
457 r = "callDeflection";
458 break;
459 case FAC_OPVAL_DIV_CALLRER:
460 r = "callRerouting";
461 break;
462 case FAC_OPVAL_DIV_LINF2:
463 r = "divertingLegInformation2";
464 break;
465 case FAC_OPVAL_DIV_INVS:
466 r = "invokeStatus";
467 break;
468 case FAC_OPVAL_DIV_INTER1:
469 r = "interrogationDiversion1";
470 break;
471 case FAC_OPVAL_DIV_LINF1:
472 r = "divertingLegInformation1";
473 break;
474 case FAC_OPVAL_DIV_LINF3:
475 r = "divertingLegInformation3";
476 break;
477 case FAC_OPVAL_ER_CRCO:
478 r = "explicitReservationCreationControl";
479 break;
480 case FAC_OPVAL_ER_MGMT:
481 r = "explicitReservationManagement";
482 break;
483 case FAC_OPVAL_ER_CANC:
484 r = "explicitReservationCancel";
485 break;
486 case FAC_OPVAL_MLPP_QUERY:
487 r = "mLPP lfb Query";
488 break;
489 case FAC_OPVAL_MLPP_CALLR:
490 r = "mLPP Call Request";
491 break;
492 case FAC_OPVAL_MLPP_CALLP:
493 r = "mLPP Call Preemption";
494 break;
495 case FAC_OPVAL_AOC_REQ:
496 r = "chargingRequest";
497 break;
498 case FAC_OPVAL_AOC_S_CUR:
499 r = "aOCSCurrency";
500 break;
501 case FAC_OPVAL_AOC_S_SPC:
502 r = "aOCSSpecialArrangement";
503 break;
504 case FAC_OPVAL_AOC_D_CUR:
505 r = "aOCDCurrency";
506 break;
507 case FAC_OPVAL_AOC_D_UNIT:
508 r = "aOCDChargingUnit";
509 break;
510 case FAC_OPVAL_AOC_E_CUR:
511 r = "aOCECurrency";
512 break;
513 case FAC_OPVAL_AOC_E_UNIT:
514 r = "aOCEChargingUnit";
515 break;
516 case FAC_OPVAL_AOC_IDOFCRG:
517 r = "identificationOfCharge";
518 break;
519 case FAC_OPVAL_CONF_BEG:
520 r = "beginConf";
521 break;
522 case FAC_OPVAL_CONF_ADD:
523 r = "addConf";
524 break;
525 case FAC_OPVAL_CONF_SPLIT:
526 r = "splitConf";
527 break;
528 case FAC_OPVAL_CONF_DROP:
529 r = "dropConf";
530 break;
531 case FAC_OPVAL_CONF_ISOLATE:
532 r = "isolateConf";
533 break;
534 case FAC_OPVAL_CONF_REATT:
535 r = "reattachConf";
536 break;
537 case FAC_OPVAL_CONF_PDISC:
538 r = "partyDISC";
539 break;
540 case FAC_OPVAL_CONF_FCONF:
541 r = "floatConf";
542 break;
543 case FAC_OPVAL_CONF_END:
544 r = "endConf";
545 break;
546 case FAC_OPVAL_CONF_IDCFE:
547 r = "indentifyConferee";
548 break;
549 case FAC_OPVAL_REVC_REQ:
550 r = "requestREV";
551 break;
552 default:
553 sprintf(buffer, "unknown operation value %d!", val);
554 r = buffer;
556 return(r);
559 /*---------------------------------------------------------------------------*
560 * billing id string
561 *---------------------------------------------------------------------------*/
562 static const char *bid_str(int val)
564 static char buffer[80];
565 const char *r;
567 switch (val)
569 case 0:
570 r = "normalCharging";
571 break;
572 case 1:
573 r = "reverseCharging";
574 break;
575 case 2:
576 r = "creditCardCharging";
577 break;
578 case 3:
579 r = "callForwardingUnconditional";
580 break;
581 case 4:
582 r = "callForwardingBusy";
583 break;
584 case 5:
585 r = "callForwardingNoReply";
586 break;
587 case 6:
588 r = "callDeflection";
589 break;
590 case 7:
591 r = "callTransfer";
592 break;
593 default:
594 sprintf(buffer, "unknown billing-id value %d!", val);
595 r = buffer;
597 return(r);
600 /*---------------------------------------------------------------------------*
601 * invoke component
602 *---------------------------------------------------------------------------*/
603 static void
604 F_1_1(char *pbuf, int val)
606 #ifdef ST_DEBUG
607 sprintf((pbuf+strlen(pbuf)), "next_state: exec F_1_1, val = %d\n", val);
608 #endif
609 if (val == -1)
611 sprintf((pbuf+strlen(pbuf)), "\t invokeComponent\n");
612 state = ST_EXP_INV_ID;
616 /*---------------------------------------------------------------------------*
617 * return result
618 *---------------------------------------------------------------------------*/
619 static void
620 F_1_2(char *pbuf, int val)
622 #ifdef ST_DEBUG
623 sprintf((pbuf+strlen(pbuf)), "next_state: exec F_1_2, val = %d\n", val);
624 #endif
625 if (val == -1)
627 sprintf((pbuf+strlen(pbuf)), "\t returnResult\n");
628 state = ST_EXP_RR_INV_ID;
631 /*---------------------------------------------------------------------------*
632 * return error
633 *---------------------------------------------------------------------------*/
634 static void
635 F_1_3(char *pbuf, int val)
637 #ifdef ST_DEBUG
638 sprintf((pbuf+strlen(pbuf)), "next_state: exec F_1_3, val = %d\n", val);
639 #endif
640 if (val == -1)
642 sprintf((pbuf+strlen(pbuf)), "\t returnError\n");
643 state = ST_EXP_NIX;
646 /*---------------------------------------------------------------------------*
647 * reject
648 *---------------------------------------------------------------------------*/
649 static void
650 F_1_4(char *pbuf, int val)
652 #ifdef ST_DEBUG
653 sprintf((pbuf+strlen(pbuf)), "next_state: exec F_1_4, val = %d\n", val);
654 #endif
655 if (val == -1)
657 sprintf((pbuf+strlen(pbuf)), "\t reject\n");
658 state = ST_EXP_REJ_INV_ID;
662 /*---------------------------------------------------------------------------*
663 * return result: invoke id
664 *---------------------------------------------------------------------------*/
665 static void
666 F_RJ2(char *pbuf, int val)
668 #ifdef ST_DEBUG
669 sprintf((pbuf+strlen(pbuf)), "next_state: exec F_RJ2, val = %d\n", val);
670 #endif
671 if (val != -1)
673 sprintf((pbuf+strlen(pbuf)), "\t InvokeIdentifier = %d\n", val);
674 state = ST_EXP_REJ_OP_VAL;
678 /*---------------------------------------------------------------------------*
679 * reject, general problem
680 *---------------------------------------------------------------------------*/
681 static void
682 F_RJ30(char *pbuf, int val)
684 #ifdef ST_DEBUG
685 sprintf((pbuf+strlen(pbuf)), "next_state: exec F_RJ30, val = %d\n", val);
686 #endif
687 if (val == -1)
689 sprintf((pbuf+strlen(pbuf)), "\t General problem\n");
691 else
693 switch (val)
695 case 0:
696 sprintf((pbuf+strlen(pbuf)), "\t problem = unrecognized component\n");
697 break;
698 case 1:
699 sprintf((pbuf+strlen(pbuf)), "\t problem = mistyped component\n");
700 break;
701 case 2:
702 sprintf((pbuf+strlen(pbuf)), "\t problem = badly structured component\n");
703 break;
704 default:
705 sprintf((pbuf+strlen(pbuf)), "\t problem = unknown problem code 0x%x\n", val);
706 break;
708 state = ST_EXP_NIX;
712 /*---------------------------------------------------------------------------*
713 * reject, invoke problem
714 *---------------------------------------------------------------------------*/
715 static void
716 F_RJ31(char *pbuf, int val)
718 #ifdef ST_DEBUG
719 sprintf((pbuf+strlen(pbuf)), "next_state: exec F_RJ31, val = %d\n", val);
720 #endif
721 if (val == -1)
723 sprintf((pbuf+strlen(pbuf)), "\t Invoke problem\n");
725 else
727 switch (val)
729 case 0:
730 sprintf((pbuf+strlen(pbuf)), "\t problem = duplicate invocation\n");
731 break;
732 case 1:
733 sprintf((pbuf+strlen(pbuf)), "\t problem = unrecognized operation\n");
734 break;
735 case 2:
736 sprintf((pbuf+strlen(pbuf)), "\t problem = mistyped argument\n");
737 break;
738 case 3:
739 sprintf((pbuf+strlen(pbuf)), "\t problem = resource limitation\n");
740 break;
741 case 4:
742 sprintf((pbuf+strlen(pbuf)), "\t problem = initiator releasing\n");
743 break;
744 case 5:
745 sprintf((pbuf+strlen(pbuf)), "\t problem = unrecognized linked identifier\n");
746 break;
747 case 6:
748 sprintf((pbuf+strlen(pbuf)), "\t problem = linked resonse unexpected\n");
749 break;
750 case 7:
751 sprintf((pbuf+strlen(pbuf)), "\t problem = unexpected child operation\n");
752 break;
753 default:
754 sprintf((pbuf+strlen(pbuf)), "\t problem = unknown problem code 0x%x\n", val);
755 break;
757 state = ST_EXP_NIX;
761 /*---------------------------------------------------------------------------*
762 * reject, return result problem
763 *---------------------------------------------------------------------------*/
764 static void
765 F_RJ32(char *pbuf, int val)
767 #ifdef ST_DEBUG
768 sprintf((pbuf+strlen(pbuf)), "next_state: exec F_RJ32, val = %d\n", val);
769 #endif
770 if (val == -1)
772 sprintf((pbuf+strlen(pbuf)), "\t Return result problem\n");
774 else
776 switch (val)
778 case 0:
779 sprintf((pbuf+strlen(pbuf)), "\t problem = unrecognized invocation\n");
780 break;
781 case 1:
782 sprintf((pbuf+strlen(pbuf)), "\t problem = return response unexpected\n");
783 break;
784 case 2:
785 sprintf((pbuf+strlen(pbuf)), "\t problem = mistyped result\n");
786 break;
787 default:
788 sprintf((pbuf+strlen(pbuf)), "\t problem = unknown problem code 0x%x\n", val);
789 break;
791 state = ST_EXP_NIX;
795 /*---------------------------------------------------------------------------*
796 * reject, return error problem
797 *---------------------------------------------------------------------------*/
798 static void
799 F_RJ33(char *pbuf, int val)
801 #ifdef ST_DEBUG
802 sprintf((pbuf+strlen(pbuf)), "next_state: exec F_RJ33, val = %d\n", val);
803 #endif
804 if (val == -1)
806 sprintf((pbuf+strlen(pbuf)), "\t Return error problem\n");
808 else
810 switch (val)
812 case 0:
813 sprintf((pbuf+strlen(pbuf)), "\t problem = unrecognized invocation\n");
814 break;
815 case 1:
816 sprintf((pbuf+strlen(pbuf)), "\t problem = error response unexpected\n");
817 break;
818 case 2:
819 sprintf((pbuf+strlen(pbuf)), "\t problem = unrecognized error\n");
820 break;
821 case 3:
822 sprintf((pbuf+strlen(pbuf)), "\t problem = unexpected error\n");
823 break;
824 case 4:
825 sprintf((pbuf+strlen(pbuf)), "\t problem = mistyped parameter\n");
826 break;
827 default:
828 sprintf((pbuf+strlen(pbuf)), "\t problem = unknown problem code 0x%x\n", val);
829 break;
831 state = ST_EXP_NIX;
835 /*---------------------------------------------------------------------------*
836 * invoke component: invoke id
837 *---------------------------------------------------------------------------*/
838 static void
839 F_2(char *pbuf, int val)
841 #ifdef ST_DEBUG
842 sprintf((pbuf+strlen(pbuf)), "next_state: exec F_2, val = %d\n", val);
843 #endif
844 if (val != -1)
846 sprintf((pbuf+strlen(pbuf)), "\t InvokeIdentifier = %d\n", val);
847 state = ST_EXP_OP_VAL;
851 /*---------------------------------------------------------------------------*
852 * return result: invoke id
853 *---------------------------------------------------------------------------*/
854 static void
855 F_RR2(char *pbuf, int val)
857 #ifdef ST_DEBUG
858 sprintf((pbuf+strlen(pbuf)), "next_state: exec F_RR2, val = %d\n", val);
859 #endif
860 if (val != -1)
862 sprintf((pbuf+strlen(pbuf)), "\t InvokeIdentifier = %d\n", val);
863 state = ST_EXP_RR_OP_VAL;
867 /*---------------------------------------------------------------------------*
868 * invoke component: operation value
869 *---------------------------------------------------------------------------*/
870 static void
871 F_3(char *pbuf, int val)
873 #ifdef ST_DEBUG
874 sprintf((pbuf+strlen(pbuf)), "next_state: exec F_3, val = %d\n", val);
875 #endif
876 if (val != -1)
878 sprintf((pbuf+strlen(pbuf)), "\t Operation Value = %s (%d)\n", opval_str(val), val);
879 state = ST_EXP_INFO;
883 /*---------------------------------------------------------------------------*
884 * return result: operation value
885 *---------------------------------------------------------------------------*/
886 static void
887 F_RR3(char *pbuf, int val)
889 #ifdef ST_DEBUG
890 sprintf((pbuf+strlen(pbuf)), "next_state: exec F_RR3, val = %d\n", val);
891 #endif
892 if (val != -1)
894 sprintf((pbuf+strlen(pbuf)), "\t Operation Value = %s (%d)\n", opval_str(val), val);
895 state = ST_EXP_RR_RESULT;
899 /*---------------------------------------------------------------------------*
900 * return result: RESULT
901 *---------------------------------------------------------------------------*/
902 static void
903 F_RRR(char *pbuf, int val)
905 #ifdef ST_DEBUG
906 sprintf((pbuf+strlen(pbuf)), "next_state: exec F_RRR, val = %d\n", val);
907 #endif
908 state = ST_EXP_NIX;
911 /*---------------------------------------------------------------------------*
913 *---------------------------------------------------------------------------*/
914 static void
915 F_4(char *pbuf, int val)
917 #ifdef ST_DEBUG
918 sprintf((pbuf+strlen(pbuf)), "next_state: exec F_4, val = %d\n", val);
919 #endif
920 if (val == -1)
922 sprintf((pbuf+strlen(pbuf)), "\t specificChargingUnits\n");
923 state = ST_EXP_RUL;
927 /*---------------------------------------------------------------------------*
929 *---------------------------------------------------------------------------*/
930 static void
931 F_4_1(char *pbuf, int val)
933 #ifdef ST_DEBUG
934 sprintf((pbuf+strlen(pbuf)), "next_state: exec F_4_1, val = %d\n", val);
935 #endif
936 if (val == -1)
938 sprintf((pbuf+strlen(pbuf)), "\t freeOfCharge\n");
939 state = ST_EXP_NIX;
943 /*---------------------------------------------------------------------------*
945 *---------------------------------------------------------------------------*/
946 static void
947 F_4_2(char *pbuf, int val)
949 #ifdef ST_DEBUG
950 sprintf((pbuf+strlen(pbuf)), "next_state: exec F_4_2, val = %d\n", val);
951 #endif
952 if (val == -1)
954 sprintf((pbuf+strlen(pbuf)), "\t chargeNotAvailable\n");
955 state = ST_EXP_NIX;
959 /*---------------------------------------------------------------------------*
961 *---------------------------------------------------------------------------*/
962 static void
963 F_5(char *pbuf, int val)
965 #ifdef ST_DEBUG
966 sprintf((pbuf+strlen(pbuf)), "next_state: exec F_5, val = %d\n", val);
967 #endif
968 if (val == -1)
970 sprintf((pbuf+strlen(pbuf)), "\t recordedUnitsList [1]\n");
971 state = ST_EXP_RU;
975 /*---------------------------------------------------------------------------*
977 *---------------------------------------------------------------------------*/
978 static void
979 F_6(char *pbuf, int val)
981 #ifdef ST_DEBUG
982 sprintf((pbuf+strlen(pbuf)), "next_state: exec F_6, val = %d\n", val);
983 #endif
984 if (val == -1)
986 sprintf((pbuf+strlen(pbuf)), "\t RecordedUnits\n");
987 state = ST_EXP_RNOU;
991 /*---------------------------------------------------------------------------*
993 *---------------------------------------------------------------------------*/
994 static void
995 F_7(char *pbuf, int val)
997 #ifdef ST_DEBUG
998 sprintf((pbuf+strlen(pbuf)), "next_state: exec F_7, val = %d\n", val);
999 #endif
1000 if (val != -1)
1002 sprintf((pbuf+strlen(pbuf)), "\t NumberOfUnits = %d\n", val);
1003 state = ST_EXP_TOCI;
1007 /*---------------------------------------------------------------------------*
1009 *---------------------------------------------------------------------------*/
1010 static void
1011 F_8(char *pbuf, int val)
1013 #ifdef ST_DEBUG
1014 sprintf((pbuf+strlen(pbuf)), "next_state: exec F_8, val = %d\n", val);
1015 #endif
1016 if (val != -1)
1018 sprintf((pbuf+strlen(pbuf)), "\t typeOfChargingInfo = %s\n", val == 0 ? "subTotal" : "total");
1019 state = ST_EXP_DBID;
1023 /*---------------------------------------------------------------------------*
1025 *---------------------------------------------------------------------------*/
1026 static void
1027 F_9(char *pbuf, int val)
1029 #ifdef ST_DEBUG
1030 sprintf((pbuf+strlen(pbuf)), "next_state: exec F_9, val = %d\n", val);
1031 #endif
1032 if (val != -1)
1034 sprintf((pbuf+strlen(pbuf)), "\t AOCDBillingId = %s (%d)\n", bid_str(val), val);
1035 state = ST_EXP_NIX;
1039 /*---------------------------------------------------------------------------*
1040 * state table
1041 *---------------------------------------------------------------------------*/
1042 static struct statetab {
1043 int currstate; /* input: current state we are in */
1044 int form; /* input: current tag form */
1045 int class; /* input: current tag class */
1046 int code; /* input: current tag code */
1047 void (*func)(char *,int); /* output: func to exec */
1048 } statetab[] = {
1050 /* current state tag form tag class tag code function */
1051 /* --------------------- ---------------------- ---------------------- ---------------------- ----------------*/
1053 /* invoke */
1055 {ST_EXP_COMP_TYP, FAC_TAGFORM_CON, FAC_TAGCLASS_COS, 1, F_1_1 },
1056 {ST_EXP_COMP_TYP, FAC_TAGFORM_CON, FAC_TAGCLASS_COS, 2, F_1_2 },
1057 {ST_EXP_COMP_TYP, FAC_TAGFORM_CON, FAC_TAGCLASS_COS, 3, F_1_3 },
1058 {ST_EXP_COMP_TYP, FAC_TAGFORM_CON, FAC_TAGCLASS_COS, 4, F_1_4 },
1059 {ST_EXP_INV_ID, FAC_TAGFORM_PRI, FAC_TAGCLASS_UNI, FAC_CODEUNI_INT, F_2 },
1060 {ST_EXP_OP_VAL, FAC_TAGFORM_PRI, FAC_TAGCLASS_UNI, FAC_CODEUNI_INT, F_3 },
1061 {ST_EXP_INFO, FAC_TAGFORM_CON, FAC_TAGCLASS_UNI, FAC_CODEUNI_SEQ, F_4 },
1062 {ST_EXP_INFO, FAC_TAGFORM_PRI, FAC_TAGCLASS_UNI, FAC_CODEUNI_NULL, F_4_1 },
1063 {ST_EXP_INFO, FAC_TAGFORM_PRI, FAC_TAGCLASS_COS, 1, F_4_2 },
1064 {ST_EXP_RUL, FAC_TAGFORM_CON, FAC_TAGCLASS_COS, 1, F_5 },
1065 {ST_EXP_RU, FAC_TAGFORM_CON, FAC_TAGCLASS_UNI, FAC_CODEUNI_SEQ, F_6 },
1066 {ST_EXP_RNOU, FAC_TAGFORM_PRI, FAC_TAGCLASS_UNI, FAC_CODEUNI_INT, F_7 },
1067 {ST_EXP_TOCI, FAC_TAGFORM_PRI, FAC_TAGCLASS_COS, 2, F_8 },
1068 {ST_EXP_DBID, FAC_TAGFORM_PRI, FAC_TAGCLASS_COS, 3, F_9 },
1070 /* return result */
1072 {ST_EXP_RR_INV_ID, FAC_TAGFORM_PRI, FAC_TAGCLASS_UNI, FAC_CODEUNI_INT, F_RR2 },
1073 {ST_EXP_RR_OP_VAL, FAC_TAGFORM_PRI, FAC_TAGCLASS_UNI, FAC_CODEUNI_INT, F_RR3 },
1074 {ST_EXP_RR_RESULT, FAC_TAGFORM_CON, FAC_TAGCLASS_UNI, FAC_CODEUNI_SET, F_RRR },
1076 /* current state tag form tag class tag code function */
1077 /* --------------------- ---------------------- ---------------------- ---------------------- ----------------*/
1078 /* reject */
1080 {ST_EXP_REJ_INV_ID, FAC_TAGFORM_PRI, FAC_TAGCLASS_UNI, FAC_CODEUNI_INT, F_RJ2 },
1081 {ST_EXP_REJ_OP_VAL, FAC_TAGFORM_PRI, FAC_TAGCLASS_COS, 0, F_RJ30 },
1082 {ST_EXP_REJ_OP_VAL, FAC_TAGFORM_PRI, FAC_TAGCLASS_COS, 1, F_RJ31 },
1083 {ST_EXP_REJ_OP_VAL, FAC_TAGFORM_PRI, FAC_TAGCLASS_COS, 2, F_RJ32 },
1084 {ST_EXP_REJ_OP_VAL, FAC_TAGFORM_PRI, FAC_TAGCLASS_COS, 3, F_RJ33 },
1086 /* end */
1088 {-1, -1, -1, -1, NULL }
1091 /*---------------------------------------------------------------------------*
1092 * state decode for do_component
1093 *---------------------------------------------------------------------------*/
1094 static void
1095 next_state(char *pbuf, int class, int form, int code, int val)
1097 int i;
1099 #ifdef ST_DEBUG
1100 sprintf((pbuf+strlen(pbuf)), "next_state: class=%d, form=%d, code=%d, val=%d\n", class, form, code, val);
1101 #endif
1103 for (i=0; ; i++)
1105 if ((statetab[i].currstate > state) ||
1106 (statetab[i].currstate == -1))
1108 break;
1111 if ((statetab[i].currstate == state) &&
1112 (statetab[i].form == form) &&
1113 (statetab[i].class == class) &&
1114 (statetab[i].code == code))
1116 (*statetab[i].func)(pbuf, val);
1117 break;
1122 /*---------------------------------------------------------------------------*
1123 * decode OBJECT IDENTIFIER
1124 *---------------------------------------------------------------------------*/
1125 static void
1126 object_id(int comp_length, unsigned char *pbuf)
1128 int x;
1129 int i;
1130 int j = 0;
1131 int id_org = 0;
1132 int etsi = 0;
1134 sprintf((pbuf+strlen(pbuf)), "\t");
1136 for (i = comp_length - 1; i >= 0; i--, j++)
1138 sprintf((pbuf+strlen(pbuf)), "0x%02x = %d", *byte_buf, *byte_buf);
1140 if (j == 0)
1142 x = *byte_buf;
1144 if (x >= 0 && x <= 39)
1146 sprintf((pbuf+strlen(pbuf)), " ccitt/itu-t (0)");
1147 switch (x)
1149 case 0:
1150 sprintf((pbuf+strlen(pbuf)), " recommendation (0)");
1151 break;
1152 case 1:
1153 sprintf((pbuf+strlen(pbuf)), " question (1)");
1154 break;
1155 case 2:
1156 sprintf((pbuf+strlen(pbuf)), " administration (2)");
1157 break;
1158 case 3:
1159 sprintf((pbuf+strlen(pbuf)), " network-operator (3)");
1160 break;
1161 case 4:
1162 sprintf((pbuf+strlen(pbuf)), " identified-organization (4)");
1163 id_org = 1;
1164 break;
1165 default:
1166 sprintf((pbuf+strlen(pbuf)), " error: undefined-identifier (%d)", x);
1167 break;
1170 else if (x >= 40 && x <= 79)
1172 sprintf((pbuf+strlen(pbuf)), " iso (1)");
1173 x -= 40;
1174 switch (x)
1176 case 0:
1177 sprintf((pbuf+strlen(pbuf)), " standard (0)");
1178 break;
1179 case 1:
1180 sprintf((pbuf+strlen(pbuf)), " registration-authority (1)");
1181 break;
1182 case 2:
1183 sprintf((pbuf+strlen(pbuf)), " member-body (2)");
1184 break;
1185 case 3:
1186 sprintf((pbuf+strlen(pbuf)), " identified-organization (3)");
1187 id_org = 1;
1188 break;
1189 default:
1190 sprintf((pbuf+strlen(pbuf)), " error: undefined-identifier (%d)", x);
1191 break;
1194 else
1196 x -= 80;
1197 sprintf((pbuf+strlen(pbuf)), " joint-iso-ccitt (3) ??? (%d)", x);
1201 if (j == 1)
1203 if (id_org == 1)
1205 if (*byte_buf == 0)
1207 sprintf((pbuf+strlen(pbuf)), " etsi (0)");
1208 etsi = 1;
1213 if (j == 2)
1215 if (etsi == 1)
1217 if (*byte_buf == 0)
1219 sprintf((pbuf+strlen(pbuf)), " mobileDomain (0)");
1221 if (*byte_buf == 1)
1223 sprintf((pbuf+strlen(pbuf)), " inDomain (1)");
1228 byte_buf++;
1229 byte_len++;
1231 if (i)
1232 sprintf((pbuf+strlen(pbuf)), "\n\t");
1233 else
1234 sprintf((pbuf+strlen(pbuf)), "\n");
1238 /* EOF */