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
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
25 *---------------------------------------------------------------------------
27 * i4b_q932fac.c - Q932 facility handling
28 * --------------------------------------
30 * $Id: i4b_q932fac.c,v 1.11 2000/08/24 11:48:58 hm Exp $
32 * $FreeBSD: src/sys/i4b/layer3/i4b_q932fac.c,v 1.6.2.1 2001/08/10 14:08:42 obrien Exp $
34 * last edit-date: [Mon May 29 16:57:04 2000]
36 *---------------------------------------------------------------------------*/
45 #include <sys/param.h>
46 #include <sys/systm.h>
49 #if defined(__NetBSD__) && __NetBSD_Version__ >= 104230000
50 #include <sys/callout.h>
54 #include <machine/i4b_debug.h>
55 #include <machine/i4b_ioctl.h>
57 #include <i4b/i4b_debug.h>
58 #include <i4b/i4b_ioctl.h>
61 #include <i4b/include/i4b_l3l4.h>
63 #include <i4b/layer3/i4b_l3.h>
64 #include <i4b/layer3/i4b_q932fac.h>
67 static int do_component(int length);
68 static void next_state(int class, int form, int code, int val);
71 static unsigned char *byte_buf;
75 static int operation_value;
77 /*---------------------------------------------------------------------------*
78 * decode Q.931/Q.932 facility info element
79 *---------------------------------------------------------------------------*/
81 i4b_aoc(unsigned char *buf, call_desc_t *cd)
85 cd->units_type = CHARGE_INVALID;
92 buf++; /* protocol profile */
100 NDBGL3(L3_A_MSG, "CMIP Protocol (Q.941), UNSUPPORTED");
105 NDBGL3(L3_A_MSG, "ACSE Protocol (X.217/X.227), UNSUPPORTED!");
110 NDBGL3(L3_A_ERR, "Unknown Protocol, UNSUPPORTED!");
115 NDBGL3(L3_A_MSG, "Remote Operations Protocol");
122 /* initialize variables for do_component */
126 state = ST_EXP_COMP_TYP;
128 /* decode facility */
132 switch(operation_value)
134 case FAC_OPVAL_AOC_D_CUR:
135 cd->units_type = CHARGE_AOCD;
140 case FAC_OPVAL_AOC_D_UNIT:
141 cd->units_type = CHARGE_AOCD;
146 case FAC_OPVAL_AOC_E_CUR:
147 cd->units_type = CHARGE_AOCE;
152 case FAC_OPVAL_AOC_E_UNIT:
153 cd->units_type = CHARGE_AOCE;
159 cd->units_type = CHARGE_INVALID;
167 /*---------------------------------------------------------------------------*
168 * handle a component recursively
169 *---------------------------------------------------------------------------*/
171 do_component(int length)
173 int comp_tag_class; /* component tag class */
174 int comp_tag_form; /* component form: constructor or primitive */
175 int comp_tag_code; /* component code depending on class */
176 int comp_length = 0; /* component length */
180 /*----------------------------------------*/
181 /* first component element: component tag */
182 /*----------------------------------------*/
186 comp_tag_class = (*byte_buf & 0xc0) >> 6;
188 switch(comp_tag_class)
190 case FAC_TAGCLASS_UNI:
192 case FAC_TAGCLASS_APW:
194 case FAC_TAGCLASS_COS:
196 case FAC_TAGCLASS_PRU:
202 comp_tag_form = (*byte_buf & 0x20) > 5;
206 comp_tag_code = *byte_buf & 0x1f;
208 if(comp_tag_code == 0x1f)
215 while(*byte_buf & 0x80)
217 comp_tag_code += (*byte_buf & 0x7f);
221 comp_tag_code += (*byte_buf & 0x7f);
225 comp_tag_code = (*byte_buf & 0x1f);
231 /*--------------------------------------------*/
232 /* second component element: component length */
233 /*--------------------------------------------*/
239 int i = *byte_buf & 0x7f;
246 comp_length += (*byte_buf * (i*256));
251 comp_length = *byte_buf & 0x7f;
254 next_state(comp_tag_class, comp_tag_form, comp_tag_code, -1);
259 /*---------------------------------------------*/
260 /* third component element: component contents */
261 /*---------------------------------------------*/
263 if(comp_tag_form) /* == constructor */
265 do_component(comp_length);
270 if(comp_tag_class == FAC_TAGCLASS_UNI)
272 switch(comp_tag_code)
274 case FAC_CODEUNI_INT:
275 case FAC_CODEUNI_ENUM:
276 case FAC_CODEUNI_BOOL:
281 for(i = comp_length-1; i >= 0; i--)
283 val += (*byte_buf + (i*255));
294 for(i = comp_length-1; i >= 0; i--)
304 else /* comp_tag_class != FAC_TAGCLASS_UNI */
310 for(i = comp_length-1; i >= 0; i--)
312 val += (*byte_buf + (i*255));
318 next_state(comp_tag_class, comp_tag_form, comp_tag_code, val);
321 if(byte_len < length)
327 /*---------------------------------------------------------------------------*
329 *---------------------------------------------------------------------------*/
335 state = ST_EXP_INV_ID;
339 /*---------------------------------------------------------------------------*
341 *---------------------------------------------------------------------------*/
348 /*---------------------------------------------------------------------------*
350 *---------------------------------------------------------------------------*/
357 /*---------------------------------------------------------------------------*
359 *---------------------------------------------------------------------------*/
367 /*---------------------------------------------------------------------------*
369 *---------------------------------------------------------------------------*/
375 NDBGL3(L3_A_MSG, "Invoke ID = %d", val);
376 state = ST_EXP_OP_VAL;
380 /*---------------------------------------------------------------------------*
382 *---------------------------------------------------------------------------*/
388 NDBGL3(L3_A_MSG, "Operation Value = %d", val);
390 operation_value = val;
392 if((val == FAC_OPVAL_AOC_D_UNIT) || (val == FAC_OPVAL_AOC_E_UNIT))
404 /*---------------------------------------------------------------------------*
405 * specific charging units
406 *---------------------------------------------------------------------------*/
414 /*---------------------------------------------------------------------------*
416 *---------------------------------------------------------------------------*/
422 NDBGL3(L3_A_MSG, "Free of Charge");
423 /* units = 0; XXXX */
428 /*---------------------------------------------------------------------------*
429 * charge not available
430 *---------------------------------------------------------------------------*/
436 NDBGL3(L3_A_MSG, "Charge not available");
437 /* units = -1; XXXXXX ??? */
442 /*---------------------------------------------------------------------------*
443 * recorded units list
444 *---------------------------------------------------------------------------*/
452 /*---------------------------------------------------------------------------*
454 *---------------------------------------------------------------------------*/
462 /*---------------------------------------------------------------------------*
464 *---------------------------------------------------------------------------*/
470 NDBGL3(L3_A_MSG, "Number of Units = %d", val);
476 /*---------------------------------------------------------------------------*
478 *---------------------------------------------------------------------------*/
484 NDBGL3(L3_A_MSG, "Subtotal/Total = %d", val);
485 /* type_of_charge = val; */
490 /*---------------------------------------------------------------------------*
492 *---------------------------------------------------------------------------*/
498 NDBGL3(L3_A_MSG, "Billing ID = %d", val);
499 /* billing_id = val; */
504 /*---------------------------------------------------------------------------*
506 *---------------------------------------------------------------------------*/
507 static struct statetab {
508 int currstate; /* input: current state we are in */
509 int form; /* input: current tag form */
510 int class; /* input: current tag class */
511 int code; /* input: current tag code */
512 void (*func)(int); /* output: func to exec */
515 /* current state tag form tag class tag code function */
516 /* --------------------- ---------------------- ---------------------- ---------------------- ----------------*/
517 {ST_EXP_COMP_TYP, FAC_TAGFORM_CON, FAC_TAGCLASS_COS, 1, F_1_1 },
518 {ST_EXP_COMP_TYP, FAC_TAGFORM_CON, FAC_TAGCLASS_COS, 2, F_1_2 },
519 {ST_EXP_COMP_TYP, FAC_TAGFORM_CON, FAC_TAGCLASS_COS, 3, F_1_3 },
520 {ST_EXP_COMP_TYP, FAC_TAGFORM_CON, FAC_TAGCLASS_COS, 4, F_1_4 },
521 {ST_EXP_INV_ID, FAC_TAGFORM_PRI, FAC_TAGCLASS_UNI, FAC_CODEUNI_INT, F_2 },
522 {ST_EXP_OP_VAL, FAC_TAGFORM_PRI, FAC_TAGCLASS_UNI, FAC_CODEUNI_INT, F_3 },
523 {ST_EXP_INFO, FAC_TAGFORM_CON, FAC_TAGCLASS_UNI, FAC_CODEUNI_SEQ, F_4 },
524 {ST_EXP_INFO, FAC_TAGFORM_PRI, FAC_TAGCLASS_UNI, FAC_CODEUNI_NULL, F_4_1 },
525 {ST_EXP_INFO, FAC_TAGFORM_PRI, FAC_TAGCLASS_COS, 1, F_4_2 },
526 {ST_EXP_RUL, FAC_TAGFORM_CON, FAC_TAGCLASS_COS, 1, F_5 },
527 {ST_EXP_RU, FAC_TAGFORM_CON, FAC_TAGCLASS_UNI, FAC_CODEUNI_SEQ, F_6 },
528 {ST_EXP_RNOU, FAC_TAGFORM_PRI, FAC_TAGCLASS_UNI, FAC_CODEUNI_INT, F_7 },
529 {ST_EXP_TOCI, FAC_TAGFORM_PRI, FAC_TAGCLASS_COS, 2, F_8 },
530 {ST_EXP_DBID, FAC_TAGFORM_PRI, FAC_TAGCLASS_COS, 3, F_9 },
531 {-1, -1, -1, -1, NULL }
534 /*---------------------------------------------------------------------------*
535 * state decode for do_component
536 *---------------------------------------------------------------------------*/
538 next_state(int class, int form, int code, int val)
544 if((statetab[i].currstate > state) ||
545 (statetab[i].currstate == -1))
550 if((statetab[i].currstate == state) &&
551 (statetab[i].form == form) &&
552 (statetab[i].class == class) &&
553 (statetab[i].code == code))
555 (*statetab[i].func)(val);
561 #endif /* NI4BQ931 > 0 */