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

Cache object: d0e42da819403b107fde1c1362eebe8c


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