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.5 2005/12/11 12:25:06 christos Exp $
34 * last edit-date: [Fri Jan 5 11:33:47 2001]
36 *---------------------------------------------------------------------------*/
38 #include <sys/cdefs.h>
39 __KERNEL_RCSID(0, "$NetBSD: i4b_q932fac.c,v 1.3.16.1 2005/03/04 16:53:45 skrll Exp $");
48 #include <sys/param.h>
49 #include <sys/kernel.h>
50 #include <sys/systm.h>
52 #include <sys/socket.h>
55 #if defined(__NetBSD__) && __NetBSD_Version__ >= 104230000
56 #include <sys/callout.h>
60 #include <machine/i4b_debug.h>
61 #include <machine/i4b_ioctl.h>
63 #include <netisdn/i4b_debug.h>
64 #include <netisdn/i4b_ioctl.h>
67 #include <netisdn/i4b_isdnq931.h>
68 #include <netisdn/i4b_l3l4.h>
69 #include <netisdn/i4b_mbuf.h>
71 #include <netisdn/i4b_l3.h>
72 #include <netisdn/i4b_l3fsm.h>
73 #include <netisdn/i4b_q931.h>
74 #include <netisdn/i4b_q932fac.h>
76 #include <netisdn/i4b_l4.h>
78 static int do_component(int length
);
79 static void next_state(int class, int form
, int code
, int val
);
82 static unsigned char *byte_buf
;
86 static int operation_value
;
88 /*---------------------------------------------------------------------------*
89 * decode Q.931/Q.932 facility info element
90 *---------------------------------------------------------------------------*/
92 i4b_aoc(unsigned char *buf
, call_desc_t
*cd
)
96 cd
->units_type
= CHARGE_INVALID
;
103 buf
++; /* protocol profile */
111 NDBGL3(L3_A_MSG
, "CMIP Protocol (Q.941), UNSUPPORTED");
116 NDBGL3(L3_A_MSG
, "ACSE Protocol (X.217/X.227), UNSUPPORTED!");
121 NDBGL3(L3_A_ERR
, "Unknown Protocol, UNSUPPORTED!");
126 NDBGL3(L3_A_MSG
, "Remote Operations Protocol");
133 /* initialize variables for do_component */
137 state
= ST_EXP_COMP_TYP
;
139 /* decode facility */
143 switch(operation_value
)
145 case FAC_OPVAL_AOC_D_CUR
:
146 cd
->units_type
= CHARGE_AOCD
;
151 case FAC_OPVAL_AOC_D_UNIT
:
152 cd
->units_type
= CHARGE_AOCD
;
157 case FAC_OPVAL_AOC_E_CUR
:
158 cd
->units_type
= CHARGE_AOCE
;
163 case FAC_OPVAL_AOC_E_UNIT
:
164 cd
->units_type
= CHARGE_AOCE
;
170 cd
->units_type
= CHARGE_INVALID
;
178 /*---------------------------------------------------------------------------*
179 * handle a component recursively
180 *---------------------------------------------------------------------------*/
182 do_component(int length
)
184 int comp_tag_class
; /* component tag class */
185 int comp_tag_form
; /* component form: constructor or primitive */
186 int comp_tag_code
; /* component code depending on class */
187 int comp_length
= 0; /* component length */
191 /*----------------------------------------*/
192 /* first component element: component tag */
193 /*----------------------------------------*/
197 comp_tag_class
= (*byte_buf
& 0xc0) >> 6;
199 switch(comp_tag_class
)
201 case FAC_TAGCLASS_UNI
:
203 case FAC_TAGCLASS_APW
:
205 case FAC_TAGCLASS_COS
:
207 case FAC_TAGCLASS_PRU
:
213 comp_tag_form
= (*byte_buf
& 0x20) > 5;
217 comp_tag_code
= *byte_buf
& 0x1f;
219 if(comp_tag_code
== 0x1f)
226 while(*byte_buf
& 0x80)
228 comp_tag_code
+= (*byte_buf
& 0x7f);
232 comp_tag_code
+= (*byte_buf
& 0x7f);
236 comp_tag_code
= (*byte_buf
& 0x1f);
242 /*--------------------------------------------*/
243 /* second component element: component length */
244 /*--------------------------------------------*/
250 int i
= *byte_buf
& 0x7f;
257 comp_length
+= (*byte_buf
* (i
*256));
262 comp_length
= *byte_buf
& 0x7f;
265 next_state(comp_tag_class
, comp_tag_form
, comp_tag_code
, -1);
270 /*---------------------------------------------*/
271 /* third component element: component contents */
272 /*---------------------------------------------*/
274 if(comp_tag_form
) /* == constructor */
276 do_component(comp_length
);
281 if(comp_tag_class
== FAC_TAGCLASS_UNI
)
283 switch(comp_tag_code
)
285 case FAC_CODEUNI_INT
:
286 case FAC_CODEUNI_ENUM
:
287 case FAC_CODEUNI_BOOL
:
292 for(i
= comp_length
-1; i
>= 0; i
--)
294 val
+= (*byte_buf
+ (i
*255));
305 for(i
= comp_length
-1; i
>= 0; i
--)
315 else /* comp_tag_class != FAC_TAGCLASS_UNI */
321 for(i
= comp_length
-1; i
>= 0; i
--)
323 val
+= (*byte_buf
+ (i
*255));
329 next_state(comp_tag_class
, comp_tag_form
, comp_tag_code
, val
);
332 if(byte_len
< length
)
338 /*---------------------------------------------------------------------------*
340 *---------------------------------------------------------------------------*/
346 state
= ST_EXP_INV_ID
;
350 /*---------------------------------------------------------------------------*
352 *---------------------------------------------------------------------------*/
359 /*---------------------------------------------------------------------------*
361 *---------------------------------------------------------------------------*/
368 /*---------------------------------------------------------------------------*
370 *---------------------------------------------------------------------------*/
378 /*---------------------------------------------------------------------------*
380 *---------------------------------------------------------------------------*/
386 NDBGL3(L3_A_MSG
, "Invoke ID = %d", val
);
387 state
= ST_EXP_OP_VAL
;
391 /*---------------------------------------------------------------------------*
393 *---------------------------------------------------------------------------*/
399 NDBGL3(L3_A_MSG
, "Operation Value = %d", val
);
401 operation_value
= val
;
403 if((val
== FAC_OPVAL_AOC_D_UNIT
) || (val
== FAC_OPVAL_AOC_E_UNIT
))
415 /*---------------------------------------------------------------------------*
416 * specific charging units
417 *---------------------------------------------------------------------------*/
425 /*---------------------------------------------------------------------------*
427 *---------------------------------------------------------------------------*/
433 NDBGL3(L3_A_MSG
, "Free of Charge");
434 /* units = 0; XXXX */
439 /*---------------------------------------------------------------------------*
440 * charge not available
441 *---------------------------------------------------------------------------*/
447 NDBGL3(L3_A_MSG
, "Charge not available");
448 /* units = -1; XXXXXX ??? */
453 /*---------------------------------------------------------------------------*
454 * recorded units list
455 *---------------------------------------------------------------------------*/
463 /*---------------------------------------------------------------------------*
465 *---------------------------------------------------------------------------*/
473 /*---------------------------------------------------------------------------*
475 *---------------------------------------------------------------------------*/
481 NDBGL3(L3_A_MSG
, "Number of Units = %d", val
);
487 /*---------------------------------------------------------------------------*
489 *---------------------------------------------------------------------------*/
495 NDBGL3(L3_A_MSG
, "Subtotal/Total = %d", val
);
496 /* type_of_charge = val; */
501 /*---------------------------------------------------------------------------*
503 *---------------------------------------------------------------------------*/
509 NDBGL3(L3_A_MSG
, "Billing ID = %d", val
);
510 /* billing_id = val; */
515 /*---------------------------------------------------------------------------*
517 *---------------------------------------------------------------------------*/
518 static struct statetab
{
519 int currstate
; /* input: current state we are in */
520 int form
; /* input: current tag form */
521 int class; /* input: current tag class */
522 int code
; /* input: current tag code */
523 void (*func
)(int); /* output: func to exec */
526 /* current state tag form tag class tag code function */
527 /* --------------------- ---------------------- ---------------------- ---------------------- ----------------*/
528 {ST_EXP_COMP_TYP
, FAC_TAGFORM_CON
, FAC_TAGCLASS_COS
, 1, F_1_1
},
529 {ST_EXP_COMP_TYP
, FAC_TAGFORM_CON
, FAC_TAGCLASS_COS
, 2, F_1_2
},
530 {ST_EXP_COMP_TYP
, FAC_TAGFORM_CON
, FAC_TAGCLASS_COS
, 3, F_1_3
},
531 {ST_EXP_COMP_TYP
, FAC_TAGFORM_CON
, FAC_TAGCLASS_COS
, 4, F_1_4
},
532 {ST_EXP_INV_ID
, FAC_TAGFORM_PRI
, FAC_TAGCLASS_UNI
, FAC_CODEUNI_INT
, F_2
},
533 {ST_EXP_OP_VAL
, FAC_TAGFORM_PRI
, FAC_TAGCLASS_UNI
, FAC_CODEUNI_INT
, F_3
},
534 {ST_EXP_INFO
, FAC_TAGFORM_CON
, FAC_TAGCLASS_UNI
, FAC_CODEUNI_SEQ
, F_4
},
535 {ST_EXP_INFO
, FAC_TAGFORM_PRI
, FAC_TAGCLASS_UNI
, FAC_CODEUNI_NULL
, F_4_1
},
536 {ST_EXP_INFO
, FAC_TAGFORM_PRI
, FAC_TAGCLASS_COS
, 1, F_4_2
},
537 {ST_EXP_RUL
, FAC_TAGFORM_CON
, FAC_TAGCLASS_COS
, 1, F_5
},
538 {ST_EXP_RU
, FAC_TAGFORM_CON
, FAC_TAGCLASS_UNI
, FAC_CODEUNI_SEQ
, F_6
},
539 {ST_EXP_RNOU
, FAC_TAGFORM_PRI
, FAC_TAGCLASS_UNI
, FAC_CODEUNI_INT
, F_7
},
540 {ST_EXP_TOCI
, FAC_TAGFORM_PRI
, FAC_TAGCLASS_COS
, 2, F_8
},
541 {ST_EXP_DBID
, FAC_TAGFORM_PRI
, FAC_TAGCLASS_COS
, 3, F_9
},
542 {-1, -1, -1, -1, NULL
}
545 /*---------------------------------------------------------------------------*
546 * state decode for do_component
547 *---------------------------------------------------------------------------*/
549 next_state(int class, int form
, int code
, int val
)
555 if((statetab
[i
].currstate
> state
) ||
556 (statetab
[i
].currstate
== -1))
561 if((statetab
[i
].currstate
== state
) &&
562 (statetab
[i
].form
== form
) &&
563 (statetab
[i
].class == class) &&
564 (statetab
[i
].code
== code
))
566 (*statetab
[i
].func
)(val
);
572 #endif /* NI4BQ931 > 0 */