rcng - add rcng script to fixup kern.bootfile
[dragonfly.git] / usr.sbin / i4b / isdndecode / facility.c
blob5ae2ab8ed53d9aba8187badcb947e6363d950319
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 * facility.c - decode Q.932 facilities
28 * ------------------------------------
30 * $Id: facility.c,v 1.5 2000/02/21 15:17:17 hm Exp $
32 * $FreeBSD: src/usr.sbin/i4b/isdndecode/facility.c,v 1.6.2.1 2001/08/01 17:45:05 obrien Exp $
33 * $DragonFly: src/usr.sbin/i4b/isdndecode/facility.c,v 1.3 2005/11/25 00:58:52 swildner Exp $
35 * last edit-date: [Mon Feb 21 16:15:43 2000]
37 *---------------------------------------------------------------------------
39 * - Q.932 (03/93) Generic Procedures for the Control of
40 * ISDN Supplementaty Services
41 * - Q.950 (03/93) Supplementary Services Protocols, Structure and
42 * General Principles
43 * - ETS 300 179 (10/92) Advice Of Charge: charging information during
44 * the call (AOC-D) supplementary service Service description
45 * - ETS 300 180 (10/92) Advice Of Charge: charging information at the
46 * end of call (AOC-E) supplementary service Service description
47 * - ETS 300 181 (04/93) Advice Of Charge (AOC) supplementary service
48 * Functional capabilities and information flows
49 * - ETS 300 182 (04/93) Advice Of Charge (AOC) supplementary service
50 * Digital Subscriber Signalling System No. one (DSS1) protocol
51 * - X.208 Specification of Abstract Syntax Notation One (ASN.1)
52 * - X.209 Specification of Basic Encoding Rules for
53 * Abstract Syntax Notation One (ASN.1)
54 * - "ASN.1 Abstract Syntax Notation One", Walter Gora, DATACOM-Verlag
55 * 1992, 3rd Edition (ISBN 3-89238-062-7) (german !)
57 *---------------------------------------------------------------------------*/
59 #include "decode.h"
60 #include "facility.h"
62 static int do_component(int length, char *pbuf);
63 static char *uni_str(int code);
64 static char *opval_str(int val);
65 static char *bid_str(int val);
66 static void next_state(char *pbuf, int class, int form, int code, int val);
68 static int byte_len;
69 static unsigned char *byte_buf;
70 static int state;
72 /*---------------------------------------------------------------------------*
73 * decode Q.931/Q.932 facility info element
74 *---------------------------------------------------------------------------*/
75 int
76 q932_facility(char *pbuf, unsigned char *buf)
78 int len;
80 sprintf((pbuf+strlen(pbuf)), "[facility (Q.932): ");
82 buf++; /* length */
84 len = *buf;
86 buf++; /* protocol profile */
88 sprintf((pbuf+strlen(pbuf)), "Protocol=");
90 switch(*buf & 0x1f)
92 case FAC_PROTO_ROP:
93 sprintf((pbuf+strlen(pbuf)), "Remote Operations Protocol\n");
94 break;
96 case FAC_PROTO_CMIP:
97 sprintf((pbuf+strlen(pbuf)), "CMIP Protocol (Q.941), UNSUPPORTED!\n");
98 return(len+2);
99 break;
101 case FAC_PROTO_ACSE:
102 sprintf((pbuf+strlen(pbuf)), "ACSE Protocol (X.217/X.227), UNSUPPORTED!\n");
103 return(len+2);
104 break;
106 default:
107 sprintf((pbuf+strlen(pbuf)), "Unknown Protocol (val = 0x%x), UNSUPPORTED!\n", *buf & 0x1f);
108 return(len+2);
109 break;
112 /* next byte */
114 buf++;
115 len--;
117 /* initialize variables for do_component */
119 byte_len = 0;
120 byte_buf = buf;
121 state = ST_EXP_COMP_TYP;
123 /* decode facility */
125 do_component(len, pbuf);
127 sprintf((pbuf+(strlen(pbuf)-1)), "]"); /* XXX replace last newline */
129 return(len+3);
132 /*---------------------------------------------------------------------------*
133 * handle a component recursively
134 *---------------------------------------------------------------------------*/
135 static int
136 do_component(int length, char *pbuf)
138 int comp_tag_class; /* component tag class */
139 int comp_tag_form; /* component form: constructor or primitive */
140 int comp_tag_code; /* component code depending on class */
141 int comp_length = 0; /* component length */
143 #ifdef FAC_DEBUG
144 sprintf((pbuf+strlen(pbuf)), "ENTER - comp_length = %d, byte_len = %d, length =%d\n", comp_length, byte_len, length);
145 #endif
147 again:
149 #ifdef FAC_DEBUG
150 sprintf((pbuf+strlen(pbuf)), "AGAIN - comp_length = %d, byte_len = %d, length =%d\n", comp_length, byte_len, length);
151 #endif
153 /*----------------------------------------*/
154 /* first component element: component tag */
155 /*----------------------------------------*/
157 /* tag class bits */
159 sprintf((pbuf+strlen(pbuf)), "\t0x%02x Tag: ", *byte_buf);
161 comp_tag_class = (*byte_buf & 0xc0) >> 6;
163 switch(comp_tag_class)
165 case FAC_TAGCLASS_UNI:
166 sprintf((pbuf+strlen(pbuf)), "Universal");
167 break;
168 case FAC_TAGCLASS_APW:
169 sprintf((pbuf+strlen(pbuf)), "Applic-wide");
170 break;
171 case FAC_TAGCLASS_COS:
172 sprintf((pbuf+strlen(pbuf)), "Context-spec");
173 break;
174 case FAC_TAGCLASS_PRU:
175 sprintf((pbuf+strlen(pbuf)), "Private");
176 break;
179 /* tag form bit */
181 comp_tag_form = (*byte_buf & 0x20) > 5;
183 sprintf((pbuf+strlen(pbuf)), ", ");
185 if(comp_tag_form == FAC_TAGFORM_CON)
187 sprintf((pbuf+strlen(pbuf)), "Constructor");
189 else
191 sprintf((pbuf+strlen(pbuf)), "Primitive");
194 /* tag code bits */
196 comp_tag_code = *byte_buf & 0x1f;
198 sprintf((pbuf+strlen(pbuf)), ", ");
200 if(comp_tag_code == 0x1f)
202 comp_tag_code = 0;
204 byte_buf++;
205 byte_len++;
207 while(*byte_buf & 0x80)
209 comp_tag_code += (*byte_buf & 0x7f);
210 byte_buf++;
211 byte_len++;
213 comp_tag_code += (*byte_buf & 0x7f);
214 sprintf((pbuf+strlen(pbuf)), "%d (ext)\n", comp_tag_code);
216 else
218 comp_tag_code = (*byte_buf & 0x1f);
220 if(comp_tag_class == FAC_TAGCLASS_UNI)
222 sprintf((pbuf+strlen(pbuf)), "%s (%d)\n", uni_str(comp_tag_code), comp_tag_code);
224 else
226 sprintf((pbuf+strlen(pbuf)), "code = %d\n", comp_tag_code);
230 byte_buf++;
231 byte_len++;
233 /*--------------------------------------------*/
234 /* second component element: component length */
235 /*--------------------------------------------*/
237 sprintf((pbuf+strlen(pbuf)), "\t0x%02x Len: ", *byte_buf);
239 comp_length = 0;
241 if(*byte_buf & 0x80)
243 int i = *byte_buf & 0x7f;
245 byte_len += i;
247 for(;i > 0;i++)
249 byte_buf++;
250 comp_length += (*byte_buf * (i*256));
252 sprintf((pbuf+strlen(pbuf)), "%d (long form)\n", comp_length);
254 else
256 comp_length = *byte_buf & 0x7f;
257 sprintf((pbuf+strlen(pbuf)), "%d (short form)\n", comp_length);
260 next_state(pbuf, comp_tag_class, comp_tag_form, comp_tag_code, -1);
262 byte_len++;
263 byte_buf++;
265 if(comp_length)
268 /*---------------------------------------------*/
269 /* third component element: component contents */
270 /*---------------------------------------------*/
272 if(comp_tag_form) /* == constructor */
274 do_component(comp_length, pbuf);
276 else
278 int val = 0;
279 if(comp_tag_class == FAC_TAGCLASS_UNI)
281 switch(comp_tag_code)
283 case FAC_CODEUNI_INT:
284 case FAC_CODEUNI_ENUM:
285 case FAC_CODEUNI_BOOL:
286 if(comp_length)
288 int i;
290 sprintf((pbuf+strlen(pbuf)), "\t");
292 for(i = comp_length-1; i >= 0; i--)
294 sprintf((pbuf+strlen(pbuf)), "0x%02x ", *byte_buf);
295 val += (*byte_buf + (i*255));
296 byte_buf++;
297 byte_len++;
298 if(i)
299 sprintf((pbuf+strlen(pbuf)), "\n\t");
301 sprintf((pbuf+strlen(pbuf)), "Val: %d\n", val);
303 break;
304 default:
305 if(comp_length)
307 int i;
309 sprintf((pbuf+strlen(pbuf)), "\t");
311 for(i = comp_length-1; i >= 0; i--)
313 sprintf((pbuf+strlen(pbuf)), "0x%02x = %d", *byte_buf, *byte_buf);
314 if(isprint(*byte_buf))
315 sprintf((pbuf+strlen(pbuf)), " = '%c'", *byte_buf);
316 byte_buf++;
317 byte_len++;
318 if(i)
319 sprintf((pbuf+strlen(pbuf)), "\n\t");
322 break;
326 else /* comp_tag_class != FAC_TAGCLASS_UNI */
328 if(comp_length)
330 int i;
332 sprintf((pbuf+strlen(pbuf)), "\t");
334 for(i = comp_length-1; i >= 0; i--)
336 sprintf((pbuf+strlen(pbuf)), "0x%02x", *byte_buf);
337 val += (*byte_buf + (i*255));
338 byte_buf++;
339 byte_len++;
340 if(i)
341 sprintf((pbuf+strlen(pbuf)), "\n\t");
343 sprintf((pbuf+strlen(pbuf)), "\n");
346 next_state(pbuf, comp_tag_class, comp_tag_form, comp_tag_code, val);
350 #ifdef FAC_DEBUG
351 sprintf((pbuf+strlen(pbuf)), "PREGOTO - comp_length = %d, byte_len = %d, length =%d\n", comp_length, byte_len, length);
352 #endif
353 if(byte_len < length)
354 goto again;
355 #ifdef FAC_DEBUG
356 sprintf((pbuf+strlen(pbuf)), "RETURN - comp_length = %d, byte_len = %d, length =%d\n", comp_length, byte_len, length);
357 #endif
358 return(byte_len);
361 /*---------------------------------------------------------------------------*
362 * print universal id type
363 *---------------------------------------------------------------------------*/
364 static char *
365 uni_str(int code)
367 static char *tbl[] = {
368 "BOOLEAN",
369 "INTEGER",
370 "BIT STRING",
371 "OCTET STRING",
372 "NULL",
373 "OBJECT IDENTIFIER",
374 "OBJECT DESCRIPTOR",
375 "EXTERNAL",
376 "REAL",
377 "ENUMERATED",
378 "RESERVED11",
379 "RESERVED12",
380 "RESERVED13",
381 "RESERVED14",
382 "RESERVED15",
383 "SEQUENCE",
384 "SET",
385 "NUMERIC STRING",
386 "PRINTABLE STRING",
387 "TELETEX STRING",
388 "ISO646 STRING",
389 "IA5 STRING",
390 "GRAPHIC STRING",
391 "GENERAL STRING"
394 if(code >= 1 && code <= FAC_CODEUNI_GNSTR)
395 return(tbl[code-1]);
396 else
397 return("ERROR, Value out of Range!");
400 /*---------------------------------------------------------------------------*
401 * print operation value
402 *---------------------------------------------------------------------------*/
403 static char *
404 opval_str(int val)
406 static char buffer[80];
407 char *r;
409 switch(val)
411 case FAC_OPVAL_UUS:
412 r = "uUs";
413 break;
414 case FAC_OPVAL_CUG:
415 r = "cUGCall";
416 break;
417 case FAC_OPVAL_MCID:
418 r = "mCIDRequest";
419 break;
420 case FAC_OPVAL_BTPY:
421 r = "beginTPY";
422 break;
423 case FAC_OPVAL_ETPY:
424 r = "endTPY";
425 break;
426 case FAC_OPVAL_ECT:
427 r = "eCTRequest";
428 break;
429 case FAC_OPVAL_DIV_ACT:
430 r = "activationDiversion";
431 break;
432 case FAC_OPVAL_DIV_DEACT:
433 r = "deactivationDiversion";
434 break;
435 case FAC_OPVAL_DIV_ACTSN:
436 r = "activationStatusNotificationDiv";
437 break;
438 case FAC_OPVAL_DIV_DEACTSN:
439 r = "deactivationStatusNotificationDiv";
440 break;
441 case FAC_OPVAL_DIV_INTER:
442 r = "interrogationDiversion";
443 break;
444 case FAC_OPVAL_DIV_INFO:
445 r = "diversionInformation";
446 break;
447 case FAC_OPVAL_DIV_CALLDEF:
448 r = "callDeflection";
449 break;
450 case FAC_OPVAL_DIV_CALLRER:
451 r = "callRerouting";
452 break;
453 case FAC_OPVAL_DIV_LINF2:
454 r = "divertingLegInformation2";
455 break;
456 case FAC_OPVAL_DIV_INVS:
457 r = "invokeStatus";
458 break;
459 case FAC_OPVAL_DIV_INTER1:
460 r = "interrogationDiversion1";
461 break;
462 case FAC_OPVAL_DIV_LINF1:
463 r = "divertingLegInformation1";
464 break;
465 case FAC_OPVAL_DIV_LINF3:
466 r = "divertingLegInformation3";
467 break;
468 case FAC_OPVAL_ER_CRCO:
469 r = "explicitReservationCreationControl";
470 break;
471 case FAC_OPVAL_ER_MGMT:
472 r = "explicitReservationManagement";
473 break;
474 case FAC_OPVAL_ER_CANC:
475 r = "explicitReservationCancel";
476 break;
477 case FAC_OPVAL_MLPP_QUERY:
478 r = "mLPP lfb Query";
479 break;
480 case FAC_OPVAL_MLPP_CALLR:
481 r = "mLPP Call Request";
482 break;
483 case FAC_OPVAL_MLPP_CALLP:
484 r = "mLPP Call Preemption";
485 break;
486 case FAC_OPVAL_AOC_REQ:
487 r = "chargingRequest";
488 break;
489 case FAC_OPVAL_AOC_S_CUR:
490 r = "aOCSCurrency";
491 break;
492 case FAC_OPVAL_AOC_S_SPC:
493 r = "aOCSSpecialArrangement";
494 break;
495 case FAC_OPVAL_AOC_D_CUR:
496 r = "aOCDCurrency";
497 break;
498 case FAC_OPVAL_AOC_D_UNIT:
499 r = "aOCDChargingUnit";
500 break;
501 case FAC_OPVAL_AOC_E_CUR:
502 r = "aOCECurrency";
503 break;
504 case FAC_OPVAL_AOC_E_UNIT:
505 r = "aOCEChargingUnit";
506 break;
507 case FAC_OPVAL_AOC_IDOFCRG:
508 r = "identificationOfCharge";
509 break;
510 case FAC_OPVAL_CONF_BEG:
511 r = "beginConf";
512 break;
513 case FAC_OPVAL_CONF_ADD:
514 r = "addConf";
515 break;
516 case FAC_OPVAL_CONF_SPLIT:
517 r = "splitConf";
518 break;
519 case FAC_OPVAL_CONF_DROP:
520 r = "dropConf";
521 break;
522 case FAC_OPVAL_CONF_ISOLATE:
523 r = "isolateConf";
524 break;
525 case FAC_OPVAL_CONF_REATT:
526 r = "reattachConf";
527 break;
528 case FAC_OPVAL_CONF_PDISC:
529 r = "partyDISC";
530 break;
531 case FAC_OPVAL_CONF_FCONF:
532 r = "floatConf";
533 break;
534 case FAC_OPVAL_CONF_END:
535 r = "endConf";
536 break;
537 case FAC_OPVAL_CONF_IDCFE:
538 r = "indentifyConferee";
539 break;
540 case FAC_OPVAL_REVC_REQ:
541 r = "requestREV";
542 break;
543 default:
544 sprintf(buffer, "unknown operation value %d!", val);
545 r = buffer;
547 return(r);
550 /*---------------------------------------------------------------------------*
551 * billing id string
552 *---------------------------------------------------------------------------*/
553 static char *
554 bid_str(int val)
556 static char buffer[80];
557 char *r;
559 switch(val)
561 case 0:
562 r = "normalCharging";
563 break;
564 case 1:
565 r = "reverseCharging";
566 break;
567 case 2:
568 r = "creditCardCharging";
569 break;
570 case 3:
571 r = "callForwardingUnconditional";
572 break;
573 case 4:
574 r = "callForwardingBusy";
575 break;
576 case 5:
577 r = "callForwardingNoReply";
578 break;
579 case 6:
580 r = "callDeflection";
581 break;
582 case 7:
583 r = "callTransfer";
584 break;
585 default:
586 sprintf(buffer, "unknown billing-id value %d!", val);
587 r = buffer;
589 return(r);
592 /*---------------------------------------------------------------------------*
593 * invoke component
594 *---------------------------------------------------------------------------*/
595 static void
596 F_1_1(char *pbuf, int val)
598 #ifdef ST_DEBUG
599 sprintf((pbuf+strlen(pbuf)), "next_state: exec F_1_1, val = %d\n", val);
600 #endif
601 if(val == -1)
603 sprintf((pbuf+strlen(pbuf)), "\t invokeComponent\n");
604 state = ST_EXP_INV_ID;
608 /*---------------------------------------------------------------------------*
609 * return result
610 *---------------------------------------------------------------------------*/
611 static void
612 F_1_2(char *pbuf, int val)
614 #ifdef ST_DEBUG
615 sprintf((pbuf+strlen(pbuf)), "next_state: exec F_1_2, val = %d\n", val);
616 #endif
617 if(val == -1)
619 sprintf((pbuf+strlen(pbuf)), "\t returnResult\n");
620 state = ST_EXP_RR_INV_ID;
623 /*---------------------------------------------------------------------------*
624 * return error
625 *---------------------------------------------------------------------------*/
626 static void
627 F_1_3(char *pbuf, int val)
629 #ifdef ST_DEBUG
630 sprintf((pbuf+strlen(pbuf)), "next_state: exec F_1_3, val = %d\n", val);
631 #endif
632 if(val == -1)
634 sprintf((pbuf+strlen(pbuf)), "\t returnError\n");
635 state = ST_EXP_NIX;
638 /*---------------------------------------------------------------------------*
639 * reject
640 *---------------------------------------------------------------------------*/
641 static void
642 F_1_4(char *pbuf, int val)
644 #ifdef ST_DEBUG
645 sprintf((pbuf+strlen(pbuf)), "next_state: exec F_1_4, val = %d\n", val);
646 #endif
647 if(val == -1)
649 sprintf((pbuf+strlen(pbuf)), "\t reject\n");
650 state = ST_EXP_REJ_INV_ID;
654 /*---------------------------------------------------------------------------*
655 * return result: invoke id
656 *---------------------------------------------------------------------------*/
657 static void
658 F_RJ2(char *pbuf, int val)
660 #ifdef ST_DEBUG
661 sprintf((pbuf+strlen(pbuf)), "next_state: exec F_RJ2, val = %d\n", val);
662 #endif
663 if(val != -1)
665 sprintf((pbuf+strlen(pbuf)), "\t InvokeIdentifier = %d\n", val);
666 state = ST_EXP_REJ_OP_VAL;
670 /*---------------------------------------------------------------------------*
671 * reject, general problem
672 *---------------------------------------------------------------------------*/
673 static void
674 F_RJ30(char *pbuf, int val)
676 #ifdef ST_DEBUG
677 sprintf((pbuf+strlen(pbuf)), "next_state: exec F_RJ30, val = %d\n", val);
678 #endif
679 if(val == -1)
681 sprintf((pbuf+strlen(pbuf)), "\t General problem\n");
683 else
685 switch(val)
687 case 0:
688 sprintf((pbuf+strlen(pbuf)), "\t problem = unrecognized component\n");
689 break;
690 case 1:
691 sprintf((pbuf+strlen(pbuf)), "\t problem = mistyped component\n");
692 break;
693 case 2:
694 sprintf((pbuf+strlen(pbuf)), "\t problem = badly structured component\n");
695 break;
696 default:
697 sprintf((pbuf+strlen(pbuf)), "\t problem = unknown problem code 0x%x\n", val);
698 break;
700 state = ST_EXP_NIX;
704 /*---------------------------------------------------------------------------*
705 * reject, invoke problem
706 *---------------------------------------------------------------------------*/
707 static void
708 F_RJ31(char *pbuf, int val)
710 #ifdef ST_DEBUG
711 sprintf((pbuf+strlen(pbuf)), "next_state: exec F_RJ31, val = %d\n", val);
712 #endif
713 if(val == -1)
715 sprintf((pbuf+strlen(pbuf)), "\t Invoke problem\n");
717 else
719 switch(val)
721 case 0:
722 sprintf((pbuf+strlen(pbuf)), "\t problem = duplicate invocation\n");
723 break;
724 case 1:
725 sprintf((pbuf+strlen(pbuf)), "\t problem = unrecognized operation\n");
726 break;
727 case 2:
728 sprintf((pbuf+strlen(pbuf)), "\t problem = mistyped argument\n");
729 break;
730 case 3:
731 sprintf((pbuf+strlen(pbuf)), "\t problem = resource limitation\n");
732 break;
733 case 4:
734 sprintf((pbuf+strlen(pbuf)), "\t problem = initiator releasing\n");
735 break;
736 case 5:
737 sprintf((pbuf+strlen(pbuf)), "\t problem = unrecognized linked identifier\n");
738 break;
739 case 6:
740 sprintf((pbuf+strlen(pbuf)), "\t problem = linked resonse unexpected\n");
741 break;
742 case 7:
743 sprintf((pbuf+strlen(pbuf)), "\t problem = unexpected child operation\n");
744 break;
745 default:
746 sprintf((pbuf+strlen(pbuf)), "\t problem = unknown problem code 0x%x\n", val);
747 break;
749 state = ST_EXP_NIX;
753 /*---------------------------------------------------------------------------*
754 * reject, return result problem
755 *---------------------------------------------------------------------------*/
756 static void
757 F_RJ32(char *pbuf, int val)
759 #ifdef ST_DEBUG
760 sprintf((pbuf+strlen(pbuf)), "next_state: exec F_RJ32, val = %d\n", val);
761 #endif
762 if(val == -1)
764 sprintf((pbuf+strlen(pbuf)), "\t Return result problem\n");
766 else
768 switch(val)
770 case 0:
771 sprintf((pbuf+strlen(pbuf)), "\t problem = unrecognized invocation\n");
772 break;
773 case 1:
774 sprintf((pbuf+strlen(pbuf)), "\t problem = return response unexpected\n");
775 break;
776 case 2:
777 sprintf((pbuf+strlen(pbuf)), "\t problem = mistyped result\n");
778 break;
779 default:
780 sprintf((pbuf+strlen(pbuf)), "\t problem = unknown problem code 0x%x\n", val);
781 break;
783 state = ST_EXP_NIX;
787 /*---------------------------------------------------------------------------*
788 * reject, return error problem
789 *---------------------------------------------------------------------------*/
790 static void
791 F_RJ33(char *pbuf, int val)
793 #ifdef ST_DEBUG
794 sprintf((pbuf+strlen(pbuf)), "next_state: exec F_RJ33, val = %d\n", val);
795 #endif
796 if(val == -1)
798 sprintf((pbuf+strlen(pbuf)), "\t Return error problem\n");
800 else
802 switch(val)
804 case 0:
805 sprintf((pbuf+strlen(pbuf)), "\t problem = unrecognized invocation\n");
806 break;
807 case 1:
808 sprintf((pbuf+strlen(pbuf)), "\t problem = error response unexpected\n");
809 break;
810 case 2:
811 sprintf((pbuf+strlen(pbuf)), "\t problem = unrecognized error\n");
812 break;
813 case 3:
814 sprintf((pbuf+strlen(pbuf)), "\t problem = unexpected error\n");
815 break;
816 case 4:
817 sprintf((pbuf+strlen(pbuf)), "\t problem = mistyped parameter\n");
818 break;
819 default:
820 sprintf((pbuf+strlen(pbuf)), "\t problem = unknown problem code 0x%x\n", val);
821 break;
823 state = ST_EXP_NIX;
827 /*---------------------------------------------------------------------------*
828 * invoke component: invoke id
829 *---------------------------------------------------------------------------*/
830 static void
831 F_2(char *pbuf, int val)
833 #ifdef ST_DEBUG
834 sprintf((pbuf+strlen(pbuf)), "next_state: exec F_2, val = %d\n", val);
835 #endif
836 if(val != -1)
838 sprintf((pbuf+strlen(pbuf)), "\t InvokeIdentifier = %d\n", val);
839 state = ST_EXP_OP_VAL;
843 /*---------------------------------------------------------------------------*
844 * return result: invoke id
845 *---------------------------------------------------------------------------*/
846 static void
847 F_RR2(char *pbuf, int val)
849 #ifdef ST_DEBUG
850 sprintf((pbuf+strlen(pbuf)), "next_state: exec F_RR2, val = %d\n", val);
851 #endif
852 if(val != -1)
854 sprintf((pbuf+strlen(pbuf)), "\t InvokeIdentifier = %d\n", val);
855 state = ST_EXP_RR_OP_VAL;
859 /*---------------------------------------------------------------------------*
860 * invoke component: operation value
861 *---------------------------------------------------------------------------*/
862 static void
863 F_3(char *pbuf, int val)
865 #ifdef ST_DEBUG
866 sprintf((pbuf+strlen(pbuf)), "next_state: exec F_3, val = %d\n", val);
867 #endif
868 if(val != -1)
870 sprintf((pbuf+strlen(pbuf)), "\t Operation Value = %s (%d)\n", opval_str(val), val);
871 state = ST_EXP_INFO;
875 /*---------------------------------------------------------------------------*
876 * return result: operation value
877 *---------------------------------------------------------------------------*/
878 static void
879 F_RR3(char *pbuf, int val)
881 #ifdef ST_DEBUG
882 sprintf((pbuf+strlen(pbuf)), "next_state: exec F_RR3, val = %d\n", val);
883 #endif
884 if(val != -1)
886 sprintf((pbuf+strlen(pbuf)), "\t Operation Value = %s (%d)\n", opval_str(val), val);
887 state = ST_EXP_RR_RESULT;
891 /*---------------------------------------------------------------------------*
892 * return result: RESULT
893 *---------------------------------------------------------------------------*/
894 static void
895 F_RRR(char *pbuf, int val)
897 #ifdef ST_DEBUG
898 sprintf((pbuf+strlen(pbuf)), "next_state: exec F_RRR, val = %d\n", val);
899 #endif
900 state = ST_EXP_NIX;
903 /*---------------------------------------------------------------------------*
905 *---------------------------------------------------------------------------*/
906 static void
907 F_4(char *pbuf, int val)
909 #ifdef ST_DEBUG
910 sprintf((pbuf+strlen(pbuf)), "next_state: exec F_4, val = %d\n", val);
911 #endif
912 if(val == -1)
914 sprintf((pbuf+strlen(pbuf)), "\t specificChargingUnits\n");
915 state = ST_EXP_RUL;
919 /*---------------------------------------------------------------------------*
921 *---------------------------------------------------------------------------*/
922 static void
923 F_4_1(char *pbuf, int val)
925 #ifdef ST_DEBUG
926 sprintf((pbuf+strlen(pbuf)), "next_state: exec F_4_1, val = %d\n", val);
927 #endif
928 if(val == -1)
930 sprintf((pbuf+strlen(pbuf)), "\t freeOfCharge\n");
931 state = ST_EXP_NIX;
935 /*---------------------------------------------------------------------------*
937 *---------------------------------------------------------------------------*/
938 static void
939 F_4_2(char *pbuf, int val)
941 #ifdef ST_DEBUG
942 sprintf((pbuf+strlen(pbuf)), "next_state: exec F_4_2, val = %d\n", val);
943 #endif
944 if(val == -1)
946 sprintf((pbuf+strlen(pbuf)), "\t chargeNotAvailable\n");
947 state = ST_EXP_NIX;
951 /*---------------------------------------------------------------------------*
953 *---------------------------------------------------------------------------*/
954 static void
955 F_5(char *pbuf, int val)
957 #ifdef ST_DEBUG
958 sprintf((pbuf+strlen(pbuf)), "next_state: exec F_5, val = %d\n", val);
959 #endif
960 if(val == -1)
962 sprintf((pbuf+strlen(pbuf)), "\t recordedUnitsList [1]\n");
963 state = ST_EXP_RU;
967 /*---------------------------------------------------------------------------*
969 *---------------------------------------------------------------------------*/
970 static void
971 F_6(char *pbuf, int val)
973 #ifdef ST_DEBUG
974 sprintf((pbuf+strlen(pbuf)), "next_state: exec F_6, val = %d\n", val);
975 #endif
976 if(val == -1)
978 sprintf((pbuf+strlen(pbuf)), "\t RecordedUnits\n");
979 state = ST_EXP_RNOU;
983 /*---------------------------------------------------------------------------*
985 *---------------------------------------------------------------------------*/
986 static void
987 F_7(char *pbuf, int val)
989 #ifdef ST_DEBUG
990 sprintf((pbuf+strlen(pbuf)), "next_state: exec F_7, val = %d\n", val);
991 #endif
992 if(val != -1)
994 sprintf((pbuf+strlen(pbuf)), "\t NumberOfUnits = %d\n", val);
995 state = ST_EXP_TOCI;
999 /*---------------------------------------------------------------------------*
1001 *---------------------------------------------------------------------------*/
1002 static void
1003 F_8(char *pbuf, int val)
1005 #ifdef ST_DEBUG
1006 sprintf((pbuf+strlen(pbuf)), "next_state: exec F_8, val = %d\n", val);
1007 #endif
1008 if(val != -1)
1010 sprintf((pbuf+strlen(pbuf)), "\t typeOfChargingInfo = %s\n", val == 0 ? "subTotal" : "total");
1011 state = ST_EXP_DBID;
1015 /*---------------------------------------------------------------------------*
1017 *---------------------------------------------------------------------------*/
1018 static void
1019 F_9(char *pbuf, int val)
1021 #ifdef ST_DEBUG
1022 sprintf((pbuf+strlen(pbuf)), "next_state: exec F_9, val = %d\n", val);
1023 #endif
1024 if(val != -1)
1026 sprintf((pbuf+strlen(pbuf)), "\t AOCDBillingId = %s (%d)\n", bid_str(val), val);
1027 state = ST_EXP_NIX;
1031 /*---------------------------------------------------------------------------*
1032 * state table
1033 *---------------------------------------------------------------------------*/
1034 static struct statetab {
1035 int currstate; /* input: current state we are in */
1036 int form; /* input: current tag form */
1037 int class; /* input: current tag class */
1038 int code; /* input: current tag code */
1039 void (*func)(char *,int); /* output: func to exec */
1040 } statetab[] = {
1042 /* current state tag form tag class tag code function */
1043 /* --------------------- ---------------------- ---------------------- ---------------------- ----------------*/
1045 /* invoke */
1047 {ST_EXP_COMP_TYP, FAC_TAGFORM_CON, FAC_TAGCLASS_COS, 1, F_1_1 },
1048 {ST_EXP_COMP_TYP, FAC_TAGFORM_CON, FAC_TAGCLASS_COS, 2, F_1_2 },
1049 {ST_EXP_COMP_TYP, FAC_TAGFORM_CON, FAC_TAGCLASS_COS, 3, F_1_3 },
1050 {ST_EXP_COMP_TYP, FAC_TAGFORM_CON, FAC_TAGCLASS_COS, 4, F_1_4 },
1051 {ST_EXP_INV_ID, FAC_TAGFORM_PRI, FAC_TAGCLASS_UNI, FAC_CODEUNI_INT, F_2 },
1052 {ST_EXP_OP_VAL, FAC_TAGFORM_PRI, FAC_TAGCLASS_UNI, FAC_CODEUNI_INT, F_3 },
1053 {ST_EXP_INFO, FAC_TAGFORM_CON, FAC_TAGCLASS_UNI, FAC_CODEUNI_SEQ, F_4 },
1054 {ST_EXP_INFO, FAC_TAGFORM_PRI, FAC_TAGCLASS_UNI, FAC_CODEUNI_NULL, F_4_1 },
1055 {ST_EXP_INFO, FAC_TAGFORM_PRI, FAC_TAGCLASS_COS, 1, F_4_2 },
1056 {ST_EXP_RUL, FAC_TAGFORM_CON, FAC_TAGCLASS_COS, 1, F_5 },
1057 {ST_EXP_RU, FAC_TAGFORM_CON, FAC_TAGCLASS_UNI, FAC_CODEUNI_SEQ, F_6 },
1058 {ST_EXP_RNOU, FAC_TAGFORM_PRI, FAC_TAGCLASS_UNI, FAC_CODEUNI_INT, F_7 },
1059 {ST_EXP_TOCI, FAC_TAGFORM_PRI, FAC_TAGCLASS_COS, 2, F_8 },
1060 {ST_EXP_DBID, FAC_TAGFORM_PRI, FAC_TAGCLASS_COS, 3, F_9 },
1062 /* return result */
1064 {ST_EXP_RR_INV_ID, FAC_TAGFORM_PRI, FAC_TAGCLASS_UNI, FAC_CODEUNI_INT, F_RR2 },
1065 {ST_EXP_RR_OP_VAL, FAC_TAGFORM_PRI, FAC_TAGCLASS_UNI, FAC_CODEUNI_INT, F_RR3 },
1066 {ST_EXP_RR_RESULT, FAC_TAGFORM_CON, FAC_TAGCLASS_UNI, FAC_CODEUNI_SET, F_RRR },
1068 /* current state tag form tag class tag code function */
1069 /* --------------------- ---------------------- ---------------------- ---------------------- ----------------*/
1070 /* reject */
1072 {ST_EXP_REJ_INV_ID, FAC_TAGFORM_PRI, FAC_TAGCLASS_UNI, FAC_CODEUNI_INT, F_RJ2 },
1073 {ST_EXP_REJ_OP_VAL, FAC_TAGFORM_PRI, FAC_TAGCLASS_COS, 0, F_RJ30 },
1074 {ST_EXP_REJ_OP_VAL, FAC_TAGFORM_PRI, FAC_TAGCLASS_COS, 1, F_RJ31 },
1075 {ST_EXP_REJ_OP_VAL, FAC_TAGFORM_PRI, FAC_TAGCLASS_COS, 2, F_RJ32 },
1076 {ST_EXP_REJ_OP_VAL, FAC_TAGFORM_PRI, FAC_TAGCLASS_COS, 3, F_RJ33 },
1078 /* end */
1080 {-1, -1, -1, -1, NULL }
1083 /*---------------------------------------------------------------------------*
1084 * state decode for do_component
1085 *---------------------------------------------------------------------------*/
1086 static void
1087 next_state(char *pbuf, int class, int form, int code, int val)
1089 int i;
1091 #ifdef ST_DEBUG
1092 sprintf((pbuf+strlen(pbuf)), "next_state: class=%d, form=%d, code=%d, val=%d\n", class, form, code, val);
1093 #endif
1095 for(i=0; ; i++)
1097 if((statetab[i].currstate > state) ||
1098 (statetab[i].currstate == -1))
1100 break;
1103 if((statetab[i].currstate == state) &&
1104 (statetab[i].form == form) &&
1105 (statetab[i].class == class) &&
1106 (statetab[i].code == code))
1108 (*statetab[i].func)(pbuf, val);
1109 break;
1114 /* EOF */