Expand PMF_FN_* macros.
[netbsd-mini2440.git] / sys / netisdn / i4b_q932fac.c
blobe1354ca250adc6a2974fcd09c4b9a1e828eaa3aa
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 * i4b_q932fac.c - Q932 facility handling
28 * --------------------------------------
30 * $Id: i4b_q932fac.c,v 1.5 2005/12/11 12:25:06 christos Exp $
32 * $FreeBSD$
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 $");
41 #ifdef __FreeBSD__
42 #include "i4bq931.h"
43 #else
44 #define NI4BQ931 1
45 #endif
46 #if NI4BQ931 > 0
48 #include <sys/param.h>
49 #include <sys/kernel.h>
50 #include <sys/systm.h>
51 #include <sys/mbuf.h>
52 #include <sys/socket.h>
53 #include <net/if.h>
55 #if defined(__NetBSD__) && __NetBSD_Version__ >= 104230000
56 #include <sys/callout.h>
57 #endif
59 #ifdef __FreeBSD__
60 #include <machine/i4b_debug.h>
61 #include <machine/i4b_ioctl.h>
62 #else
63 #include <netisdn/i4b_debug.h>
64 #include <netisdn/i4b_ioctl.h>
65 #endif
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);
81 static int byte_len;
82 static unsigned char *byte_buf;
83 static int state;
85 static int units;
86 static int operation_value;
88 /*---------------------------------------------------------------------------*
89 * decode Q.931/Q.932 facility info element
90 *---------------------------------------------------------------------------*/
91 int
92 i4b_aoc(unsigned char *buf, call_desc_t *cd)
94 int len;
96 cd->units_type = CHARGE_INVALID;
97 cd->units = -1;
99 buf++; /* length */
101 len = *buf;
103 buf++; /* protocol profile */
105 switch(*buf & 0x1f)
107 case FAC_PROTO_ROP:
108 break;
110 case FAC_PROTO_CMIP:
111 NDBGL3(L3_A_MSG, "CMIP Protocol (Q.941), UNSUPPORTED");
112 return(-1);
113 break;
115 case FAC_PROTO_ACSE:
116 NDBGL3(L3_A_MSG, "ACSE Protocol (X.217/X.227), UNSUPPORTED!");
117 return(-1);
118 break;
120 default:
121 NDBGL3(L3_A_ERR, "Unknown Protocol, UNSUPPORTED!");
122 return(-1);
123 break;
126 NDBGL3(L3_A_MSG, "Remote Operations Protocol");
128 /* next byte */
130 buf++;
131 len--;
133 /* initialize variables for do_component */
135 byte_len = 0;
136 byte_buf = buf;
137 state = ST_EXP_COMP_TYP;
139 /* decode facility */
141 do_component(len);
143 switch(operation_value)
145 case FAC_OPVAL_AOC_D_CUR:
146 cd->units_type = CHARGE_AOCD;
147 cd->units = 0;
148 return(0);
149 break;
151 case FAC_OPVAL_AOC_D_UNIT:
152 cd->units_type = CHARGE_AOCD;
153 cd->units = units;
154 return(0);
155 break;
157 case FAC_OPVAL_AOC_E_CUR:
158 cd->units_type = CHARGE_AOCE;
159 cd->units = 0;
160 return(0);
161 break;
163 case FAC_OPVAL_AOC_E_UNIT:
164 cd->units_type = CHARGE_AOCE;
165 cd->units = units;
166 return(0);
167 break;
169 default:
170 cd->units_type = CHARGE_INVALID;
171 cd->units = -1;
172 return(-1);
173 break;
175 return(-1);
178 /*---------------------------------------------------------------------------*
179 * handle a component recursively
180 *---------------------------------------------------------------------------*/
181 static int
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 */
189 again:
191 /*----------------------------------------*/
192 /* first component element: component tag */
193 /*----------------------------------------*/
195 /* tag class bits */
197 comp_tag_class = (*byte_buf & 0xc0) >> 6;
199 switch(comp_tag_class)
201 case FAC_TAGCLASS_UNI:
202 break;
203 case FAC_TAGCLASS_APW:
204 break;
205 case FAC_TAGCLASS_COS:
206 break;
207 case FAC_TAGCLASS_PRU:
208 break;
211 /* tag form bit */
213 comp_tag_form = (*byte_buf & 0x20) > 5;
215 /* tag code bits */
217 comp_tag_code = *byte_buf & 0x1f;
219 if(comp_tag_code == 0x1f)
221 comp_tag_code = 0;
223 byte_buf++;
224 byte_len++;
226 while(*byte_buf & 0x80)
228 comp_tag_code += (*byte_buf & 0x7f);
229 byte_buf++;
230 byte_len++;
232 comp_tag_code += (*byte_buf & 0x7f);
234 else
236 comp_tag_code = (*byte_buf & 0x1f);
239 byte_buf++;
240 byte_len++;
242 /*--------------------------------------------*/
243 /* second component element: component length */
244 /*--------------------------------------------*/
246 comp_length = 0;
248 if(*byte_buf & 0x80)
250 int i = *byte_buf & 0x7f;
252 byte_len += i;
254 for(;i > 0;i++)
256 byte_buf++;
257 comp_length += (*byte_buf * (i*256));
260 else
262 comp_length = *byte_buf & 0x7f;
265 next_state(comp_tag_class, comp_tag_form, comp_tag_code, -1);
267 byte_len++;
268 byte_buf++;
270 /*---------------------------------------------*/
271 /* third component element: component contents */
272 /*---------------------------------------------*/
274 if(comp_tag_form) /* == constructor */
276 do_component(comp_length);
278 else
280 int val = 0;
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:
288 if(comp_length)
290 int i;
292 for(i = comp_length-1; i >= 0; i--)
294 val += (*byte_buf + (i*255));
295 byte_buf++;
296 byte_len++;
299 break;
300 default:
301 if(comp_length)
303 int i;
305 for(i = comp_length-1; i >= 0; i--)
307 byte_buf++;
308 byte_len++;
311 break;
315 else /* comp_tag_class != FAC_TAGCLASS_UNI */
317 if(comp_length)
319 int i;
321 for(i = comp_length-1; i >= 0; i--)
323 val += (*byte_buf + (i*255));
324 byte_buf++;
325 byte_len++;
329 next_state(comp_tag_class, comp_tag_form, comp_tag_code, val);
332 if(byte_len < length)
333 goto again;
335 return(byte_len);
338 /*---------------------------------------------------------------------------*
339 * invoke component
340 *---------------------------------------------------------------------------*/
341 static void
342 F_1_1(int val)
344 if(val == -1)
346 state = ST_EXP_INV_ID;
350 /*---------------------------------------------------------------------------*
351 * return result
352 *---------------------------------------------------------------------------*/
353 static void
354 F_1_2(int val)
356 if(val == -1)
357 state = ST_EXP_NIX;
359 /*---------------------------------------------------------------------------*
360 * return error
361 *---------------------------------------------------------------------------*/
362 static void
363 F_1_3(int val)
365 if(val == -1)
366 state = ST_EXP_NIX;
368 /*---------------------------------------------------------------------------*
369 * reject
370 *---------------------------------------------------------------------------*/
371 static void
372 F_1_4(int val)
374 if(val == -1)
375 state = ST_EXP_NIX;
378 /*---------------------------------------------------------------------------*
379 * invoke id
380 *---------------------------------------------------------------------------*/
381 static void
382 F_2(int val)
384 if(val != -1)
386 NDBGL3(L3_A_MSG, "Invoke ID = %d", val);
387 state = ST_EXP_OP_VAL;
391 /*---------------------------------------------------------------------------*
392 * operation value
393 *---------------------------------------------------------------------------*/
394 static void
395 F_3(int val)
397 if(val != -1)
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))
405 units = 0;
406 state = ST_EXP_INFO;
408 else
410 state = ST_EXP_NIX;
415 /*---------------------------------------------------------------------------*
416 * specific charging units
417 *---------------------------------------------------------------------------*/
418 static void
419 F_4(int val)
421 if(val == -1)
422 state = ST_EXP_RUL;
425 /*---------------------------------------------------------------------------*
426 * free of charge
427 *---------------------------------------------------------------------------*/
428 static void
429 F_4_1(int val)
431 if(val == -1)
433 NDBGL3(L3_A_MSG, "Free of Charge");
434 /* units = 0; XXXX */
435 state = ST_EXP_NIX;
439 /*---------------------------------------------------------------------------*
440 * charge not available
441 *---------------------------------------------------------------------------*/
442 static void
443 F_4_2(int val)
445 if(val == -1)
447 NDBGL3(L3_A_MSG, "Charge not available");
448 /* units = -1; XXXXXX ??? */
449 state = ST_EXP_NIX;
453 /*---------------------------------------------------------------------------*
454 * recorded units list
455 *---------------------------------------------------------------------------*/
456 static void
457 F_5(int val)
459 if(val == -1)
460 state = ST_EXP_RU;
463 /*---------------------------------------------------------------------------*
464 * recorded units
465 *---------------------------------------------------------------------------*/
466 static void
467 F_6(int val)
469 if(val == -1)
470 state = ST_EXP_RNOU;
473 /*---------------------------------------------------------------------------*
474 * number of units
475 *---------------------------------------------------------------------------*/
476 static void
477 F_7(int val)
479 if(val != -1)
481 NDBGL3(L3_A_MSG, "Number of Units = %d", val);
482 units = val;
483 state = ST_EXP_TOCI;
487 /*---------------------------------------------------------------------------*
488 * subtotal/total
489 *---------------------------------------------------------------------------*/
490 static void
491 F_8(int val)
493 if(val != -1)
495 NDBGL3(L3_A_MSG, "Subtotal/Total = %d", val);
496 /* type_of_charge = val; */
497 state = ST_EXP_DBID;
501 /*---------------------------------------------------------------------------*
502 * billing_id
503 *---------------------------------------------------------------------------*/
504 static void
505 F_9(int val)
507 if(val != -1)
509 NDBGL3(L3_A_MSG, "Billing ID = %d", val);
510 /* billing_id = val; */
511 state = ST_EXP_NIX;
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 */
524 } statetab[] = {
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 *---------------------------------------------------------------------------*/
548 static void
549 next_state(int class, int form, int code, int val)
551 int i;
553 for(i=0; ; i++)
555 if((statetab[i].currstate > state) ||
556 (statetab[i].currstate == -1))
558 break;
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);
567 break;
572 #endif /* NI4BQ931 > 0 */