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_l4mgmt.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 /*      $NetBSD: i4b_l4mgmt.c,v 1.14 2005/02/26 22:39:49 perry Exp $    */
    2 
    3 /*
    4  * Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved.
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  *
   15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   25  * SUCH DAMAGE.
   26  *
   27  *---------------------------------------------------------------------------
   28  *
   29  *      i4b_l4mgmt.c - layer 4 calldescriptor management utilites
   30  *      -----------------------------------------------------------
   31  *
   32  *      $Id: i4b_l4mgmt.c,v 1.14 2005/02/26 22:39:49 perry Exp $
   33  *
   34  * $FreeBSD$
   35  *
   36  *      last edit-date: [Fri Jan  5 11:33:47 2001]
   37  *
   38  *---------------------------------------------------------------------------*/
   39 
   40 #include <sys/cdefs.h>
   41 __KERNEL_RCSID(0, "$NetBSD: i4b_l4mgmt.c,v 1.14 2005/02/26 22:39:49 perry Exp $");
   42 
   43 #include "isdn.h"
   44 
   45 #if NISDN > 0
   46 
   47 #include <sys/param.h>
   48 #include <sys/kernel.h>
   49 #include <sys/systm.h>
   50 #include <sys/mbuf.h>
   51 #include <sys/socket.h>
   52 #include <net/if.h>
   53 
   54 #if defined(__NetBSD__) && __NetBSD_Version__ >= 104230000
   55 #include <sys/callout.h>
   56 #endif
   57 
   58 #if defined(__FreeBSD__)
   59 #if defined (__FreeBSD_version) && __FreeBSD_version <= 400000
   60 #include <machine/random.h>
   61 #else
   62 #include <sys/random.h>
   63 #endif
   64 #endif
   65 
   66 #ifdef __FreeBSD__
   67 #include <machine/i4b_debug.h>
   68 #include <machine/i4b_ioctl.h>
   69 #else
   70 #include <netisdn/i4b_debug.h>
   71 #include <netisdn/i4b_ioctl.h>
   72 #endif
   73 
   74 #include <netisdn/i4b_l3l4.h>
   75 #include <netisdn/i4b_mbuf.h>
   76 #include <netisdn/i4b_isdnq931.h>
   77 #include <netisdn/i4b_global.h>
   78 
   79 #include <netisdn/i4b_l2.h>
   80 #include <netisdn/i4b_l1l2.h>
   81 #include <netisdn/i4b_l4.h>
   82 
   83 static unsigned int get_cdid(void);
   84 
   85 static void i4b_init_callout(call_desc_t *);
   86 static void i4b_stop_callout(call_desc_t *cd);
   87 
   88 call_desc_t call_desc[N_CALL_DESC];     /* call descriptor array */
   89 int num_call_desc = 0;
   90 
   91 /*---------------------------------------------------------------------------*
   92  *      return a new unique call descriptor id
   93  *      --------------------------------------
   94  *      returns a new calldescriptor id which is used to uniquely identyfy
   95  *      a single call in the communication between kernel and userland.
   96  *      this cdid is then used to associate a calldescriptor with an id.
   97  *---------------------------------------------------------------------------*/
   98 static unsigned int
   99 get_cdid(void)
  100 {
  101         static unsigned int cdid_count = 0;
  102         int i;
  103         int x;
  104 
  105         x = splnet();
  106 
  107         /* get next id */
  108 
  109         cdid_count++;
  110 
  111 again:
  112         if(cdid_count == CDID_UNUSED)           /* zero is invalid */
  113                 cdid_count++;
  114         else if(cdid_count > CDID_MAX)          /* wraparound ? */
  115                 cdid_count = 1;
  116 
  117         /* check if id already in use */
  118 
  119         for(i=0; i < num_call_desc; i++)
  120         {
  121                 if(call_desc[i].cdid == cdid_count)
  122                 {
  123                         cdid_count++;
  124                         goto again;
  125                 }
  126         }
  127 
  128         splx(x);
  129 
  130         return(cdid_count);
  131 }
  132 
  133 /*---------------------------------------------------------------------------*
  134  *      reserve a calldescriptor for later usage
  135  *      ----------------------------------------
  136  *      searches the calldescriptor array until an unused
  137  *      descriptor is found, gets a new calldescriptor id
  138  *      and reserves it by putting the id into the cdid field.
  139  *      returns pointer to the calldescriptor.
  140  *---------------------------------------------------------------------------*/
  141 call_desc_t *
  142 reserve_cd(void)
  143 {
  144         call_desc_t *cd;
  145         int x;
  146         int i;
  147 
  148         x = splnet();
  149 
  150         cd = NULL;
  151 
  152         for(i=0; i < num_call_desc; i++)
  153         {
  154                 if(call_desc[i].cdid == CDID_UNUSED)
  155                 {
  156                         cd = &(call_desc[i]);   /* get pointer to descriptor */
  157                         NDBGL4(L4_MSG, "found free cd - index=%d cdid=%u",
  158                                  i, call_desc[i].cdid);
  159                         break;
  160                 }
  161         }
  162         if (cd == NULL && num_call_desc < N_CALL_DESC) {
  163                 i = num_call_desc++;
  164                 cd = &(call_desc[i]);   /* get pointer to descriptor */
  165                 NDBGL4(L4_MSG, "found free cd - index=%d cdid=%u",
  166                          i, call_desc[i].cdid);
  167         }
  168         if (cd != NULL) {
  169                 memset(cd, 0, sizeof(call_desc_t)); /* clear it */
  170                 cd->cdid = get_cdid();  /* fill in new cdid */
  171         }
  172 
  173         splx(x);
  174 
  175         if(cd == NULL)
  176                 panic("reserve_cd: no free call descriptor available!");
  177 
  178         i4b_init_callout(cd);
  179 
  180         return(cd);
  181 }
  182 
  183 /*---------------------------------------------------------------------------*
  184  *      free a calldescriptor
  185  *      ---------------------
  186  *      free a unused calldescriptor by giving address of calldescriptor
  187  *      and writing a 0 into the cdid field marking it as unused.
  188  *---------------------------------------------------------------------------*/
  189 void
  190 freecd_by_cd(call_desc_t *cd)
  191 {
  192         int i;
  193         int x = splnet();
  194 
  195         for(i=0; i < num_call_desc; i++)
  196         {
  197                 if( (call_desc[i].cdid != CDID_UNUSED) &&
  198                     (&(call_desc[i]) == cd) )
  199                 {
  200                         NDBGL4(L4_MSG, "releasing cd - index=%d cdid=%u cr=%d",
  201                                 i, call_desc[i].cdid, cd->cr);
  202                         call_desc[i].cdid = CDID_UNUSED;
  203                         break;
  204                 }
  205         }
  206 
  207         if(i == N_CALL_DESC)
  208                 panic("freecd_by_cd: ERROR, cd not found, cr = %d", cd->cr);
  209 
  210         splx(x);
  211 }
  212 
  213 /*
  214  * ISDN is gone, get rid of all CDs for it
  215  */
  216 void free_all_cd_of_isdnif(int isdnif)
  217 {
  218         int i;
  219         int x = splnet();
  220 
  221         for(i=0; i < num_call_desc; i++)
  222         {
  223                 if( (call_desc[i].cdid != CDID_UNUSED) &&
  224                     call_desc[i].isdnif == isdnif) {
  225                         NDBGL4(L4_MSG, "releasing cd - index=%d cdid=%u cr=%d",
  226                                 i, call_desc[i].cdid, call_desc[i].cr);
  227                         if (call_desc[i].callouts_inited)
  228                                 i4b_stop_callout(&call_desc[i]);
  229                         call_desc[i].cdid = CDID_UNUSED;
  230                         call_desc[i].isdnif = -1;
  231                         call_desc[i].l3drv = NULL;
  232                 }
  233         }
  234 
  235         splx(x);
  236 }
  237 
  238 /*---------------------------------------------------------------------------*
  239  *      return pointer to calldescriptor by giving the calldescriptor id
  240  *      ----------------------------------------------------------------
  241  *      lookup a calldescriptor in the calldescriptor array by looking
  242  *      at the cdid field. return pointer to calldescriptor if found,
  243  *      else return NULL if not found.
  244  *---------------------------------------------------------------------------*/
  245 call_desc_t *
  246 cd_by_cdid(unsigned int cdid)
  247 {
  248         int i;
  249 
  250         for(i=0; i < num_call_desc; i++)
  251         {
  252                 if(call_desc[i].cdid == cdid)
  253                 {
  254                         NDBGL4(L4_MSG, "found cdid - index=%d cdid=%u cr=%d",
  255                                         i, call_desc[i].cdid, call_desc[i].cr);
  256                         i4b_init_callout(&call_desc[i]);
  257                         return(&(call_desc[i]));
  258                 }
  259         }
  260         return(NULL);
  261 }
  262 
  263 /*---------------------------------------------------------------------------*
  264  *      search calldescriptor
  265  *      ---------------------
  266  *      This routine searches for the calldescriptor for a passive controller
  267  *      given by unit number, callreference and callreference flag.
  268  *      It returns a pointer to the calldescriptor if found, else a NULL.
  269  *---------------------------------------------------------------------------*/
  270 call_desc_t *
  271 cd_by_isdnifcr(int isdnif, int cr, int crf)
  272 {
  273         int i;
  274 
  275         for(i=0; i < num_call_desc; i++) {
  276                 if (call_desc[i].cdid != CDID_UNUSED
  277                     && call_desc[i].isdnif == isdnif
  278                     && call_desc[i].cr == cr
  279                     && call_desc[i].crflag == crf) {
  280                         NDBGL4(L4_MSG, "found cd, index=%d cdid=%u cr=%d",
  281                             i, call_desc[i].cdid, call_desc[i].cr);
  282                         i4b_init_callout(&call_desc[i]);
  283                         return(&(call_desc[i]));
  284                 }
  285         }
  286         return(NULL);
  287 }
  288 
  289 /*---------------------------------------------------------------------------*
  290  *      generate 7 bit "random" number used for outgoing Call Reference
  291  *---------------------------------------------------------------------------*/
  292 unsigned char
  293 get_rand_cr(int unit)
  294 {
  295         register int i, j;
  296         static u_char val, retval;
  297         static int called = 42;
  298 
  299         val += ++called;
  300 
  301         for(i=0; i < 50 ; i++, val++)
  302         {
  303                 int found = 1;
  304 
  305 #if defined(__FreeBSD__)
  306 
  307 #ifdef RANDOMDEV
  308                 read_random((char *)&val, sizeof(val));
  309 #else
  310                 val = (u_char)random();
  311 #endif /* RANDOMDEV */
  312 
  313 #else
  314                 val |= unit+i;
  315                 val <<= i;
  316                 val ^= (time.tv_sec >> 8) ^ time.tv_usec;
  317                 val <<= i;
  318                 val ^= time.tv_sec ^ (time.tv_usec >> 8);
  319 #endif
  320 
  321                 retval = val & 0x7f;
  322 
  323                 if(retval == 0 || retval == 0x7f)
  324                         continue;
  325 
  326                 for(j=0; j < num_call_desc; j++)
  327                 {
  328                         if( (call_desc[j].cdid != CDID_UNUSED) &&
  329                             (call_desc[j].cr == retval) )
  330                         {
  331                                 found = 0;
  332                                 break;
  333                         }
  334                 }
  335 
  336                 if(found)
  337                         return(retval);
  338         }
  339         return(0);      /* XXX */
  340 }
  341 
  342 static void
  343 i4b_stop_callout(call_desc_t *cd)
  344 {
  345         if (!cd->callouts_inited)
  346                 return;
  347 
  348         callout_stop(&cd->idle_timeout_handle);
  349         callout_stop(&cd->T303_callout);
  350         callout_stop(&cd->T305_callout);
  351         callout_stop(&cd->T308_callout);
  352         callout_stop(&cd->T309_callout);
  353         callout_stop(&cd->T310_callout);
  354         callout_stop(&cd->T313_callout);
  355         callout_stop(&cd->T400_callout);
  356 }
  357 
  358 /*---------------------------------------------------------------------------*
  359  *      initialize the callout handles for FreeBSD
  360  *---------------------------------------------------------------------------*/
  361 void
  362 i4b_init_callout(call_desc_t *cd)
  363 {
  364         if(cd->callouts_inited == 0)
  365         {
  366                 callout_init(&cd->idle_timeout_handle);
  367                 callout_init(&cd->T303_callout);
  368                 callout_init(&cd->T305_callout);
  369                 callout_init(&cd->T308_callout);
  370                 callout_init(&cd->T309_callout);
  371                 callout_init(&cd->T310_callout);
  372                 callout_init(&cd->T313_callout);
  373                 callout_init(&cd->T400_callout);
  374                 cd->callouts_inited = 1;
  375         }
  376 }
  377 
  378 #ifdef I4B_CD_DEBUG_PRINT
  379 
  380 extern char *print_l3state(call_desc_t *cd);
  381 
  382 void i4b_print_cdp(call_desc_t *cdp);
  383 void i4b_print_cdx(int index);
  384 void i4b_print_cda(void);
  385 void i4b_print_cdaa(void);
  386 
  387 /*---------------------------------------------------------------------------*
  388  *      print a call descriptor by cd-pointer
  389  *---------------------------------------------------------------------------*/
  390 void
  391 i4b_print_cdp(call_desc_t *cdp)
  392 {
  393         if((cdp > &(call_desc[num_call_desc])) || (cdp < &(call_desc[0])))
  394         {
  395                 printf("i4b_print_cd: cdp out of range!\n");
  396                 return;
  397         }
  398 
  399         printf("i4b_print_cd: printing call descriptor %d at 0x%lx:\n", cdp - (&(call_desc[0])), (unsigned long)cdp);
  400 
  401         printf("         cdid = %d\n", cdp->cdid);
  402         printf("   controller = %d (u=%d, dl=%d, b1=%d, b2=%d)\n",
  403                         cdp->controller,
  404                         ctrl_desc[cdp->controller].unit,
  405                         ctrl_desc[cdp->controller].dl_est,
  406                         ctrl_desc[cdp->controller].bch_state[CHAN_B1],
  407                         ctrl_desc[cdp->controller].bch_state[CHAN_B2]);
  408         printf("           cr = 0x%02x\n", cdp->cr);
  409         printf("       crflag = %d\n", cdp->crflag);
  410         printf("    channelid = %d\n", cdp->channelid);
  411         printf("        bprot = %d\n", cdp->bprot);
  412         printf("       driver = %d\n", cdp->driver);
  413         printf("  driver_unit = %d\n", cdp->driver_unit);
  414         printf("   call_state = %d\n", cdp->call_state);
  415         printf("    Q931state = %s\n", print_l3state(cdp));
  416         printf("        event = %d\n", cdp->event);
  417         printf("     response = %d\n", cdp->response);
  418         printf("         T303 = %d\n", cdp->T303);
  419         printf("T303_first_to = %d\n", cdp->T303_first_to);
  420         printf("         T305 = %d\n", cdp->T305);
  421         printf("         T308 = %d\n", cdp->T308);
  422         printf("T308_first_to = %d\n", cdp->T308_first_to);
  423         printf("         T309 = %d\n", cdp->T309);
  424         printf("         T310 = %d\n", cdp->T310);
  425         printf("         T313 = %d\n", cdp->T313);
  426         printf("         T400 = %d\n", cdp->T400);
  427         printf("          dir = %s\n", cdp->dir == DIR_OUTGOING ? "out" : "in");
  428 }
  429 
  430 /*---------------------------------------------------------------------------*
  431  *      print a call descriptor by index
  432  *---------------------------------------------------------------------------*/
  433 void
  434 i4b_print_cdx(int index)
  435 {
  436         if(index >= num_call_desc)
  437         {
  438                 printf("i4b_print_cdx: index %d >= N_CALL_DESC %d\n", index, N_CALL_DESC);
  439                 return;
  440         }
  441         i4b_print_cdp(&(call_desc[index]));
  442 }
  443 
  444 /*---------------------------------------------------------------------------*
  445  *      print all call descriptors
  446  *---------------------------------------------------------------------------*/
  447 void
  448 i4b_print_cda(void)
  449 {
  450         int i;
  451 
  452         for(i=0; i < num_call_desc; i++)
  453         {
  454                 i4b_print_cdp(&(call_desc[i]));
  455         }
  456 }
  457 
  458 /*---------------------------------------------------------------------------*
  459  *      print all active call descriptors
  460  *---------------------------------------------------------------------------*/
  461 void
  462 i4b_print_cdaa(void)
  463 {
  464         int i;
  465 
  466         for(i=0; i < num_call_desc; i++)
  467         {
  468                 if(call_desc[i].cdid != CDID_UNUSED)
  469                 {
  470                         i4b_print_cdp(&(call_desc[i]));
  471                 }
  472         }
  473 }
  474 
  475 #endif /* I4B_CD_DEBUG_PRINT */
  476 
  477 #endif /* NISDN > 0 */

Cache object: 7b9a58ed8f8c7c410e45848793fd3de1


[ 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.