2 * Copyright (c) 1997, 2002 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
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
26 /*---------------------------------------------------------------------------
28 * i4b_q932fac.c - Q932 facility handling
29 * --------------------------------------
30 * last edit-date: [Sat Mar 9 19:37:29 2002]
32 *---------------------------------------------------------------------------*/
34 #include <sys/cdefs.h>
35 __FBSDID("$FreeBSD$");
37 #include <sys/param.h>
38 #include <sys/systm.h>
41 #include <i4b/include/i4b_debug.h>
42 #include <i4b/include/i4b_ioctl.h>
44 #include <i4b/include/i4b_l3l4.h>
46 #include <i4b/layer3/i4b_l3.h>
47 #include <i4b/layer3/i4b_q932fac.h>
49 static int do_component(int length);
50 static void next_state(int class, int form, int code, int val);
53 static unsigned char *byte_buf;
57 static int operation_value;
59 /*---------------------------------------------------------------------------*
60 * decode Q.931/Q.932 facility info element
61 *---------------------------------------------------------------------------*/
63 i4b_aoc(unsigned char *buf, call_desc_t *cd)
67 cd->units_type = CHARGE_INVALID;
74 buf++; /* protocol profile */
82 NDBGL3(L3_A_MSG, "CMIP Protocol (Q.941), UNSUPPORTED");
87 NDBGL3(L3_A_MSG, "ACSE Protocol (X.217/X.227), UNSUPPORTED!");
92 NDBGL3(L3_A_ERR, "Unknown Protocol, UNSUPPORTED!");
97 NDBGL3(L3_A_MSG, "Remote Operations Protocol");
104 /* initialize variables for do_component */
108 state = ST_EXP_COMP_TYP;
110 /* decode facility */
114 switch(operation_value)
116 case FAC_OPVAL_AOC_D_CUR:
117 cd->units_type = CHARGE_AOCD;
122 case FAC_OPVAL_AOC_D_UNIT:
123 cd->units_type = CHARGE_AOCD;
128 case FAC_OPVAL_AOC_E_CUR:
129 cd->units_type = CHARGE_AOCE;
134 case FAC_OPVAL_AOC_E_UNIT:
135 cd->units_type = CHARGE_AOCE;
141 cd->units_type = CHARGE_INVALID;
149 /*---------------------------------------------------------------------------*
150 * handle a component recursively
151 *---------------------------------------------------------------------------*/
153 do_component(int length)
155 int comp_tag_class; /* component tag class */
156 int comp_tag_form; /* component form: constructor or primitive */
157 int comp_tag_code; /* component code depending on class */
158 int comp_length = 0; /* component length */
162 /*----------------------------------------*/
163 /* first component element: component tag */
164 /*----------------------------------------*/
168 comp_tag_class = (*byte_buf & 0xc0) >> 6;
170 switch(comp_tag_class)
172 case FAC_TAGCLASS_UNI:
174 case FAC_TAGCLASS_APW:
176 case FAC_TAGCLASS_COS:
178 case FAC_TAGCLASS_PRU:
184 comp_tag_form = (*byte_buf & 0x20) > 5;
188 comp_tag_code = *byte_buf & 0x1f;
190 if(comp_tag_code == 0x1f)
197 while(*byte_buf & 0x80)
199 comp_tag_code += (*byte_buf & 0x7f);
203 comp_tag_code += (*byte_buf & 0x7f);
207 comp_tag_code = (*byte_buf & 0x1f);
213 /*--------------------------------------------*/
214 /* second component element: component length */
215 /*--------------------------------------------*/
221 int i = *byte_buf & 0x7f;
228 comp_length += (*byte_buf * (i*256));
233 comp_length = *byte_buf & 0x7f;
236 next_state(comp_tag_class, comp_tag_form, comp_tag_code, -1);
241 /*---------------------------------------------*/
242 /* third component element: component contents */
243 /*---------------------------------------------*/
245 if(comp_tag_form) /* == constructor */
247 do_component(comp_length);
252 if(comp_tag_class == FAC_TAGCLASS_UNI)
254 switch(comp_tag_code)
256 case FAC_CODEUNI_INT:
257 case FAC_CODEUNI_ENUM:
258 case FAC_CODEUNI_BOOL:
263 for(i = comp_length-1; i >= 0; i--)
265 val += (*byte_buf + (i*255));
276 for(i = comp_length-1; i >= 0; i--)
286 else /* comp_tag_class != FAC_TAGCLASS_UNI */
292 for(i = comp_length-1; i >= 0; i--)
294 val += (*byte_buf + (i*255));
300 next_state(comp_tag_class, comp_tag_form, comp_tag_code, val);
303 if(byte_len < length)
309 /*---------------------------------------------------------------------------*
311 *---------------------------------------------------------------------------*/
317 state = ST_EXP_INV_ID;
321 /*---------------------------------------------------------------------------*
323 *---------------------------------------------------------------------------*/
330 /*---------------------------------------------------------------------------*
332 *---------------------------------------------------------------------------*/
339 /*---------------------------------------------------------------------------*
341 *---------------------------------------------------------------------------*/
349 /*---------------------------------------------------------------------------*
351 *---------------------------------------------------------------------------*/
357 NDBGL3(L3_A_MSG, "Invoke ID = %d", val);
358 state = ST_EXP_OP_VAL;
362 /*---------------------------------------------------------------------------*
364 *---------------------------------------------------------------------------*/
370 NDBGL3(L3_A_MSG, "Operation Value = %d", val);
372 operation_value = val;
374 if((val == FAC_OPVAL_AOC_D_UNIT) || (val == FAC_OPVAL_AOC_E_UNIT))
386 /*---------------------------------------------------------------------------*
387 * specific charging units
388 *---------------------------------------------------------------------------*/
396 /*---------------------------------------------------------------------------*
398 *---------------------------------------------------------------------------*/
404 NDBGL3(L3_A_MSG, "Free of Charge");
405 /* units = 0; XXXX */
410 /*---------------------------------------------------------------------------*
411 * charge not available
412 *---------------------------------------------------------------------------*/
418 NDBGL3(L3_A_MSG, "Charge not available");
419 /* units = -1; XXXXXX ??? */
424 /*---------------------------------------------------------------------------*
425 * recorded units list
426 *---------------------------------------------------------------------------*/
434 /*---------------------------------------------------------------------------*
436 *---------------------------------------------------------------------------*/
444 /*---------------------------------------------------------------------------*
446 *---------------------------------------------------------------------------*/
452 NDBGL3(L3_A_MSG, "Number of Units = %d", val);
458 /*---------------------------------------------------------------------------*
460 *---------------------------------------------------------------------------*/
466 NDBGL3(L3_A_MSG, "Subtotal/Total = %d", val);
467 /* type_of_charge = val; */
472 /*---------------------------------------------------------------------------*
474 *---------------------------------------------------------------------------*/
480 NDBGL3(L3_A_MSG, "Billing ID = %d", val);
481 /* billing_id = val; */
486 /*---------------------------------------------------------------------------*
488 *---------------------------------------------------------------------------*/
489 static struct statetab {
490 int currstate; /* input: current state we are in */
491 int form; /* input: current tag form */
492 int class; /* input: current tag class */
493 int code; /* input: current tag code */
494 void (*func)(int); /* output: func to exec */
497 /* current state tag form tag class tag code function */
498 /* --------------------- ---------------------- ---------------------- ---------------------- ----------------*/
499 {ST_EXP_COMP_TYP, FAC_TAGFORM_CON, FAC_TAGCLASS_COS, 1, F_1_1 },
500 {ST_EXP_COMP_TYP, FAC_TAGFORM_CON, FAC_TAGCLASS_COS, 2, F_1_2 },
501 {ST_EXP_COMP_TYP, FAC_TAGFORM_CON, FAC_TAGCLASS_COS, 3, F_1_3 },
502 {ST_EXP_COMP_TYP, FAC_TAGFORM_CON, FAC_TAGCLASS_COS, 4, F_1_4 },
503 {ST_EXP_INV_ID, FAC_TAGFORM_PRI, FAC_TAGCLASS_UNI, FAC_CODEUNI_INT, F_2 },
504 {ST_EXP_OP_VAL, FAC_TAGFORM_PRI, FAC_TAGCLASS_UNI, FAC_CODEUNI_INT, F_3 },
505 {ST_EXP_INFO, FAC_TAGFORM_CON, FAC_TAGCLASS_UNI, FAC_CODEUNI_SEQ, F_4 },
506 {ST_EXP_INFO, FAC_TAGFORM_PRI, FAC_TAGCLASS_UNI, FAC_CODEUNI_NULL, F_4_1 },
507 {ST_EXP_INFO, FAC_TAGFORM_PRI, FAC_TAGCLASS_COS, 1, F_4_2 },
508 {ST_EXP_RUL, FAC_TAGFORM_CON, FAC_TAGCLASS_COS, 1, F_5 },
509 {ST_EXP_RU, FAC_TAGFORM_CON, FAC_TAGCLASS_UNI, FAC_CODEUNI_SEQ, F_6 },
510 {ST_EXP_RNOU, FAC_TAGFORM_PRI, FAC_TAGCLASS_UNI, FAC_CODEUNI_INT, F_7 },
511 {ST_EXP_TOCI, FAC_TAGFORM_PRI, FAC_TAGCLASS_COS, 2, F_8 },
512 {ST_EXP_DBID, FAC_TAGFORM_PRI, FAC_TAGCLASS_COS, 3, F_9 },
513 {-1, -1, -1, -1, NULL }
516 /*---------------------------------------------------------------------------*
517 * state decode for do_component
518 *---------------------------------------------------------------------------*/
520 next_state(int class, int form, int code, int val)
526 if((statetab[i].currstate > state) ||
527 (statetab[i].currstate == -1))
532 if((statetab[i].currstate == state) &&
533 (statetab[i].form == form) &&
534 (statetab[i].class == class) &&
535 (statetab[i].code == code))
537 (*statetab[i].func)(val);