The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/netisdn/i4b_q932fac.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved.
    3  *
    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.
   12  *
   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.
   24  *
   25  *---------------------------------------------------------------------------
   26  *
   27  *      i4b_q932fac.c - Q932 facility handling
   28  *      --------------------------------------
   29  *
   30  *      $Id: i4b_q932fac.c,v 1.4 2005/02/26 22:39:49 perry Exp $
   31  *
   32  * $FreeBSD$
   33  *
   34  *      last edit-date: [Fri Jan  5 11:33:47 2001]
   35  *
   36  *---------------------------------------------------------------------------*/
   37 
   38 #include <sys/cdefs.h>
   39 __KERNEL_RCSID(0, "$NetBSD: i4b_q932fac.c,v 1.4 2005/02/26 22:39:49 perry Exp $");
   40 
   41 #ifdef __FreeBSD__
   42 #include "i4bq931.h"
   43 #else
   44 #define NI4BQ931        1
   45 #endif
   46 #if NI4BQ931 > 0
   47 
   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>
   54 
   55 #if defined(__NetBSD__) && __NetBSD_Version__ >= 104230000
   56 #include <sys/callout.h>
   57 #endif
   58 
   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
   66 
   67 #include <netisdn/i4b_isdnq931.h>
   68 #include <netisdn/i4b_l3l4.h>
   69 #include <netisdn/i4b_mbuf.h>
   70 
   71 #include <netisdn/i4b_l3.h>
   72 #include <netisdn/i4b_l3fsm.h>
   73 #include <netisdn/i4b_q931.h>
   74 #include <netisdn/i4b_q932fac.h>
   75 
   76 #include <netisdn/i4b_l4.h>
   77 
   78 static int do_component(int length);
   79 static void next_state(int class, int form, int code, int val);
   80 
   81 static int byte_len;
   82 static unsigned char *byte_buf;
   83 static int state;
   84 
   85 static int units;
   86 static int operation_value;
   87 
   88 /*---------------------------------------------------------------------------*
   89  *      decode Q.931/Q.932 facility info element
   90  *---------------------------------------------------------------------------*/
   91 int
   92 i4b_aoc(unsigned char *buf, call_desc_t *cd)
   93 {
   94         int len;
   95 
   96         cd->units_type = CHARGE_INVALID;
   97         cd->units = -1;
   98 
   99         buf++;          /* length */
  100 
  101         len = *buf;
  102 
  103         buf++;          /* protocol profile */
  104 
  105         switch(*buf & 0x1f)
  106         {
  107                 case FAC_PROTO_ROP:
  108                         break;
  109 
  110                 case FAC_PROTO_CMIP:
  111                         NDBGL3(L3_A_MSG, "CMIP Protocol (Q.941), UNSUPPORTED");
  112                         return(-1);
  113                         break;
  114 
  115                 case FAC_PROTO_ACSE:
  116                         NDBGL3(L3_A_MSG, "ACSE Protocol (X.217/X.227), UNSUPPORTED!");
  117                         return(-1);
  118                         break;
  119 
  120                 default:
  121                         NDBGL3(L3_A_ERR, "Unknown Protocol, UNSUPPORTED!");
  122                         return(-1);
  123                         break;
  124         }
  125 
  126         NDBGL3(L3_A_MSG, "Remote Operations Protocol");
  127 
  128         /* next byte */
  129 
  130         buf++;
  131         len--;
  132 
  133         /* initialize variables for do_component */
  134 
  135         byte_len = 0;
  136         byte_buf = buf;
  137         state = ST_EXP_COMP_TYP;
  138 
  139         /* decode facility */
  140 
  141         do_component(len);
  142 
  143         switch(operation_value)
  144         {
  145                 case FAC_OPVAL_AOC_D_CUR:
  146                         cd->units_type = CHARGE_AOCD;
  147                         cd->units = 0;
  148                         return(0);
  149                         break;
  150 
  151                 case FAC_OPVAL_AOC_D_UNIT:
  152                         cd->units_type = CHARGE_AOCD;
  153                         cd->units = units;
  154                         return(0);
  155                         break;
  156 
  157                 case FAC_OPVAL_AOC_E_CUR:
  158                         cd->units_type = CHARGE_AOCE;
  159                         cd->units = 0;
  160                         return(0);
  161                         break;
  162 
  163                 case FAC_OPVAL_AOC_E_UNIT:
  164                         cd->units_type = CHARGE_AOCE;
  165                         cd->units = units;
  166                         return(0);
  167                         break;
  168 
  169                 default:
  170                         cd->units_type = CHARGE_INVALID;
  171                         cd->units = -1;
  172                         return(-1);
  173                         break;
  174         }
  175         return(-1);
  176 }
  177 
  178 /*---------------------------------------------------------------------------*
  179  *      handle a component recursively
  180  *---------------------------------------------------------------------------*/
  181 static int
  182 do_component(int length)
  183 {
  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 */
  188 
  189 again:
  190 
  191         /*----------------------------------------*/
  192         /* first component element: component tag */
  193         /*----------------------------------------*/
  194 
  195         /* tag class bits */
  196 
  197         comp_tag_class = (*byte_buf & 0xc0) >> 6;
  198 
  199         switch(comp_tag_class)
  200         {
  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;
  209         }
  210 
  211         /* tag form bit */
  212 
  213         comp_tag_form = (*byte_buf & 0x20) > 5;
  214 
  215         /* tag code bits */
  216 
  217         comp_tag_code = *byte_buf & 0x1f;
  218 
  219         if(comp_tag_code == 0x1f)
  220         {
  221                 comp_tag_code = 0;
  222 
  223                 byte_buf++;
  224                 byte_len++;
  225 
  226                 while(*byte_buf & 0x80)
  227                 {
  228                         comp_tag_code += (*byte_buf & 0x7f);
  229                         byte_buf++;
  230                         byte_len++;
  231                 }
  232                 comp_tag_code += (*byte_buf & 0x7f);
  233         }
  234         else
  235         {
  236                 comp_tag_code = (*byte_buf & 0x1f);
  237         }
  238 
  239         byte_buf++;
  240         byte_len++;
  241 
  242         /*--------------------------------------------*/
  243         /* second component element: component length */
  244         /*--------------------------------------------*/
  245 
  246         comp_length = 0;
  247 
  248         if(*byte_buf & 0x80)
  249         {
  250                 int i = *byte_buf & 0x7f;
  251 
  252                 byte_len += i;
  253 
  254                 for(;i > 0;i++)
  255                 {
  256                         byte_buf++;
  257                         comp_length += (*byte_buf * (i*256));
  258                 }
  259         }
  260         else
  261         {
  262                 comp_length = *byte_buf & 0x7f;
  263         }
  264 
  265         next_state(comp_tag_class, comp_tag_form, comp_tag_code, -1);
  266 
  267         byte_len++;
  268         byte_buf++;
  269 
  270         /*---------------------------------------------*/
  271         /* third component element: component contents */
  272         /*---------------------------------------------*/
  273 
  274         if(comp_tag_form)       /* == constructor */
  275         {
  276                 do_component(comp_length);
  277         }
  278         else
  279         {
  280                 int val = 0;
  281                 if(comp_tag_class == FAC_TAGCLASS_UNI)
  282                 {
  283                         switch(comp_tag_code)
  284                         {
  285                                 case FAC_CODEUNI_INT:
  286                                 case FAC_CODEUNI_ENUM:
  287                                 case FAC_CODEUNI_BOOL:
  288                                         if(comp_length)
  289                                         {
  290                                                 int i;
  291 
  292                                                 for(i = comp_length-1; i >= 0; i--)
  293                                                 {
  294                                                         val += (*byte_buf + (i*255));
  295                                                         byte_buf++;
  296                                                         byte_len++;
  297                                                 }
  298                                         }
  299                                         break;
  300                                 default:
  301                                         if(comp_length)
  302                                         {
  303                                                 int i;
  304 
  305                                                 for(i = comp_length-1; i >= 0; i--)
  306                                                 {
  307                                                         byte_buf++;
  308                                                         byte_len++;
  309                                                 }
  310                                         }
  311                                         break;
  312                         }
  313                 }
  314 
  315                 else    /* comp_tag_class != FAC_TAGCLASS_UNI */
  316                 {
  317                         if(comp_length)
  318                         {
  319                                 int i;
  320 
  321                                 for(i = comp_length-1; i >= 0; i--)
  322                                 {
  323                                         val += (*byte_buf + (i*255));
  324                                         byte_buf++;
  325                                         byte_len++;
  326                                 }
  327                         }
  328                 }
  329                 next_state(comp_tag_class, comp_tag_form, comp_tag_code, val);
  330         }
  331 
  332         if(byte_len < length)
  333                 goto again;
  334 
  335         return(byte_len);
  336 }
  337 
  338 /*---------------------------------------------------------------------------*
  339  *      invoke component
  340  *---------------------------------------------------------------------------*/
  341 static void
  342 F_1_1(int val)
  343 {
  344         if(val == -1)
  345         {
  346                 state = ST_EXP_INV_ID;
  347         }
  348 }
  349 
  350 /*---------------------------------------------------------------------------*
  351  *      return result
  352  *---------------------------------------------------------------------------*/
  353 static void
  354 F_1_2(int val)
  355 {
  356         if(val == -1)
  357                 state = ST_EXP_NIX;
  358 }
  359 /*---------------------------------------------------------------------------*
  360  *      return error
  361  *---------------------------------------------------------------------------*/
  362 static void
  363 F_1_3(int val)
  364 {
  365         if(val == -1)
  366                 state = ST_EXP_NIX;
  367 }
  368 /*---------------------------------------------------------------------------*
  369  *      reject
  370  *---------------------------------------------------------------------------*/
  371 static void
  372 F_1_4(int val)
  373 {
  374         if(val == -1)
  375                 state = ST_EXP_NIX;
  376 }
  377 
  378 /*---------------------------------------------------------------------------*
  379  *      invoke id
  380  *---------------------------------------------------------------------------*/
  381 static void
  382 F_2(int val)
  383 {
  384         if(val != -1)
  385         {
  386                 NDBGL3(L3_A_MSG, "Invoke ID = %d", val);
  387                 state = ST_EXP_OP_VAL;
  388         }
  389 }
  390 
  391 /*---------------------------------------------------------------------------*
  392  *      operation value
  393  *---------------------------------------------------------------------------*/
  394 static void
  395 F_3(int val)
  396 {
  397         if(val != -1)
  398         {
  399                 NDBGL3(L3_A_MSG, "Operation Value = %d", val);
  400 
  401                 operation_value = val;
  402 
  403                 if((val == FAC_OPVAL_AOC_D_UNIT) || (val == FAC_OPVAL_AOC_E_UNIT))
  404                 {
  405                         units = 0;
  406                         state = ST_EXP_INFO;
  407                 }
  408                 else
  409                 {
  410                         state = ST_EXP_NIX;
  411                 }
  412         }
  413 }
  414 
  415 /*---------------------------------------------------------------------------*
  416  *      specific charging units
  417  *---------------------------------------------------------------------------*/
  418 static void
  419 F_4(int val)
  420 {
  421         if(val == -1)
  422                 state = ST_EXP_RUL;
  423 }
  424 
  425 /*---------------------------------------------------------------------------*
  426  *      free of charge
  427  *---------------------------------------------------------------------------*/
  428 static void
  429 F_4_1(int val)
  430 {
  431         if(val == -1)
  432         {
  433                 NDBGL3(L3_A_MSG, "Free of Charge");
  434                 /* units = 0; XXXX */
  435                 state = ST_EXP_NIX;
  436         }
  437 }
  438 
  439 /*---------------------------------------------------------------------------*
  440  *      charge not available
  441  *---------------------------------------------------------------------------*/
  442 static void
  443 F_4_2(int val)
  444 {
  445         if(val == -1)
  446         {
  447                 NDBGL3(L3_A_MSG, "Charge not available");
  448                 /* units = -1;  XXXXXX ??? */
  449                 state = ST_EXP_NIX;
  450         }
  451 }
  452 
  453 /*---------------------------------------------------------------------------*
  454  *      recorded units list
  455  *---------------------------------------------------------------------------*/
  456 static void
  457 F_5(int val)
  458 {
  459         if(val == -1)
  460                 state = ST_EXP_RU;
  461 }
  462 
  463 /*---------------------------------------------------------------------------*
  464  *      recorded units
  465  *---------------------------------------------------------------------------*/
  466 static void
  467 F_6(int val)
  468 {
  469         if(val == -1)
  470                 state = ST_EXP_RNOU;
  471 }
  472 
  473 /*---------------------------------------------------------------------------*
  474  *      number of units
  475  *---------------------------------------------------------------------------*/
  476 static void
  477 F_7(int val)
  478 {
  479         if(val != -1)
  480         {
  481                 NDBGL3(L3_A_MSG, "Number of Units = %d", val);
  482                 units = val;
  483                 state = ST_EXP_TOCI;
  484         }
  485 }
  486 
  487 /*---------------------------------------------------------------------------*
  488  *      subtotal/total
  489  *---------------------------------------------------------------------------*/
  490 static void
  491 F_8(int val)
  492 {
  493         if(val != -1)
  494         {
  495                 NDBGL3(L3_A_MSG, "Subtotal/Total = %d", val);
  496                 /* type_of_charge = val; */
  497                 state = ST_EXP_DBID;
  498         }
  499 }
  500 
  501 /*---------------------------------------------------------------------------*
  502  *      billing_id
  503  *---------------------------------------------------------------------------*/
  504 static void
  505 F_9(int val)
  506 {
  507         if(val != -1)
  508         {
  509                 NDBGL3(L3_A_MSG, "Billing ID = %d", val);
  510                 /* billing_id = val; */
  511                 state = ST_EXP_NIX;
  512         }
  513 }
  514 
  515 /*---------------------------------------------------------------------------*
  516  *
  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[] = {
  525 
  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            }
  543 };
  544 
  545 /*---------------------------------------------------------------------------*
  546  *      state decode for do_component
  547  *---------------------------------------------------------------------------*/
  548 static void
  549 next_state(int class, int form, int code, int val)
  550 {
  551         int i;
  552 
  553         for(i=0; ; i++)
  554         {
  555                 if((statetab[i].currstate > state) ||
  556                    (statetab[i].currstate == -1))
  557                 {
  558                         break;
  559                 }
  560 
  561                 if((statetab[i].currstate == state)     &&
  562                    (statetab[i].form == form)           &&
  563                    (statetab[i].class == class)         &&
  564                    (statetab[i].code == code))
  565                 {
  566                         (*statetab[i].func)(val);
  567                         break;
  568                 }
  569         }
  570 }
  571 
  572 #endif /* NI4BQ931 > 0 */

Cache object: 74a2b27e38ac9c3d1316d0789bd0e638


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.