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_l4.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_l4.c - kernel interface to userland
   28  *      -----------------------------------------
   29  *
   30  *      $Id: i4b_l4.c,v 1.26 2004/03/21 16:29:40 martin 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_l4.c,v 1.26 2004/03/21 16:29:40 martin Exp $");
   40 
   41 #include "isdn.h"
   42 #include "irip.h"
   43 
   44 #if NISDN > 0
   45 
   46 #include <sys/param.h>
   47 #include <sys/kernel.h>
   48 #include <sys/systm.h>
   49 #include <sys/conf.h>
   50 #include <sys/mbuf.h>
   51 #include <sys/proc.h>
   52 #include <sys/fcntl.h>
   53 #include <sys/socket.h>
   54 #include <net/if.h>
   55 
   56 #if defined(__NetBSD__) && __NetBSD_Version__ >= 104230000
   57 #include <sys/callout.h>
   58 #endif
   59 
   60 #ifdef __FreeBSD__
   61 #include <machine/i4b_debug.h>
   62 #include <machine/i4b_ioctl.h>
   63 #include <machine/i4b_cause.h>
   64 #else
   65 #include <netisdn/i4b_debug.h>
   66 #include <netisdn/i4b_ioctl.h>
   67 #include <netisdn/i4b_cause.h>
   68 #endif
   69 
   70 #include <netisdn/i4b_global.h>
   71 #include <netisdn/i4b_l3l4.h>
   72 #include <netisdn/i4b_mbuf.h>
   73 #include <netisdn/i4b_l2.h>
   74 #include <netisdn/i4b_l3.h>
   75 #include <netisdn/i4b_l4.h>
   76 
   77 unsigned int i4b_l4_debug = L4_DEBUG_DEFAULT;
   78 
   79 /*
   80  * ISDNs, in userland sometimes called "controllers", but one controller
   81  * may have multiple BRIs, for example daic QUAD cards attach four BRIs.
   82  * An ISDN may also be a PRI (30 B channels).
   83  */
   84 static SLIST_HEAD(, isdn_l3_driver) isdnif_list = SLIST_HEAD_INITIALIZER(isdnif_list);
   85 static int next_isdnif = 0;
   86 
   87 /*
   88  * Attach a new L3 driver instance and return its ISDN identifier
   89  */
   90 struct isdn_l3_driver *
   91 isdn_attach_isdnif(const char *devname, const char *cardname, 
   92     void *l1_token, const struct isdn_l3_driver_functions *l3driver, int nbch)
   93 {
   94         int s = splnet();
   95         int i, l, isdnif = next_isdnif++;
   96         struct isdn_l3_driver *new_ctrl;
   97 
   98         new_ctrl = malloc(sizeof(*new_ctrl), M_DEVBUF, 0);
   99         memset(new_ctrl, 0, sizeof *new_ctrl);
  100         SLIST_INSERT_HEAD(&isdnif_list, new_ctrl, l3drvq);
  101         l = strlen(devname);
  102         new_ctrl->devname = malloc(l + 1, M_DEVBUF, 0);
  103         strlcpy(new_ctrl->devname, devname, l + 1);
  104         l = strlen(cardname);
  105         new_ctrl->card_name = malloc(l + 1, M_DEVBUF, 0);
  106         strlcpy(new_ctrl->card_name, cardname, l + 1);
  107 
  108         new_ctrl->l3driver = l3driver;
  109         new_ctrl->l1_token = l1_token;
  110         new_ctrl->isdnif = isdnif;
  111         new_ctrl->tei = -1;
  112         new_ctrl->dl_est = DL_DOWN;
  113         new_ctrl->nbch = nbch;
  114 
  115         new_ctrl->bch_state = malloc(nbch * sizeof(int), M_DEVBUF, 0);
  116         for (i = 0; i < nbch; i++)
  117                 new_ctrl->bch_state[i] = BCH_ST_FREE;
  118 
  119         splx(s);
  120 
  121         return new_ctrl;
  122 }
  123 
  124 /*
  125  * Detach a L3 driver instance
  126  */
  127 int
  128 isdn_detach_isdnif(struct isdn_l3_driver *l3drv)
  129 {
  130         struct isdn_l3_driver *sc;
  131         int s = splnet();
  132         int isdnif = l3drv->isdnif;
  133         int max;
  134 
  135         i4b_l4_contr_ev_ind(isdnif, 0);
  136         SLIST_REMOVE(&isdnif_list, l3drv, isdn_l3_driver, l3drvq);
  137 
  138         max = -1;
  139         SLIST_FOREACH(sc, &isdnif_list, l3drvq)
  140                 if (sc->isdnif > max)
  141                         max = sc->isdnif;
  142         next_isdnif = max+1;
  143 
  144         free_all_cd_of_isdnif(isdnif);
  145 
  146         splx(s);
  147 
  148         free(l3drv, M_DEVBUF);
  149         printf("ISDN %d detached\n", isdnif);
  150         return 1;
  151 }
  152 
  153 struct isdn_l3_driver *
  154 isdn_find_l3_by_isdnif(int isdnif)
  155 {
  156         struct isdn_l3_driver *sc;
  157 
  158         SLIST_FOREACH(sc, &isdnif_list, l3drvq)
  159                 if (sc->isdnif == isdnif)
  160                         return sc;
  161         return NULL;
  162 }
  163 
  164 int isdn_count_isdnif(int *misdnif)
  165 {
  166         struct isdn_l3_driver *sc;
  167         int count = 0;
  168         int max_isdnif = -1;
  169 
  170         SLIST_FOREACH(sc, &isdnif_list, l3drvq) {
  171                 count++;
  172                 if (sc->isdnif > max_isdnif)
  173                         max_isdnif = sc->isdnif;
  174         }
  175 
  176         if (misdnif)
  177                 *misdnif = max_isdnif;
  178 
  179         return count;
  180 }
  181 
  182 void *
  183 isdn_find_softc_by_isdnif(int isdnif)
  184 {
  185         struct isdn_l3_driver *sc = isdn_find_l3_by_isdnif(isdnif);
  186         if (sc == NULL)
  187                 return NULL;
  188         /*
  189          * XXX - hack: do not return a softc for active cards.
  190          *       all callers of this expecting l2_softc* results
  191          *       should be fixed!
  192          */
  193         if (sc->l3driver->N_DOWNLOAD)
  194                 return NULL;
  195         return sc->l1_token;
  196 }
  197 
  198 /*---------------------------------------------------------------------------*
  199  *      daemon is attached
  200  *---------------------------------------------------------------------------*/
  201 void 
  202 i4b_l4_daemon_attached(void)
  203 {
  204         struct isdn_l3_driver *d;
  205 
  206         int x = splnet();
  207         SLIST_FOREACH(d, &isdnif_list, l3drvq)
  208         {
  209                 d->l3driver->N_MGMT_COMMAND(d, CMR_DOPEN, 0);
  210         }
  211         splx(x);
  212 }
  213 
  214 /*---------------------------------------------------------------------------*
  215  *      daemon is detached
  216  *---------------------------------------------------------------------------*/
  217 void 
  218 i4b_l4_daemon_detached(void)
  219 {
  220         struct isdn_l3_driver *d;
  221 
  222         int x = splnet();
  223         SLIST_FOREACH(d, &isdnif_list, l3drvq)
  224         {
  225                 d->l3driver->N_MGMT_COMMAND(d, CMR_DCLOSE, 0);
  226         }
  227         splx(x);
  228 }
  229 
  230 /*
  231  * B-channel layer 4 drivers and their registry.
  232  * (Application drivers connecting to a B-channel)
  233  */
  234 static int i4b_link_bchandrvr(call_desc_t *cd);
  235 static void i4b_unlink_bchandrvr(call_desc_t *cd);
  236 static void i4b_l4_setup_timeout(call_desc_t *cd);
  237 static void i4b_idle_check_fix_unit(call_desc_t *cd);
  238 static void i4b_idle_check_var_unit(call_desc_t *cd);
  239 static void i4b_l4_setup_timeout_fix_unit(call_desc_t *cd);
  240 static void i4b_l4_setup_timeout_var_unit(call_desc_t *cd);
  241 static time_t i4b_get_idletime(call_desc_t *cd);
  242 
  243 static int next_l4_driver_id = 0;
  244 
  245 struct l4_driver_desc {
  246         SLIST_ENTRY(l4_driver_desc) l4drvq;
  247         char name[L4DRIVER_NAME_SIZ];
  248         int driver_id;
  249         const struct isdn_l4_driver_functions *driver;
  250         int units;
  251 };
  252 static SLIST_HEAD(, l4_driver_desc) l4_driver_registry
  253     = SLIST_HEAD_INITIALIZER(l4_driver_registry);
  254 
  255 int isdn_l4_driver_attach(const char *name, int units, const struct isdn_l4_driver_functions *driver)
  256 {
  257         struct l4_driver_desc * new_driver;
  258 
  259         new_driver = malloc(sizeof(struct l4_driver_desc), M_DEVBUF, 0);
  260         memset(new_driver, 0, sizeof(struct l4_driver_desc));
  261         strncpy(new_driver->name, name, L4DRIVER_NAME_SIZ);
  262         new_driver->name[L4DRIVER_NAME_SIZ-1] = 0;
  263         new_driver->driver_id = next_l4_driver_id++;
  264         new_driver->driver = driver;
  265         new_driver->units = units;
  266         SLIST_INSERT_HEAD(&l4_driver_registry, new_driver, l4drvq);
  267         return new_driver->driver_id;
  268 }
  269 
  270 int isdn_l4_driver_detatch(const char *name)
  271 {
  272         /* XXX - not yet implemented */
  273         return 0;
  274 }
  275 
  276 const struct isdn_l4_driver_functions *isdn_l4_find_driver(const char *name, int unit)
  277 {
  278         struct l4_driver_desc * d;
  279         SLIST_FOREACH(d, &l4_driver_registry, l4drvq)
  280                 if (strcmp(d->name, name) == 0) {
  281                         return d->driver;
  282                 }
  283         return NULL;
  284 }
  285 
  286 int isdn_l4_find_driverid(const char *name)
  287 {
  288         struct l4_driver_desc * d;
  289         SLIST_FOREACH(d, &l4_driver_registry, l4drvq)
  290                 if (strcmp(d->name, name) == 0) {
  291                         return d->driver_id;
  292                 }
  293         return -1;
  294 }
  295 
  296 const struct isdn_l4_driver_functions *isdn_l4_get_driver(int driver_id, int unit)
  297 {
  298         struct l4_driver_desc * d;
  299         SLIST_FOREACH(d, &l4_driver_registry, l4drvq)
  300                 if (d->driver_id == driver_id) {
  301                         return d->driver;
  302                 }
  303         return NULL;
  304 }
  305 
  306 /*---------------------------------------------------------------------------*
  307  *      send MSG_PDEACT_IND message to userland
  308  *---------------------------------------------------------------------------*/
  309 void
  310 i4b_l4_pdeact(struct isdn_l3_driver *d, int numactive)
  311 {
  312         struct mbuf *m;
  313         int i;
  314         call_desc_t *cd;
  315         
  316         for(i=0; i < num_call_desc; i++)
  317         {
  318                 if(call_desc[i].cdid != CDID_UNUSED && call_desc[i].l3drv == d)
  319                 {
  320                         cd = &call_desc[i];
  321                         
  322                         if(cd->timeout_active)
  323                         {
  324                                 STOP_TIMER(cd->idle_timeout_handle, i4b_idle_check, cd);
  325                         }
  326                         
  327                         if (cd->l4_driver != NULL && cd->l4_driver_softc != NULL)
  328                         {
  329                                 (*cd->l4_driver->line_disconnected)(cd->l4_driver_softc, (void *)cd);
  330                                 i4b_unlink_bchandrvr(cd);
  331                         }
  332                 
  333                         if ((cd->channelid >= 0)
  334                              && (cd->channelid < d->nbch));
  335                                 d->bch_state[cd->channelid] = BCH_ST_FREE;
  336 
  337                         cd->cdid = CDID_UNUSED;
  338                 }
  339         }
  340         
  341         if((m = i4b_Dgetmbuf(sizeof(msg_pdeact_ind_t))) != NULL)
  342         {
  343                 msg_pdeact_ind_t *md = (msg_pdeact_ind_t *)m->m_data;
  344 
  345                 md->header.type = MSG_PDEACT_IND;
  346                 md->header.cdid = -1;
  347 
  348                 md->controller = d->isdnif;
  349                 md->numactive = numactive;
  350 
  351                 i4bputqueue_hipri(m);           /* URGENT !!! */
  352         }
  353 }
  354 
  355 /*---------------------------------------------------------------------------*
  356  *      send MSG_L12STAT_IND message to userland
  357  *---------------------------------------------------------------------------*/
  358 void
  359 i4b_l4_l12stat(struct isdn_l3_driver *d, int layer, int state)
  360 {
  361         struct mbuf *m;
  362 
  363         if((m = i4b_Dgetmbuf(sizeof(msg_l12stat_ind_t))) != NULL)
  364         {
  365                 msg_l12stat_ind_t *md = (msg_l12stat_ind_t *)m->m_data;
  366 
  367                 md->header.type = MSG_L12STAT_IND;
  368                 md->header.cdid = -1;
  369 
  370                 md->controller = d->isdnif;
  371                 md->layer = layer;
  372                 md->state = state;
  373 
  374                 i4bputqueue(m);
  375         }
  376 }
  377 
  378 /*---------------------------------------------------------------------------*
  379  *      send MSG_TEIASG_IND message to userland
  380  *---------------------------------------------------------------------------*/
  381 void
  382 i4b_l4_teiasg(struct isdn_l3_driver *d, int tei)
  383 {
  384         struct mbuf *m;
  385 
  386         if((m = i4b_Dgetmbuf(sizeof(msg_teiasg_ind_t))) != NULL)
  387         {
  388                 msg_teiasg_ind_t *md = (msg_teiasg_ind_t *)m->m_data;
  389 
  390                 md->header.type = MSG_TEIASG_IND;
  391                 md->header.cdid = -1;
  392 
  393                 md->controller = d->isdnif;
  394                 md->tei = d->tei;
  395 
  396                 i4bputqueue(m);
  397         }
  398 }
  399 
  400 /*---------------------------------------------------------------------------*
  401  *      send MSG_DIALOUT_IND message to userland
  402  *---------------------------------------------------------------------------*/
  403 void
  404 i4b_l4_dialout(int driver, int driver_unit)
  405 {
  406         struct mbuf *m;
  407 
  408         if((m = i4b_Dgetmbuf(sizeof(msg_dialout_ind_t))) != NULL)
  409         {
  410                 msg_dialout_ind_t *md = (msg_dialout_ind_t *)m->m_data;
  411 
  412                 md->header.type = MSG_DIALOUT_IND;
  413                 md->header.cdid = -1;
  414 
  415                 md->driver = driver;
  416                 md->driver_unit = driver_unit;  
  417 
  418                 i4bputqueue(m);
  419         }
  420 }
  421 
  422 /*---------------------------------------------------------------------------*
  423  *      send MSG_DIALOUTNUMBER_IND message to userland
  424  *---------------------------------------------------------------------------*/
  425 void
  426 i4b_l4_dialoutnumber(int driver, int driver_unit, int cmdlen, char *cmd)
  427 {
  428         struct mbuf *m;
  429 
  430         if((m = i4b_Dgetmbuf(sizeof(msg_dialoutnumber_ind_t))) != NULL)
  431         {
  432                 msg_dialoutnumber_ind_t *md = (msg_dialoutnumber_ind_t *)m->m_data;
  433 
  434                 md->header.type = MSG_DIALOUTNUMBER_IND;
  435                 md->header.cdid = -1;
  436 
  437                 md->driver = driver;
  438                 md->driver_unit = driver_unit;
  439 
  440                 if(cmdlen > TELNO_MAX)
  441                         cmdlen = TELNO_MAX;
  442 
  443                 md->cmdlen = cmdlen;
  444                 memcpy(md->cmd, cmd, cmdlen);
  445                 i4bputqueue(m);
  446         }
  447 }
  448 
  449 /*---------------------------------------------------------------------------*
  450  *      send MSG_NEGOTIATION_COMPL message to userland
  451  *---------------------------------------------------------------------------*/
  452 void
  453 i4b_l4_negcomplete(call_desc_t *cd)
  454 {
  455         struct mbuf *m;
  456 
  457         if((m = i4b_Dgetmbuf(sizeof(msg_negcomplete_ind_t))) != NULL)
  458         {
  459                 msg_negcomplete_ind_t *md = (msg_negcomplete_ind_t *)m->m_data;
  460 
  461                 md->header.type = MSG_NEGCOMP_IND;
  462                 md->header.cdid = cd->cdid;
  463 
  464                 i4bputqueue(m);
  465         }
  466 }
  467 
  468 /*---------------------------------------------------------------------------*
  469  *      send MSG_IFSTATE_CHANGED_IND message to userland
  470  *---------------------------------------------------------------------------*/
  471 void
  472 i4b_l4_ifstate_changed(call_desc_t *cd, int new_state)
  473 {
  474         struct mbuf *m;
  475 
  476         if((m = i4b_Dgetmbuf(sizeof(msg_ifstatechg_ind_t))) != NULL)
  477         {
  478                 msg_ifstatechg_ind_t *md = (msg_ifstatechg_ind_t *)m->m_data;
  479 
  480                 md->header.type = MSG_IFSTATE_CHANGED_IND;
  481                 md->header.cdid = cd->cdid;
  482                 md->state = new_state;
  483 
  484                 i4bputqueue(m);
  485         }
  486 }
  487 
  488 /*---------------------------------------------------------------------------*
  489  *      send MSG_DRVRDISC_REQ message to userland
  490  *---------------------------------------------------------------------------*/
  491 void
  492 i4b_l4_drvrdisc(int cdid)
  493 {
  494         struct mbuf *m;
  495 
  496         if((m = i4b_Dgetmbuf(sizeof(msg_drvrdisc_req_t))) != NULL)
  497         {
  498                 msg_drvrdisc_req_t *md = (msg_drvrdisc_req_t *)m->m_data;
  499 
  500                 md->header.type = MSG_DRVRDISC_REQ;
  501                 md->header.cdid = cdid;
  502 
  503                 i4bputqueue(m);
  504         }
  505 }
  506 
  507 /*---------------------------------------------------------------------------*
  508  *      send MSG_ACCT_IND message to userland
  509  *---------------------------------------------------------------------------*/
  510 void
  511 i4b_l4_accounting(int cdid, int accttype, int ioutbytes,
  512                 int iinbytes, int ro, int ri, int outbytes, int inbytes)
  513 {
  514         struct mbuf *m;
  515 
  516         if((m = i4b_Dgetmbuf(sizeof(msg_accounting_ind_t))) != NULL)
  517         {
  518                 msg_accounting_ind_t *md = (msg_accounting_ind_t *)m->m_data;
  519 
  520                 md->header.type = MSG_ACCT_IND;
  521                 md->header.cdid = cdid;
  522 
  523                 md->accttype = accttype;
  524                 md->ioutbytes = ioutbytes;
  525                 md->iinbytes = iinbytes;
  526                 md->outbps = ro;
  527                 md->inbps = ri;
  528                 md->outbytes = outbytes;
  529                 md->inbytes = inbytes;
  530                 
  531                 i4bputqueue(m);
  532         }
  533 }
  534 
  535 /*---------------------------------------------------------------------------*
  536  *      send MSG_CONNECT_IND message to userland
  537  *---------------------------------------------------------------------------*/
  538 void
  539 i4b_l4_connect_ind(call_desc_t *cd)
  540 {
  541         struct mbuf *m;
  542 
  543         if((m = i4b_Dgetmbuf(sizeof(msg_connect_ind_t))) != NULL)
  544         {
  545                 msg_connect_ind_t *mp = (msg_connect_ind_t *)m->m_data;
  546 
  547                 mp->header.type = MSG_CONNECT_IND;
  548                 mp->header.cdid = cd->cdid;
  549 
  550                 mp->controller = cd->isdnif;
  551                 mp->channel = cd->channelid;
  552                 mp->bprot = cd->bprot;
  553 
  554                 cd->dir = DIR_INCOMING;
  555 
  556                 if(strlen(cd->dst_telno) > 0)
  557                         strlcpy(mp->dst_telno, cd->dst_telno,
  558                             sizeof(mp->dst_telno));
  559                 else
  560                         strlcpy(mp->dst_telno, TELNO_EMPTY,
  561                             sizeof(mp->dst_telno));
  562 
  563                 if(strlen(cd->src_telno) > 0)
  564                         strlcpy(mp->src_telno, cd->src_telno,
  565                             sizeof(mp->src_telno));
  566                 else
  567                         strlcpy(mp->src_telno, TELNO_EMPTY,
  568                             sizeof(mp->src_telno));
  569                 mp->type_plan = cd->type_plan;
  570                 memcpy(mp->src_subaddr, cd->src_subaddr, sizeof(mp->src_subaddr));
  571                 memcpy(mp->dest_subaddr, cd->dest_subaddr, sizeof(mp->dest_subaddr));
  572                         
  573                 strlcpy(mp->display, cd->display, sizeof(mp->src_telno));
  574 
  575                 mp->scr_ind = cd->scr_ind;
  576                 mp->prs_ind = cd->prs_ind;              
  577                 
  578                 T400_start(cd);
  579                 
  580                 i4bputqueue(m);
  581         }
  582 }
  583 
  584 /*---------------------------------------------------------------------------*
  585  *      send MSG_CONNECT_ACTIVE_IND message to userland
  586  *---------------------------------------------------------------------------*/
  587 void
  588 i4b_l4_connect_active_ind(call_desc_t *cd)
  589 {
  590         int s;
  591         struct mbuf *m;
  592 
  593         s = splnet();
  594 
  595         cd->last_active_time = cd->connect_time = SECOND;
  596 
  597         NDBGL4(L4_TIMO, "last_active/connect_time=%ld", (long)cd->connect_time);
  598         
  599         i4b_link_bchandrvr(cd);
  600 
  601         update_controller_leds(cd->l3drv);
  602 
  603         if (cd->l4_driver != NULL && cd->l4_driver_softc != NULL)
  604                 (*cd->l4_driver->line_connected)(cd->l4_driver_softc, cd);
  605 
  606         i4b_l4_setup_timeout(cd);
  607         
  608         splx(s);        
  609         
  610         if((m = i4b_Dgetmbuf(sizeof(msg_connect_active_ind_t))) != NULL)
  611         {
  612                 msg_connect_active_ind_t *mp = (msg_connect_active_ind_t *)m->m_data;
  613 
  614                 mp->header.type = MSG_CONNECT_ACTIVE_IND;
  615                 mp->header.cdid = cd->cdid;
  616                 mp->controller = cd->isdnif;
  617                 mp->channel = cd->channelid;
  618                 if(cd->datetime[0] != '\0')
  619                         strlcpy(mp->datetime, cd->datetime,
  620                             sizeof(mp->datetime));
  621                 else
  622                         mp->datetime[0] = '\0';
  623                 i4bputqueue(m);
  624         }
  625 }
  626 
  627 /*---------------------------------------------------------------------------*
  628  *      send MSG_DISCONNECT_IND message to userland
  629  *---------------------------------------------------------------------------*/
  630 void
  631 i4b_l4_disconnect_ind(call_desc_t *cd)
  632 {
  633         struct isdn_l3_driver *d;
  634         struct mbuf *m;
  635 
  636         if(cd->timeout_active)
  637                 STOP_TIMER(cd->idle_timeout_handle, i4b_idle_check, cd);
  638 
  639         if (cd->l4_driver != NULL && cd->l4_driver_softc != NULL)
  640         {
  641                 (*cd->l4_driver->line_disconnected)(cd->l4_driver_softc, (void *)cd);
  642                 i4b_unlink_bchandrvr(cd);
  643         }
  644 
  645         d = cd->l3drv;
  646 
  647         if((cd->channelid >= 0) && (cd->channelid < d->nbch))
  648         {
  649                 d->bch_state[cd->channelid] = BCH_ST_FREE;
  650                 /*
  651                  * XXX: don't call l2 function for active cards.
  652                  */
  653                 if (d->l3driver->N_DOWNLOAD == NULL)
  654                         i4b_l2_channel_set_state(d, cd->channelid, BCH_ST_FREE);
  655         }
  656         else
  657         {
  658                 /* no error, might be hunting call for callback */
  659                 NDBGL4(L4_MSG, "invalid channel %d for ISDN!", cd->channelid);
  660         }
  661         update_controller_leds(d);
  662         
  663         if((m = i4b_Dgetmbuf(sizeof(msg_disconnect_ind_t))) != NULL)
  664         {
  665                 msg_disconnect_ind_t *mp = (msg_disconnect_ind_t *)m->m_data;
  666 
  667                 mp->header.type = MSG_DISCONNECT_IND;
  668                 mp->header.cdid = cd->cdid;
  669                 mp->cause = cd->cause_in;
  670 
  671                 i4bputqueue(m);
  672         }
  673 }
  674 
  675 /*---------------------------------------------------------------------------*
  676  *      send MSG_IDLE_TIMEOUT_IND message to userland
  677  *---------------------------------------------------------------------------*/
  678 void
  679 i4b_l4_idle_timeout_ind(call_desc_t *cd)
  680 {
  681         struct mbuf *m;
  682 
  683         if((m = i4b_Dgetmbuf(sizeof(msg_idle_timeout_ind_t))) != NULL)
  684         {
  685                 msg_idle_timeout_ind_t *mp = (msg_idle_timeout_ind_t *)m->m_data;
  686 
  687                 mp->header.type = MSG_IDLE_TIMEOUT_IND;
  688                 mp->header.cdid = cd->cdid;
  689 
  690                 i4bputqueue(m);
  691         }
  692 }
  693 
  694 /*---------------------------------------------------------------------------*
  695  *      send MSG_CHARGING_IND message to userland
  696  *---------------------------------------------------------------------------*/
  697 void
  698 i4b_l4_charging_ind(call_desc_t *cd)
  699 {
  700         struct mbuf *m;
  701 
  702         if((m = i4b_Dgetmbuf(sizeof(msg_charging_ind_t))) != NULL)
  703         {
  704                 msg_charging_ind_t *mp = (msg_charging_ind_t *)m->m_data;
  705 
  706                 mp->header.type = MSG_CHARGING_IND;
  707                 mp->header.cdid = cd->cdid;
  708                 mp->units_type = cd->units_type;
  709 
  710 /*XXX*/         if(mp->units_type == CHARGE_CALC)
  711                         mp->units = cd->cunits;
  712                 else
  713                         mp->units = cd->units;
  714 
  715                 i4bputqueue(m);
  716         }
  717 }
  718 
  719 /*---------------------------------------------------------------------------*
  720  *      send MSG_STATUS_IND message to userland
  721  *---------------------------------------------------------------------------*/
  722 void
  723 i4b_l4_status_ind(call_desc_t *cd)
  724 {
  725 }
  726 
  727 /*---------------------------------------------------------------------------*
  728  *      send MSG_ALERT_IND message to userland
  729  *---------------------------------------------------------------------------*/
  730 void
  731 i4b_l4_alert_ind(call_desc_t *cd)
  732 {
  733         struct mbuf *m;
  734 
  735         if((m = i4b_Dgetmbuf(sizeof(msg_alert_ind_t))) != NULL)
  736         {
  737                 msg_alert_ind_t *mp = (msg_alert_ind_t *)m->m_data;
  738 
  739                 mp->header.type = MSG_ALERT_IND;
  740                 mp->header.cdid = cd->cdid;
  741 
  742                 i4bputqueue(m);
  743         }
  744 }
  745 
  746 /*---------------------------------------------------------------------------*
  747  *      send MSG_INFO_IND message to userland
  748  *---------------------------------------------------------------------------*/
  749 void
  750 i4b_l4_info_ind(call_desc_t *cd)
  751 {
  752 }
  753 
  754 /*---------------------------------------------------------------------------*
  755  *      send MSG_INFO_IND message to userland
  756  *---------------------------------------------------------------------------*/
  757 void
  758 i4b_l4_proceeding_ind(call_desc_t *cd)
  759 {
  760         struct mbuf *m;
  761 
  762         if((m = i4b_Dgetmbuf(sizeof(msg_proceeding_ind_t))) != NULL)
  763         {
  764                 msg_proceeding_ind_t *mp = (msg_proceeding_ind_t *)m->m_data;
  765 
  766                 mp->header.type = MSG_PROCEEDING_IND;
  767                 mp->header.cdid = cd->cdid;
  768                 mp->controller = cd->isdnif;
  769                 mp->channel = cd->channelid;
  770                 i4bputqueue(m);
  771         }
  772 }
  773 
  774 /*---------------------------------------------------------------------------*
  775  *    send MSG_PACKET_IND message to userland
  776  *---------------------------------------------------------------------------*/
  777 void
  778 i4b_l4_packet_ind(int driver, int driver_unit, int dir, struct mbuf *pkt)
  779 {
  780         struct mbuf *m;
  781         int len = pkt->m_pkthdr.len;
  782         unsigned char *ip = pkt->m_data;
  783 
  784         if((m = i4b_Dgetmbuf(sizeof(msg_packet_ind_t))) != NULL)
  785         {
  786                 msg_packet_ind_t *mp = (msg_packet_ind_t *)m->m_data;
  787 
  788                 mp->header.type = MSG_PACKET_IND;
  789                 mp->header.cdid = -1;
  790                 mp->driver = driver;
  791                 mp->driver_unit = driver_unit;
  792                 mp->direction = dir;
  793                 memcpy(mp->pktdata, ip,
  794                         len <MAX_PACKET_LOG ? len : MAX_PACKET_LOG);
  795                 i4bputqueue(m);
  796         }
  797 }
  798 
  799 /*---------------------------------------------------------------------------*
  800  *    send MSG_CONTR_EV_IND message to userland
  801  *---------------------------------------------------------------------------*/
  802 void
  803 i4b_l4_contr_ev_ind(int controller, int attach)
  804 {
  805         struct mbuf *m;
  806 
  807         if((m = i4b_Dgetmbuf(sizeof(msg_ctrl_ev_ind_t))) != NULL)
  808         {
  809                 msg_ctrl_ev_ind_t *ev = (msg_ctrl_ev_ind_t *)m->m_data;
  810 
  811                 ev->header.type = MSG_CONTR_EV_IND;
  812                 ev->header.cdid = -1;
  813                 ev->controller = controller;
  814                 ev->event = attach;
  815                 i4bputqueue(m);
  816         }
  817 }
  818 
  819 /*---------------------------------------------------------------------------*
  820  *      link a driver(unit) to a B-channel(controller,unit,channel)
  821  *---------------------------------------------------------------------------*/
  822 static int
  823 i4b_link_bchandrvr(call_desc_t *cd)
  824 {
  825         struct isdn_l3_driver *d = cd->l3drv;
  826         
  827         if (d == NULL || d->l3driver == NULL || d->l3driver->get_linktab == NULL)
  828         {
  829                         cd->ilt = NULL;
  830                         return 1;
  831         }
  832 
  833         cd->ilt = d->l3driver->get_linktab(d->l1_token,
  834             cd->channelid);
  835 
  836         cd->l4_driver = isdn_l4_get_driver(cd->bchan_driver_index, cd->bchan_driver_unit);
  837         if (cd->l4_driver != NULL)
  838                 cd->l4_driver_softc = cd->l4_driver->get_softc(cd->bchan_driver_unit);
  839         else
  840                 cd->l4_driver_softc = NULL;
  841 
  842         if(cd->l4_driver == NULL || cd->l4_driver_softc == NULL || cd->ilt == NULL)
  843                 return(-1);
  844 
  845         if (d->l3driver->set_l4_driver != NULL)
  846         {
  847                 d->l3driver->set_l4_driver(d->l1_token,
  848                     cd->channelid, cd->l4_driver, cd->l4_driver_softc);
  849         }
  850 
  851         cd->l4_driver->set_linktab(cd->l4_driver_softc, cd->ilt);
  852 
  853         /* activate B channel */
  854                 
  855         (*cd->ilt->bchannel_driver->bch_config)(cd->ilt->l1token, cd->ilt->channel, cd->bprot, 1);
  856 
  857         return(0);
  858 }
  859 
  860 /*---------------------------------------------------------------------------*
  861  *      unlink a driver(unit) from a B-channel(controller,unit,channel)
  862  *---------------------------------------------------------------------------*/
  863 static void
  864 i4b_unlink_bchandrvr(call_desc_t *cd)
  865 {
  866         struct isdn_l3_driver *d = cd->l3drv;
  867 
  868         /*
  869          * XXX - what's this *cd manipulation for? Shouldn't we
  870          * close the bchannel driver first and then just set ilt to NULL
  871          * in *cd?
  872          */
  873         if (d == NULL || d->l3driver == NULL || d->l3driver->get_linktab == NULL)
  874         {
  875                 cd->ilt = NULL;
  876                 return;
  877         }
  878         else
  879         {
  880                 cd->ilt = d->l3driver->get_linktab(
  881                     d->l1_token, cd->channelid);
  882         }
  883         
  884         /* deactivate B channel */
  885                 
  886         (*cd->ilt->bchannel_driver->bch_config)(cd->ilt->l1token, cd->ilt->channel, cd->bprot, 0);
  887 } 
  888 
  889 /*---------------------------------------------------------------------------
  890 
  891         How shorthold mode works for OUTGOING connections
  892         =================================================
  893 
  894         |<---- unchecked-window ------->|<-checkwindow->|<-safetywindow>|
  895 
  896 idletime_state:      IST_NONCHK             IST_CHECK       IST_SAFE    
  897         
  898         |                               |               |               |
  899   time>>+-------------------------------+---------------+---------------+-...
  900         |                               |               |               |
  901         |                               |<--idle_time-->|<--earlyhup--->|
  902         |<-----------------------unitlen------------------------------->|
  903 
  904         
  905           unitlen - specifies the time a charging unit lasts
  906         idle_time - specifies the thime the line must be idle at the
  907                     end of the unit to be elected for hangup
  908          earlyhup - is the beginning of a timing safety zone before the
  909                     next charging unit starts
  910 
  911         The algorithm works as follows: lets assume the unitlen is 100
  912         secons, idle_time is 40 seconds and earlyhup is 10 seconds.
  913         The line then must be idle 50 seconds after the begin of the
  914         current unit and it must then be quiet for 40 seconds. if it
  915         has been quiet for this 40 seconds, the line is closed 10
  916         seconds before the next charging unit starts. In case there was
  917         any traffic within the idle_time, the line is not closed.
  918         It does not matter whether there was any traffic between second
  919         0 and second 50 or not.
  920 
  921 
  922         How shorthold mode works for INCOMING connections
  923         =================================================
  924 
  925         it is just possible to specify a maximum idle time for incoming
  926         connections, after this time of no activity on the line the line
  927         is closed.
  928         
  929 ---------------------------------------------------------------------------*/   
  930 
  931 static time_t
  932 i4b_get_idletime(call_desc_t *cd)
  933 {
  934         if (cd->l4_driver != NULL && cd->l4_driver_softc != NULL
  935             && cd->l4_driver->get_idletime)
  936                 return cd->l4_driver->get_idletime(cd->l4_driver_softc);
  937         return cd->last_active_time;
  938 }
  939 
  940 /*---------------------------------------------------------------------------*
  941  *      B channel idle check timeout setup
  942  *---------------------------------------------------------------------------*/ 
  943 static void
  944 i4b_l4_setup_timeout(call_desc_t *cd)
  945 {
  946         NDBGL4(L4_TIMO, "%ld: direction %d, shorthold algorithm %d",
  947                 (long)SECOND, cd->dir, cd->shorthold_data.shorthold_algorithm);
  948         
  949         cd->timeout_active = 0;
  950         cd->idletime_state = IST_IDLE;
  951         
  952         if((cd->dir == DIR_INCOMING) && (cd->max_idle_time > 0))
  953         {
  954                 /* incoming call: simple max idletime check */
  955         
  956                 START_TIMER(cd->idle_timeout_handle, i4b_idle_check, cd, hz/2);
  957                 cd->timeout_active = 1;
  958                 NDBGL4(L4_TIMO, "%ld: incoming-call, setup max_idle_time to %ld", (long)SECOND, (long)cd->max_idle_time);
  959         }
  960         else if((cd->dir == DIR_OUTGOING) && (cd->shorthold_data.idle_time > 0))
  961         {
  962                 switch( cd->shorthold_data.shorthold_algorithm )
  963                 {
  964                         default:        /* fall into the old fix algorithm */
  965                         case SHA_FIXU:
  966                                 i4b_l4_setup_timeout_fix_unit( cd );
  967                                 break;
  968                                 
  969                         case SHA_VARU:
  970                                 i4b_l4_setup_timeout_var_unit( cd );
  971                                 break;
  972                 }
  973         }
  974         else
  975         {
  976                 NDBGL4(L4_TIMO, "no idle_timeout configured");
  977         }
  978 }
  979 
  980 /*---------------------------------------------------------------------------*
  981  *      fixed unit algorithm B channel idle check timeout setup
  982  *---------------------------------------------------------------------------*/
  983 static void
  984 i4b_l4_setup_timeout_fix_unit(call_desc_t *cd)
  985 {
  986         /* outgoing call */
  987         
  988         if((cd->shorthold_data.idle_time > 0) && (cd->shorthold_data.unitlen_time == 0))
  989         {
  990                 /* outgoing call: simple max idletime check */
  991                 
  992                 START_TIMER(cd->idle_timeout_handle, i4b_idle_check, cd, hz/2);
  993                 cd->timeout_active = 1;
  994                 NDBGL4(L4_TIMO, "%ld: outgoing-call, setup idle_time to %ld",
  995                         (long)SECOND, (long)cd->shorthold_data.idle_time);
  996         }
  997         else if((cd->shorthold_data.unitlen_time > 0) && (cd->shorthold_data.unitlen_time > (cd->shorthold_data.idle_time + cd->shorthold_data.earlyhup_time)))
  998         {
  999                 /* outgoing call: full shorthold mode check */
 1000                 
 1001                 START_TIMER(cd->idle_timeout_handle, i4b_idle_check, cd, hz*(cd->shorthold_data.unitlen_time - (cd->shorthold_data.idle_time + cd->shorthold_data.earlyhup_time)));
 1002                 cd->timeout_active = 1;
 1003                 cd->idletime_state = IST_NONCHK;
 1004                 NDBGL4(L4_TIMO, "%ld: outgoing-call, start %ld sec nocheck window", 
 1005                         (long)SECOND, (long)(cd->shorthold_data.unitlen_time - (cd->shorthold_data.idle_time + cd->shorthold_data.earlyhup_time)));
 1006 
 1007                 if(cd->aocd_flag == 0)
 1008                 {
 1009                         cd->units_type = CHARGE_CALC;
 1010                         cd->cunits++;
 1011                         i4b_l4_charging_ind(cd);
 1012                 }
 1013         }
 1014         else
 1015         {
 1016                 /* parms somehow got wrong .. */
 1017                 
 1018                 NDBGL4(L4_ERR, "%ld: ERROR: idletime[%ld]+earlyhup[%ld] > unitlength[%ld]!",
 1019                         (long)SECOND, (long)cd->shorthold_data.idle_time, (long)cd->shorthold_data.earlyhup_time, (long)cd->shorthold_data.unitlen_time);
 1020         }
 1021 }
 1022 
 1023 /*---------------------------------------------------------------------------*
 1024  *      variable unit algorithm B channel idle check timeout setup
 1025  *---------------------------------------------------------------------------*/
 1026 static void
 1027 i4b_l4_setup_timeout_var_unit(call_desc_t *cd)
 1028 {
 1029         /* outgoing call: variable unit idletime check */
 1030                 
 1031         /*
 1032          * start checking for an idle connect one second before the end of the unit.
 1033          * The one second takes into account of rounding due to the driver only
 1034          * using the seconds and not the uSeconds of the current time
 1035          */
 1036         cd->idletime_state = IST_CHECK; /* move directly to the checking state */
 1037 
 1038         START_TIMER(cd->idle_timeout_handle, i4b_idle_check, cd, hz * (cd->shorthold_data.unitlen_time - 1) );
 1039         cd->timeout_active = 1;
 1040         NDBGL4(L4_TIMO, "%ld: outgoing-call, var idle time - setup to %ld",
 1041                 (long)SECOND, (long)cd->shorthold_data.unitlen_time);
 1042 }
 1043 
 1044 
 1045 /*---------------------------------------------------------------------------*
 1046  *      B channel idle check timeout function
 1047  *---------------------------------------------------------------------------*/ 
 1048 void
 1049 i4b_idle_check(call_desc_t *cd)
 1050 {
 1051         int s;
 1052 
 1053         if(cd->cdid == CDID_UNUSED)
 1054                 return;
 1055         
 1056         s = splnet();
 1057 
 1058         /* failsafe */
 1059 
 1060         if(cd->timeout_active == 0)
 1061         {
 1062                 NDBGL4(L4_ERR, "ERROR: timeout_active == 0 !!!");
 1063         }
 1064         else
 1065         {       
 1066                 cd->timeout_active = 0;
 1067         }
 1068         
 1069         /* incoming connections, simple idletime check */
 1070 
 1071         if(cd->dir == DIR_INCOMING)
 1072         {
 1073                 if((i4b_get_idletime(cd) + cd->max_idle_time) <= SECOND)
 1074                 {
 1075                         struct isdn_l3_driver *d = cd->l3drv;
 1076                         NDBGL4(L4_TIMO, "%ld: incoming-call, line idle timeout, disconnecting!", (long)SECOND);
 1077                         d->l3driver->N_DISCONNECT_REQUEST(cd,
 1078                                         (CAUSET_I4B << 8) | CAUSE_I4B_NORMAL);
 1079                         i4b_l4_idle_timeout_ind(cd);
 1080                 }
 1081                 else
 1082                 {
 1083                         NDBGL4(L4_TIMO, "%ld: incoming-call, activity, last_active=%ld, max_idle=%ld", (long)SECOND, (long)i4b_get_idletime(cd), (long)cd->max_idle_time);
 1084 
 1085                         START_TIMER(cd->idle_timeout_handle, i4b_idle_check, cd, hz/2);
 1086                         cd->timeout_active = 1;
 1087                 }
 1088         }
 1089 
 1090         /* outgoing connections */
 1091 
 1092         else if(cd->dir == DIR_OUTGOING)
 1093         {
 1094                 switch( cd->shorthold_data.shorthold_algorithm )
 1095                 {
 1096                         case SHA_FIXU:
 1097                                 i4b_idle_check_fix_unit( cd );
 1098                                 break;
 1099                         case SHA_VARU:
 1100                                 i4b_idle_check_var_unit( cd );
 1101                                 break;
 1102                         default:
 1103                                 NDBGL4(L4_TIMO, "%ld: bad value for shorthold_algorithm of %d",
 1104                                         (long)SECOND, cd->shorthold_data.shorthold_algorithm);
 1105                                 i4b_idle_check_fix_unit( cd );
 1106                                 break;
 1107                 }
 1108         }
 1109         splx(s);
 1110 }
 1111 
 1112 /*---------------------------------------------------------------------------*
 1113  *      fixed unit algorithm B channel idle check timeout function
 1114  *---------------------------------------------------------------------------*/
 1115 static void
 1116 i4b_idle_check_fix_unit(call_desc_t *cd)
 1117 {
 1118         struct isdn_l3_driver *d = cd->l3drv;
 1119 
 1120         /* simple idletime calculation */
 1121 
 1122         if((cd->shorthold_data.idle_time > 0) && (cd->shorthold_data.unitlen_time == 0))
 1123         {
 1124                 if((i4b_get_idletime(cd) + cd->shorthold_data.idle_time) <= SECOND)
 1125                 {
 1126                         NDBGL4(L4_TIMO, "%ld: outgoing-call-st, idle timeout, disconnecting!", (long)SECOND);
 1127                         d->l3driver->N_DISCONNECT_REQUEST(cd, (CAUSET_I4B << 8) | CAUSE_I4B_NORMAL);
 1128                         i4b_l4_idle_timeout_ind(cd);
 1129                 }
 1130                 else
 1131                 {
 1132                         NDBGL4(L4_TIMO, "%ld: outgoing-call-st, activity, last_active=%ld, max_idle=%ld",
 1133                                         (long)SECOND, (long)i4b_get_idletime(cd), (long)cd->shorthold_data.idle_time);
 1134                         START_TIMER(cd->idle_timeout_handle, i4b_idle_check, cd, hz/2);
 1135                         cd->timeout_active = 1;
 1136                 }
 1137         }
 1138 
 1139         /* full shorthold mode calculation */
 1140 
 1141         else if((cd->shorthold_data.unitlen_time > 0)
 1142                  && (cd->shorthold_data.unitlen_time > (cd->shorthold_data.idle_time + cd->shorthold_data.earlyhup_time)))
 1143         {
 1144                 switch(cd->idletime_state)
 1145                 {
 1146 
 1147                 case IST_NONCHK:        /* end of non-check time */
 1148 
 1149                         START_TIMER(cd->idle_timeout_handle, i4b_idle_check, cd, hz*(cd->shorthold_data.idle_time));
 1150                         cd->idletimechk_start = SECOND;
 1151                         cd->idletime_state = IST_CHECK;
 1152                         cd->timeout_active = 1;
 1153                         NDBGL4(L4_TIMO, "%ld: outgoing-call, idletime check window reached!", (long)SECOND);
 1154                         break;
 1155 
 1156                 case IST_CHECK:         /* end of idletime chk */
 1157                         if((i4b_get_idletime(cd) > cd->idletimechk_start) &&
 1158                            (i4b_get_idletime(cd) <= SECOND))
 1159                         {       /* activity detected */
 1160                                 START_TIMER(cd->idle_timeout_handle, i4b_idle_check, cd, hz*(cd->shorthold_data.earlyhup_time));
 1161                                 cd->timeout_active = 1;
 1162                                 cd->idletime_state = IST_SAFE;
 1163                                 NDBGL4(L4_TIMO, "%ld: outgoing-call, activity at %ld, wait earlyhup-end", (long)SECOND, (long)i4b_get_idletime(cd));
 1164                         }
 1165                         else
 1166                         {       /* no activity, hangup */
 1167                                 NDBGL4(L4_TIMO, "%ld: outgoing-call, idle timeout, last activity at %ld", (long)SECOND, (long)i4b_get_idletime(cd));
 1168                                 d->l3driver->N_DISCONNECT_REQUEST(cd, (CAUSET_I4B << 8) | CAUSE_I4B_NORMAL);
 1169                                 i4b_l4_idle_timeout_ind(cd);
 1170                                 cd->idletime_state = IST_IDLE;
 1171                         }
 1172                         break;
 1173 
 1174                 case IST_SAFE:  /* end of earlyhup time */
 1175 
 1176                         START_TIMER(cd->idle_timeout_handle, i4b_idle_check, cd, hz*(cd->shorthold_data.unitlen_time - (cd->shorthold_data.idle_time+cd->shorthold_data.earlyhup_time)));
 1177                         cd->timeout_active = 1;
 1178                         cd->idletime_state = IST_NONCHK;
 1179 
 1180                         if(cd->aocd_flag == 0)
 1181                         {
 1182                                 cd->units_type = CHARGE_CALC;
 1183                                 cd->cunits++;
 1184                                 i4b_l4_charging_ind(cd);
 1185                         }
 1186                         
 1187                         NDBGL4(L4_TIMO, "%ld: outgoing-call, earlyhup end, wait for idletime start", (long)SECOND);
 1188                         break;
 1189 
 1190                 default:
 1191                         NDBGL4(L4_ERR, "outgoing-call: invalid idletime_state value!");
 1192                         cd->idletime_state = IST_IDLE;
 1193                         break;
 1194                 }
 1195         }
 1196 }
 1197 
 1198 /*---------------------------------------------------------------------------*
 1199  *      variable unit algorithm B channel idle check timeout function
 1200  *---------------------------------------------------------------------------*/
 1201 static void
 1202 i4b_idle_check_var_unit(call_desc_t *cd)
 1203 {
 1204         switch(cd->idletime_state)
 1205         {
 1206 
 1207         /* see if there has been any activity within the last idle_time seconds */
 1208         case IST_CHECK:
 1209                 if( i4b_get_idletime(cd) > (SECOND - cd->shorthold_data.idle_time))
 1210                 {       /* activity detected */
 1211 #if defined(__FreeBSD_version) && __FreeBSD_version >= 300001
 1212                         cd->idle_timeout_handle =
 1213 #endif
 1214                         /* check again in one second */
 1215                         START_TIMER(cd->idle_timeout_handle, i4b_idle_check, cd, hz);
 1216                         cd->timeout_active = 1;
 1217                         cd->idletime_state = IST_CHECK;
 1218                         NDBGL4(L4_TIMO, "%ld: outgoing-call, var idle timeout - activity at %ld, continuing", (long)SECOND, (long)i4b_get_idletime(cd));
 1219                 }
 1220                 else
 1221                 {       /* no activity, hangup */
 1222                         struct isdn_l3_driver *d = cd->l3drv;
 1223                         NDBGL4(L4_TIMO, "%ld: outgoing-call, var idle timeout - last activity at %ld", (long)SECOND, (long)i4b_get_idletime(cd));
 1224                         d->l3driver->N_DISCONNECT_REQUEST(cd, (CAUSET_I4B << 8) | CAUSE_I4B_NORMAL);
 1225                         i4b_l4_idle_timeout_ind(cd);
 1226                         cd->idletime_state = IST_IDLE;
 1227                 }
 1228                 break;
 1229 
 1230         default:
 1231                 NDBGL4(L4_ERR, "outgoing-call: var idle timeout invalid idletime_state value!");
 1232                 cd->idletime_state = IST_IDLE;
 1233                 break;
 1234         }
 1235 }
 1236 
 1237 #endif /* NISDN > 0 */

Cache object: c8f1cfe093000260cdcaadec35747e3c


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