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/i4b/layer4/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, 2002 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  *
   28  *      i4b_l4.c - kernel interface to userland
   29  *      -----------------------------------------
   30  *      last edit-date: [Sun Aug 11 12:43:14 2002]
   31  *
   32  *---------------------------------------------------------------------------*/
   33 
   34 #include <sys/cdefs.h>
   35 __FBSDID("$FreeBSD: releng/5.4/sys/i4b/layer4/i4b_l4.c 141090 2005-01-31 23:27:04Z imp $");
   36 
   37 #include "i4bipr.h"
   38 
   39 #include <sys/param.h>
   40 #include <sys/kernel.h>
   41 #include <sys/systm.h>
   42 #include <sys/mbuf.h>
   43 
   44 #include "i4bing.h"
   45 #include "i4bisppp.h"
   46 #include "i4brbch.h"
   47 #include "i4btel.h"
   48 
   49 #include <machine/i4b_debug.h>
   50 #include <machine/i4b_ioctl.h>
   51 #include <machine/i4b_cause.h>
   52 
   53 #include <i4b/include/i4b_global.h>
   54 #include <i4b/include/i4b_l3l4.h>
   55 #include <i4b/include/i4b_mbuf.h>
   56 #include <i4b/layer4/i4b_l4.h>
   57 
   58 unsigned int i4b_l4_debug = L4_DEBUG_DEFAULT;
   59 
   60 struct ctrl_type_desc ctrl_types[CTRL_NUMTYPES] = { { NULL, NULL} };
   61 
   62 static int i4b_link_bchandrvr(call_desc_t *cd);
   63 static void i4b_unlink_bchandrvr(call_desc_t *cd);
   64 static void i4b_l4_setup_timeout(call_desc_t *cd);
   65 static void i4b_idle_check_fix_unit(call_desc_t *cd);
   66 static void i4b_idle_check_var_unit(call_desc_t *cd);
   67 static void i4b_l4_setup_timeout_fix_unit(call_desc_t *cd);
   68 static void i4b_l4_setup_timeout_var_unit(call_desc_t *cd);
   69 static time_t i4b_get_idletime(call_desc_t *cd);
   70 
   71 #if NI4BISPPP > 0
   72 extern time_t i4bisppp_idletime(int);
   73 #endif
   74 
   75 /*---------------------------------------------------------------------------*
   76  *      send MSG_PDEACT_IND message to userland
   77  *---------------------------------------------------------------------------*/
   78 void
   79 i4b_l4_pdeact(int controller, int numactive)
   80 {
   81         struct mbuf *m;
   82         int i;
   83         call_desc_t *cd;
   84         
   85         for(i=0; i < N_CALL_DESC; i++)
   86         {
   87                 if((call_desc[i].cdid != CDID_UNUSED)                             &&
   88                    (ctrl_desc[call_desc[i].controller].ctrl_type == CTRL_PASSIVE) &&
   89                    (ctrl_desc[call_desc[i].controller].unit == controller))
   90                 {
   91                         cd = &call_desc[i];
   92                         
   93                         if(cd->timeout_active)
   94                         {
   95                                 STOP_TIMER(cd->idle_timeout_handle, i4b_idle_check, cd);
   96                         }
   97                         
   98                         if(cd->dlt != NULL)
   99                         {
  100                                 (*cd->dlt->line_disconnected)(cd->driver_unit, (void *)cd);
  101                                 i4b_unlink_bchandrvr(cd);
  102                         }
  103                 
  104                         if((cd->channelid >= 0) & (cd->channelid < ctrl_desc[cd->controller].nbch))
  105                         {
  106                                 ctrl_desc[cd->controller].bch_state[cd->channelid] = BCH_ST_FREE;
  107                         }
  108 
  109                         cd->cdid = CDID_UNUSED;
  110                 }
  111         }
  112         
  113         if((m = i4b_Dgetmbuf(sizeof(msg_pdeact_ind_t))) != NULL)
  114         {
  115                 msg_pdeact_ind_t *md = (msg_pdeact_ind_t *)m->m_data;
  116 
  117                 md->header.type = MSG_PDEACT_IND;
  118                 md->header.cdid = -1;
  119 
  120                 md->controller = controller;
  121                 md->numactive = numactive;
  122 
  123                 i4bputqueue_hipri(m);           /* URGENT !!! */
  124         }
  125 }
  126 
  127 /*---------------------------------------------------------------------------*
  128  *      send MSG_L12STAT_IND message to userland
  129  *---------------------------------------------------------------------------*/
  130 void
  131 i4b_l4_l12stat(int controller, int layer, int state)
  132 {
  133         struct mbuf *m;
  134 
  135         if((m = i4b_Dgetmbuf(sizeof(msg_l12stat_ind_t))) != NULL)
  136         {
  137                 msg_l12stat_ind_t *md = (msg_l12stat_ind_t *)m->m_data;
  138 
  139                 md->header.type = MSG_L12STAT_IND;
  140                 md->header.cdid = -1;
  141 
  142                 md->controller = controller;
  143                 md->layer = layer;
  144                 md->state = state;
  145 
  146                 i4bputqueue(m);
  147         }
  148 }
  149 
  150 /*---------------------------------------------------------------------------*
  151  *      send MSG_TEIASG_IND message to userland
  152  *---------------------------------------------------------------------------*/
  153 void
  154 i4b_l4_teiasg(int controller, int tei)
  155 {
  156         struct mbuf *m;
  157 
  158         if((m = i4b_Dgetmbuf(sizeof(msg_teiasg_ind_t))) != NULL)
  159         {
  160                 msg_teiasg_ind_t *md = (msg_teiasg_ind_t *)m->m_data;
  161 
  162                 md->header.type = MSG_TEIASG_IND;
  163                 md->header.cdid = -1;
  164 
  165                 md->controller = controller;
  166                 md->tei = ctrl_desc[controller].tei;
  167 
  168                 i4bputqueue(m);
  169         }
  170 }
  171 
  172 /*---------------------------------------------------------------------------*
  173  *      send MSG_DIALOUT_IND message to userland
  174  *---------------------------------------------------------------------------*/
  175 void
  176 i4b_l4_dialout(int driver, int driver_unit)
  177 {
  178         struct mbuf *m;
  179 
  180         if((m = i4b_Dgetmbuf(sizeof(msg_dialout_ind_t))) != NULL)
  181         {
  182                 msg_dialout_ind_t *md = (msg_dialout_ind_t *)m->m_data;
  183 
  184                 md->header.type = MSG_DIALOUT_IND;
  185                 md->header.cdid = -1;
  186 
  187                 md->driver = driver;
  188                 md->driver_unit = driver_unit;  
  189 
  190                 i4bputqueue(m);
  191         }
  192 }
  193 
  194 /*---------------------------------------------------------------------------*
  195  *      send MSG_DIALOUTNUMBER_IND message to userland
  196  *---------------------------------------------------------------------------*/
  197 void
  198 i4b_l4_dialoutnumber(int driver, int driver_unit, int cmdlen, char *cmd)
  199 {
  200         struct mbuf *m;
  201 
  202         if((m = i4b_Dgetmbuf(sizeof(msg_dialoutnumber_ind_t))) != NULL)
  203         {
  204                 msg_dialoutnumber_ind_t *md = (msg_dialoutnumber_ind_t *)m->m_data;
  205                 int i;
  206 
  207                 md->header.type = MSG_DIALOUTNUMBER_IND;
  208                 md->header.cdid = -1;
  209 
  210                 md->driver = driver;
  211                 md->driver_unit = driver_unit;
  212 
  213                 for (i = 0; i < cmdlen; i++)
  214                         if (cmd[i] == '*')
  215                                 break;
  216 
  217                 /* XXX: TELNO_MAX is _with_ tailing '\0', so max is actually TELNO_MAX - 1 */
  218                 md->cmdlen = (i < TELNO_MAX  - 1 ? i : TELNO_MAX - 1);
  219                 /* skip the (first) '*' */
  220                 md->subaddrlen = (cmdlen - i - 1 < SUBADDR_MAX - 1 ? cmdlen - i - 1 : SUBADDR_MAX - 1);
  221 
  222                 bcopy(cmd, md->cmd, md->cmdlen);
  223                 if (md->subaddrlen != -1)
  224                         bcopy(cmd+i+1, md->subaddr, md->subaddrlen); 
  225 
  226                 NDBGL4(L4_TIMO, "cmd[%d]=%s, subaddr[%d]=%s", md->cmdlen, md->cmd, md->subaddrlen, md->subaddr);
  227                 i4bputqueue(m);
  228         }
  229 }
  230 
  231 /*---------------------------------------------------------------------------*
  232  *      send MSG_KEYPAD_IND message to userland
  233  *---------------------------------------------------------------------------*/
  234 void
  235 i4b_l4_keypad(int driver, int driver_unit, int cmdlen, char *cmd)
  236 {
  237         struct mbuf *m;
  238 
  239         if((m = i4b_Dgetmbuf(sizeof(msg_keypad_ind_t))) != NULL)
  240         {
  241                 msg_keypad_ind_t *md = (msg_keypad_ind_t *)m->m_data;
  242 
  243                 md->header.type = MSG_KEYPAD_IND;
  244                 md->header.cdid = -1;
  245 
  246                 md->driver = driver;
  247                 md->driver_unit = driver_unit;
  248 
  249                 if(cmdlen > KEYPAD_MAX)
  250                         cmdlen = KEYPAD_MAX;
  251 
  252                 md->cmdlen = cmdlen;
  253                 bcopy(cmd, md->cmd, cmdlen);
  254                 i4bputqueue(m);
  255         }
  256 }
  257 
  258 /*---------------------------------------------------------------------------*
  259  *      send MSG_NEGOTIATION_COMPL message to userland
  260  *---------------------------------------------------------------------------*/
  261 void
  262 i4b_l4_negcomplete(call_desc_t *cd)
  263 {
  264         struct mbuf *m;
  265 
  266         if((m = i4b_Dgetmbuf(sizeof(msg_negcomplete_ind_t))) != NULL)
  267         {
  268                 msg_negcomplete_ind_t *md = (msg_negcomplete_ind_t *)m->m_data;
  269 
  270                 md->header.type = MSG_NEGCOMP_IND;
  271                 md->header.cdid = cd->cdid;
  272 
  273                 i4bputqueue(m);
  274         }
  275 }
  276 
  277 /*---------------------------------------------------------------------------*
  278  *      send MSG_IFSTATE_CHANGED_IND message to userland
  279  *---------------------------------------------------------------------------*/
  280 void
  281 i4b_l4_ifstate_changed(call_desc_t *cd, int new_state)
  282 {
  283         struct mbuf *m;
  284 
  285         if((m = i4b_Dgetmbuf(sizeof(msg_ifstatechg_ind_t))) != NULL)
  286         {
  287                 msg_ifstatechg_ind_t *md = (msg_ifstatechg_ind_t *)m->m_data;
  288 
  289                 md->header.type = MSG_IFSTATE_CHANGED_IND;
  290                 md->header.cdid = cd->cdid;
  291                 md->state = new_state;
  292 
  293                 i4bputqueue(m);
  294         }
  295 }
  296 
  297 /*---------------------------------------------------------------------------*
  298  *      send MSG_DRVRDISC_REQ message to userland
  299  *---------------------------------------------------------------------------*/
  300 void
  301 i4b_l4_drvrdisc(int driver, int driver_unit)
  302 {
  303         struct mbuf *m;
  304 
  305         if((m = i4b_Dgetmbuf(sizeof(msg_drvrdisc_req_t))) != NULL)
  306         {
  307                 msg_drvrdisc_req_t *md = (msg_drvrdisc_req_t *)m->m_data;
  308 
  309                 md->header.type = MSG_DRVRDISC_REQ;
  310                 md->header.cdid = -1;
  311 
  312                 md->driver = driver;
  313                 md->driver_unit = driver_unit;  
  314 
  315                 i4bputqueue(m);
  316         }
  317 }
  318 
  319 /*---------------------------------------------------------------------------*
  320  *      send MSG_ACCT_IND message to userland
  321  *---------------------------------------------------------------------------*/
  322 void
  323 i4b_l4_accounting(int driver, int driver_unit, int accttype, int ioutbytes,
  324                 int iinbytes, int ro, int ri, int outbytes, int inbytes)
  325 {
  326         struct mbuf *m;
  327 
  328         if((m = i4b_Dgetmbuf(sizeof(msg_accounting_ind_t))) != NULL)
  329         {
  330                 msg_accounting_ind_t *md = (msg_accounting_ind_t *)m->m_data;
  331 
  332                 md->header.type = MSG_ACCT_IND;
  333                 md->header.cdid = -1;
  334 
  335                 md->driver = driver;
  336                 md->driver_unit = driver_unit;  
  337 
  338                 md->accttype = accttype;
  339                 md->ioutbytes = ioutbytes;
  340                 md->iinbytes = iinbytes;
  341                 md->outbps = ro;
  342                 md->inbps = ri;
  343                 md->outbytes = outbytes;
  344                 md->inbytes = inbytes;
  345                 
  346                 i4bputqueue(m);
  347         }
  348 }
  349 
  350 /*---------------------------------------------------------------------------*
  351  *      send MSG_CONNECT_IND message to userland
  352  *---------------------------------------------------------------------------*/
  353 void
  354 i4b_l4_connect_ind(call_desc_t *cd)
  355 {
  356         struct mbuf *m;
  357 
  358         if((m = i4b_Dgetmbuf(sizeof(msg_connect_ind_t))) != NULL)
  359         {
  360                 msg_connect_ind_t *mp = (msg_connect_ind_t *)m->m_data;
  361 
  362                 mp->header.type = MSG_CONNECT_IND;
  363                 mp->header.cdid = cd->cdid;
  364 
  365                 mp->controller = cd->controller;
  366                 mp->channel = cd->channelid;
  367                 mp->bprot = cd->bprot;
  368                 mp->bcap = cd->bcap;            
  369 
  370                 cd->dir = DIR_INCOMING;
  371 
  372                 if(strlen(cd->dst_telno) > 0)
  373                         strcpy(mp->dst_telno, cd->dst_telno);
  374                 else
  375                         strcpy(mp->dst_telno, TELNO_EMPTY);
  376 
  377                 if(strlen(cd->dst_subaddr) > 0)
  378                         strcpy(mp->dst_subaddr, cd->dst_subaddr);
  379                 else
  380                         strcpy(mp->dst_subaddr, TELNO_EMPTY);
  381 
  382                 if(strlen(cd->src_telno) > 0)
  383                         strcpy(mp->src_telno, cd->src_telno);
  384                 else
  385                         strcpy(mp->src_telno, TELNO_EMPTY);
  386                         
  387                 if(strlen(cd->src_subaddr) > 0)
  388                         strcpy(mp->src_subaddr, cd->src_subaddr);
  389                 else
  390                         strcpy(mp->src_subaddr, TELNO_EMPTY);
  391 
  392                 mp->src_ton = cd->src_ton;
  393                 mp->dst_ton = cd->dst_ton;
  394 
  395                 strcpy(mp->display, cd->display);
  396 
  397                 mp->scr_ind = cd->scr_ind;
  398                 mp->prs_ind = cd->prs_ind;              
  399                 
  400                 T400_start(cd);
  401                 
  402                 i4bputqueue(m);
  403         }
  404 }
  405 
  406 /*---------------------------------------------------------------------------*
  407  *      send MSG_CONNECT_ACTIVE_IND message to userland
  408  *---------------------------------------------------------------------------*/
  409 void
  410 i4b_l4_connect_active_ind(call_desc_t *cd)
  411 {
  412         int s;
  413         struct mbuf *m;
  414 
  415         s = SPLI4B();
  416 
  417         cd->last_active_time = cd->connect_time = SECOND;
  418 
  419         NDBGL4(L4_TIMO, "last_active/connect_time=%ld", (long)cd->connect_time);
  420         
  421         i4b_link_bchandrvr(cd);
  422 
  423         (*cd->dlt->line_connected)(cd->driver_unit, (void *)cd);
  424 
  425         i4b_l4_setup_timeout(cd);
  426         
  427         splx(s);        
  428         
  429         if((m = i4b_Dgetmbuf(sizeof(msg_connect_active_ind_t))) != NULL)
  430         {
  431                 msg_connect_active_ind_t *mp = (msg_connect_active_ind_t *)m->m_data;
  432 
  433                 mp->header.type = MSG_CONNECT_ACTIVE_IND;
  434                 mp->header.cdid = cd->cdid;
  435                 mp->controller = cd->controller;
  436                 mp->channel = cd->channelid;
  437                 if(cd->datetime[0] != '\0')
  438                         strcpy(mp->datetime, cd->datetime);
  439                 else
  440                         mp->datetime[0] = '\0';
  441                 i4bputqueue(m);
  442         }
  443 }
  444 
  445 /*---------------------------------------------------------------------------*
  446  *      send MSG_DISCONNECT_IND message to userland
  447  *---------------------------------------------------------------------------*/
  448 void
  449 i4b_l4_disconnect_ind(call_desc_t *cd)
  450 {
  451         struct mbuf *m;
  452 
  453         if(cd->timeout_active)
  454                 STOP_TIMER(cd->idle_timeout_handle, i4b_idle_check, cd);
  455 
  456         if(cd->dlt != NULL)
  457         {
  458                 (*cd->dlt->line_disconnected)(cd->driver_unit, (void *)cd);
  459                 i4b_unlink_bchandrvr(cd);
  460         }
  461 
  462         if((cd->channelid >= 0) && (cd->channelid < ctrl_desc[cd->controller].nbch))
  463         {
  464                 ctrl_desc[cd->controller].bch_state[cd->channelid] = BCH_ST_FREE;
  465         }
  466         else
  467         {
  468                 /* no error, might be hunting call for callback */
  469                 NDBGL4(L4_MSG, "channel free not valid but %d!", cd->channelid);
  470         }
  471         
  472         if((m = i4b_Dgetmbuf(sizeof(msg_disconnect_ind_t))) != NULL)
  473         {
  474                 msg_disconnect_ind_t *mp = (msg_disconnect_ind_t *)m->m_data;
  475 
  476                 mp->header.type = MSG_DISCONNECT_IND;
  477                 mp->header.cdid = cd->cdid;
  478                 mp->cause = cd->cause_in;
  479 
  480                 i4bputqueue(m);
  481         }
  482 }
  483 
  484 /*---------------------------------------------------------------------------*
  485  *      send MSG_IDLE_TIMEOUT_IND message to userland
  486  *---------------------------------------------------------------------------*/
  487 void
  488 i4b_l4_idle_timeout_ind(call_desc_t *cd)
  489 {
  490         struct mbuf *m;
  491 
  492         if((m = i4b_Dgetmbuf(sizeof(msg_idle_timeout_ind_t))) != NULL)
  493         {
  494                 msg_idle_timeout_ind_t *mp = (msg_idle_timeout_ind_t *)m->m_data;
  495 
  496                 mp->header.type = MSG_IDLE_TIMEOUT_IND;
  497                 mp->header.cdid = cd->cdid;
  498 
  499                 i4bputqueue(m);
  500         }
  501 }
  502 
  503 /*---------------------------------------------------------------------------*
  504  *      send MSG_CHARGING_IND message to userland
  505  *---------------------------------------------------------------------------*/
  506 void
  507 i4b_l4_charging_ind(call_desc_t *cd)
  508 {
  509         struct mbuf *m;
  510 
  511         if((m = i4b_Dgetmbuf(sizeof(msg_charging_ind_t))) != NULL)
  512         {
  513                 msg_charging_ind_t *mp = (msg_charging_ind_t *)m->m_data;
  514 
  515                 mp->header.type = MSG_CHARGING_IND;
  516                 mp->header.cdid = cd->cdid;
  517                 mp->units_type = cd->units_type;
  518 
  519 /*XXX*/         if(mp->units_type == CHARGE_CALC)
  520                         mp->units = cd->cunits;
  521                 else
  522                         mp->units = cd->units;
  523 
  524                 i4bputqueue(m);
  525         }
  526 }
  527 
  528 /*---------------------------------------------------------------------------*
  529  *      send MSG_STATUS_IND message to userland
  530  *---------------------------------------------------------------------------*/
  531 void
  532 i4b_l4_status_ind(call_desc_t *cd)
  533 {
  534 }
  535 
  536 /*---------------------------------------------------------------------------*
  537  *      send MSG_ALERT_IND message to userland
  538  *---------------------------------------------------------------------------*/
  539 void
  540 i4b_l4_alert_ind(call_desc_t *cd)
  541 {
  542         struct mbuf *m;
  543 
  544         if((m = i4b_Dgetmbuf(sizeof(msg_alert_ind_t))) != NULL)
  545         {
  546                 msg_alert_ind_t *mp = (msg_alert_ind_t *)m->m_data;
  547 
  548                 mp->header.type = MSG_ALERT_IND;
  549                 mp->header.cdid = cd->cdid;
  550 
  551                 i4bputqueue(m);
  552         }
  553 }
  554 
  555 /*---------------------------------------------------------------------------*
  556  *      send MSG_INFO_IND message to userland
  557  *---------------------------------------------------------------------------*/
  558 void
  559 i4b_l4_info_ind(call_desc_t *cd)
  560 {
  561 }
  562 
  563 /*---------------------------------------------------------------------------*
  564  *      send MSG_INFO_IND message to userland
  565  *---------------------------------------------------------------------------*/
  566 void
  567 i4b_l4_proceeding_ind(call_desc_t *cd)
  568 {
  569         struct mbuf *m;
  570 
  571         if((m = i4b_Dgetmbuf(sizeof(msg_proceeding_ind_t))) != NULL)
  572         {
  573                 msg_proceeding_ind_t *mp = (msg_proceeding_ind_t *)m->m_data;
  574 
  575                 mp->header.type = MSG_PROCEEDING_IND;
  576                 mp->header.cdid = cd->cdid;
  577                 mp->controller = cd->controller;
  578                 mp->channel = cd->channelid;
  579                 i4bputqueue(m);
  580         }
  581 }
  582 
  583 /*---------------------------------------------------------------------------*
  584  *    send MSG_PACKET_IND message to userland
  585  *---------------------------------------------------------------------------*/
  586 void
  587 i4b_l4_packet_ind(int driver, int driver_unit, int dir, struct mbuf *pkt)
  588 {
  589         struct mbuf *m;
  590         int len = pkt->m_pkthdr.len;
  591         unsigned char *ip = pkt->m_data;
  592 
  593         if((m = i4b_Dgetmbuf(sizeof(msg_packet_ind_t))) != NULL)
  594         {
  595                 msg_packet_ind_t *mp = (msg_packet_ind_t *)m->m_data;
  596 
  597                 mp->header.type = MSG_PACKET_IND;
  598                 mp->header.cdid = -1;
  599                 mp->driver = driver;
  600                 mp->driver_unit = driver_unit;
  601                 mp->direction = dir;
  602                 memcpy(mp->pktdata, ip,
  603                         len <MAX_PACKET_LOG ? len : MAX_PACKET_LOG);
  604                 i4bputqueue(m);
  605         }
  606 }
  607 
  608 /*---------------------------------------------------------------------------*
  609  *      link a driver(unit) to a B-channel(controller,unit,channel)
  610  *---------------------------------------------------------------------------*/
  611 static int
  612 i4b_link_bchandrvr(call_desc_t *cd)
  613 {
  614         int t = ctrl_desc[cd->controller].ctrl_type;
  615         
  616         if(t < 0 || t >= CTRL_NUMTYPES || ctrl_types[t].get_linktab == NULL)
  617         {
  618                         cd->ilt = NULL;
  619         }
  620         else
  621         {
  622                 cd->ilt = ctrl_types[t].get_linktab(
  623                         ctrl_desc[cd->controller].unit,
  624                         cd->channelid);
  625         }
  626 
  627         switch(cd->driver)
  628         {
  629 #if NI4BRBCH > 0
  630                 case BDRV_RBCH:
  631                         cd->dlt = rbch_ret_linktab(cd->driver_unit);
  632                         break;
  633 #endif
  634                 
  635 #if NI4BTEL > 0
  636                 case BDRV_TEL:
  637                         cd->dlt = tel_ret_linktab(cd->driver_unit);
  638                         break;
  639 #endif
  640 
  641 #if NI4BIPR > 0
  642                 case BDRV_IPR:
  643                         cd->dlt = ipr_ret_linktab(cd->driver_unit);
  644                         break;
  645 #endif
  646 
  647 #if NI4BISPPP > 0
  648                 case BDRV_ISPPP:
  649                         cd->dlt = i4bisppp_ret_linktab(cd->driver_unit);
  650                         break;
  651 #endif
  652 
  653 #if NIBC > 0
  654                 case BDRV_IBC:
  655                         cd->dlt = ibc_ret_linktab(cd->driver_unit);
  656                         break;
  657 #endif
  658 
  659 #if NI4BING > 0
  660                 case BDRV_ING:
  661                         cd->dlt = ing_ret_linktab(cd->driver_unit);
  662                         break;
  663 #endif
  664 
  665                 default:
  666                         cd->dlt = NULL;
  667                         break;
  668         }
  669 
  670         if(cd->dlt == NULL || cd->ilt == NULL)
  671                 return(-1);
  672 
  673         if(t >= 0 && t < CTRL_NUMTYPES && ctrl_types[t].set_linktab != NULL)
  674         {
  675                 ctrl_types[t].set_linktab(
  676                                 ctrl_desc[cd->controller].unit,
  677                                 cd->channelid,
  678                                 cd->dlt);
  679         }
  680 
  681         switch(cd->driver)
  682         {
  683 #if NI4BRBCH > 0
  684                 case BDRV_RBCH:
  685                         rbch_set_linktab(cd->driver_unit, cd->ilt);
  686                         break;
  687 #endif
  688 
  689 #if NI4BTEL > 0
  690                 case BDRV_TEL:
  691                         tel_set_linktab(cd->driver_unit, cd->ilt);
  692                         break;
  693 #endif
  694 
  695 #if NI4BIPR > 0
  696                 case BDRV_IPR:
  697                         ipr_set_linktab(cd->driver_unit, cd->ilt);
  698                         break;
  699 #endif
  700 
  701 #if NI4BISPPP > 0
  702                 case BDRV_ISPPP:
  703                         i4bisppp_set_linktab(cd->driver_unit, cd->ilt);
  704                         break;
  705 #endif
  706 
  707 #if NIBC > 0
  708                 case BDRV_IBC:
  709                         ibc_set_linktab(cd->driver_unit, cd->ilt);
  710                         break;
  711 #endif
  712 
  713 #if NI4BING > 0
  714                 case BDRV_ING:
  715                         ing_set_linktab(cd->driver_unit, cd->ilt);
  716                         break;
  717 #endif
  718 
  719                 default:
  720                         return(0);
  721                         break;
  722         }
  723 
  724         /* activate B channel */
  725                 
  726         (*cd->ilt->bch_config)(cd->ilt->unit, cd->ilt->channel, cd->bprot, 1);
  727 
  728         return(0);
  729 }
  730 
  731 /*---------------------------------------------------------------------------*
  732  *      unlink a driver(unit) from a B-channel(controller,unit,channel)
  733  *---------------------------------------------------------------------------*/
  734 static void
  735 i4b_unlink_bchandrvr(call_desc_t *cd)
  736 {
  737         int t = ctrl_desc[cd->controller].ctrl_type;
  738 
  739         if(t < 0 || t >= CTRL_NUMTYPES || ctrl_types[t].get_linktab == NULL)
  740         {
  741                 cd->ilt = NULL;
  742                 return;
  743         }
  744         else
  745         {
  746                 cd->ilt = ctrl_types[t].get_linktab(
  747                                 ctrl_desc[cd->controller].unit,
  748                                 cd->channelid);
  749         }
  750         
  751         /* deactivate B channel */
  752                 
  753         (*cd->ilt->bch_config)(cd->ilt->unit, cd->ilt->channel, cd->bprot, 0);
  754 } 
  755 
  756 /*---------------------------------------------------------------------------
  757 
  758         How shorthold mode works for OUTGOING connections
  759         =================================================
  760 
  761         |<---- unchecked-window ------->|<-checkwindow->|<-safetywindow>|
  762 
  763 idletime_state:      IST_NONCHK             IST_CHECK       IST_SAFE    
  764         
  765         |                               |               |               |
  766   time>>+-------------------------------+---------------+---------------+-...
  767         |                               |               |               |
  768         |                               |<--idle_time-->|<--earlyhup--->|
  769         |<-----------------------unitlen------------------------------->|
  770 
  771         
  772           unitlen - specifies the time a charging unit lasts
  773         idle_time - specifies the thime the line must be idle at the
  774                     end of the unit to be elected for hangup
  775          earlyhup - is the beginning of a timing safety zone before the
  776                     next charging unit starts
  777 
  778         The algorithm works as follows: lets assume the unitlen is 100
  779         secons, idle_time is 40 seconds and earlyhup is 10 seconds.
  780         The line then must be idle 50 seconds after the begin of the
  781         current unit and it must then be quiet for 40 seconds. if it
  782         has been quiet for this 40 seconds, the line is closed 10
  783         seconds before the next charging unit starts. In case there was
  784         any traffic within the idle_time, the line is not closed.
  785         It does not matter whether there was any traffic between second
  786         0 and second 50 or not.
  787 
  788 
  789         How shorthold mode works for INCOMING connections
  790         =================================================
  791 
  792         it is just possible to specify a maximum idle time for incoming
  793         connections, after this time of no activity on the line the line
  794         is closed.
  795         
  796 ---------------------------------------------------------------------------*/   
  797 
  798 static time_t
  799 i4b_get_idletime(call_desc_t *cd)
  800 {
  801         switch (cd->driver) {
  802 #if NI4BISPPP > 0
  803                 case BDRV_ISPPP:
  804                         return i4bisppp_idletime(cd->driver_unit);
  805                 break;
  806 #endif
  807                 default:
  808                         return cd->last_active_time;
  809                 break;
  810         }
  811 }
  812 /*---------------------------------------------------------------------------*
  813  *      B channel idle check timeout setup
  814  *---------------------------------------------------------------------------*/ 
  815 static void
  816 i4b_l4_setup_timeout(call_desc_t *cd)
  817 {
  818         NDBGL4(L4_TIMO, "%ld: direction %d, shorthold algorithm %d",
  819                 (long)SECOND, cd->dir, cd->shorthold_data.shorthold_algorithm);
  820         
  821         cd->timeout_active = 0;
  822         cd->idletime_state = IST_IDLE;
  823         
  824         if((cd->dir == DIR_INCOMING) && (cd->max_idle_time > 0))
  825         {
  826                 /* incoming call: simple max idletime check */
  827         
  828                 START_TIMER(cd->idle_timeout_handle, i4b_idle_check, cd, hz/2);
  829                 cd->timeout_active = 1;
  830                 NDBGL4(L4_TIMO, "%ld: incoming-call, setup max_idle_time to %ld", (long)SECOND, (long)cd->max_idle_time);
  831         }
  832         else if((cd->dir == DIR_OUTGOING) && (cd->shorthold_data.idle_time > 0))
  833         {
  834                 switch( cd->shorthold_data.shorthold_algorithm )
  835                 {
  836                         default:        /* fall into the old fix algorithm */
  837                         case SHA_FIXU:
  838                                 i4b_l4_setup_timeout_fix_unit( cd );
  839                                 break;
  840                                 
  841                         case SHA_VARU:
  842                                 i4b_l4_setup_timeout_var_unit( cd );
  843                                 break;
  844                 }
  845         }
  846         else
  847         {
  848                 NDBGL4(L4_TIMO, "no idle_timeout configured");
  849         }
  850 }
  851 
  852 /*---------------------------------------------------------------------------*
  853  *      fixed unit algorithm B channel idle check timeout setup
  854  *---------------------------------------------------------------------------*/
  855 static void
  856 i4b_l4_setup_timeout_fix_unit(call_desc_t *cd)
  857 {
  858         /* outgoing call */
  859         
  860         if((cd->shorthold_data.idle_time > 0) && (cd->shorthold_data.unitlen_time == 0))
  861         {
  862                 /* outgoing call: simple max idletime check */
  863                 
  864                 START_TIMER(cd->idle_timeout_handle, i4b_idle_check, cd, hz/2);
  865                 cd->timeout_active = 1;
  866                 NDBGL4(L4_TIMO, "%ld: outgoing-call, setup idle_time to %ld",
  867                         (long)SECOND, (long)cd->shorthold_data.idle_time);
  868         }
  869         else if((cd->shorthold_data.unitlen_time > 0) && (cd->shorthold_data.unitlen_time > (cd->shorthold_data.idle_time + cd->shorthold_data.earlyhup_time)))
  870         {
  871                 /* outgoing call: full shorthold mode check */
  872                 
  873                 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)));
  874                 cd->timeout_active = 1;
  875                 cd->idletime_state = IST_NONCHK;
  876                 NDBGL4(L4_TIMO, "%ld: outgoing-call, start %ld sec nocheck window", 
  877                         (long)SECOND, (long)(cd->shorthold_data.unitlen_time - (cd->shorthold_data.idle_time + cd->shorthold_data.earlyhup_time)));
  878 
  879                 if(cd->aocd_flag == 0)
  880                 {
  881                         cd->units_type = CHARGE_CALC;
  882                         cd->cunits++;
  883                         i4b_l4_charging_ind(cd);
  884                 }
  885         }
  886         else
  887         {
  888                 /* parms somehow got wrong .. */
  889                 
  890                 NDBGL4(L4_ERR, "%ld: ERROR: idletime[%ld]+earlyhup[%ld] > unitlength[%ld]!",
  891                         (long)SECOND, (long)cd->shorthold_data.idle_time, (long)cd->shorthold_data.earlyhup_time, (long)cd->shorthold_data.unitlen_time);
  892         }
  893 }
  894 
  895 /*---------------------------------------------------------------------------*
  896  *      variable unit algorithm B channel idle check timeout setup
  897  *---------------------------------------------------------------------------*/
  898 static void
  899 i4b_l4_setup_timeout_var_unit(call_desc_t *cd)
  900 {
  901         /* outgoing call: variable unit idletime check */
  902                 
  903         /*
  904          * start checking for an idle connect one second before the end of the unit.
  905          * The one second takes into account of rounding due to the driver only
  906          * using the seconds and not the uSeconds of the current time
  907          */
  908         cd->idletime_state = IST_CHECK; /* move directly to the checking state */
  909 
  910         START_TIMER(cd->idle_timeout_handle, i4b_idle_check, cd, hz * (cd->shorthold_data.unitlen_time - 1) );
  911         cd->timeout_active = 1;
  912         NDBGL4(L4_TIMO, "%ld: outgoing-call, var idle time - setup to %ld",
  913                 (long)SECOND, (long)cd->shorthold_data.unitlen_time);
  914 }
  915 
  916 
  917 /*---------------------------------------------------------------------------*
  918  *      B channel idle check timeout function
  919  *---------------------------------------------------------------------------*/ 
  920 void
  921 i4b_idle_check(call_desc_t *cd)
  922 {
  923         int s;
  924 
  925         if(cd->cdid == CDID_UNUSED)
  926                 return;
  927         
  928         s = SPLI4B();
  929 
  930         /* failsafe */
  931 
  932         if(cd->timeout_active == 0)
  933         {
  934                 NDBGL4(L4_ERR, "ERROR: timeout_active == 0 !!!");
  935         }
  936         else
  937         {       
  938                 cd->timeout_active = 0;
  939         }
  940         
  941         /* incoming connections, simple idletime check */
  942 
  943         if(cd->dir == DIR_INCOMING)
  944         {
  945                 if((i4b_get_idletime(cd) + cd->max_idle_time) <= SECOND)
  946                 {
  947                         NDBGL4(L4_TIMO, "%ld: incoming-call, line idle timeout, disconnecting!", (long)SECOND);
  948                         (*ctrl_desc[cd->controller].N_DISCONNECT_REQUEST)(cd->cdid,
  949                                         (CAUSET_I4B << 8) | CAUSE_I4B_NORMAL);
  950                         i4b_l4_idle_timeout_ind(cd);
  951                 }
  952                 else
  953                 {
  954                         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);
  955 
  956                         START_TIMER(cd->idle_timeout_handle, i4b_idle_check, cd, hz/2);
  957                         cd->timeout_active = 1;
  958                 }
  959         }
  960 
  961         /* outgoing connections */
  962 
  963         else if(cd->dir == DIR_OUTGOING)
  964         {
  965                 switch( cd->shorthold_data.shorthold_algorithm )
  966                 {
  967                         case SHA_FIXU:
  968                                 i4b_idle_check_fix_unit( cd );
  969                                 break;
  970                         case SHA_VARU:
  971                                 i4b_idle_check_var_unit( cd );
  972                                 break;
  973                         default:
  974                                 NDBGL4(L4_TIMO, "%ld: bad value for shorthold_algorithm of %d",
  975                                         (long)SECOND, cd->shorthold_data.shorthold_algorithm);
  976                                 i4b_idle_check_fix_unit( cd );
  977                                 break;
  978                 }
  979         }
  980         splx(s);
  981 }
  982 
  983 /*---------------------------------------------------------------------------*
  984  *      fixed unit algorithm B channel idle check timeout function
  985  *---------------------------------------------------------------------------*/
  986 static void
  987 i4b_idle_check_fix_unit(call_desc_t *cd)
  988 {
  989 
  990         /* simple idletime calculation */
  991 
  992         if((cd->shorthold_data.idle_time > 0) && (cd->shorthold_data.unitlen_time == 0))
  993         {
  994                 if((i4b_get_idletime(cd) + cd->shorthold_data.idle_time) <= SECOND)
  995                 {
  996                         NDBGL4(L4_TIMO, "%ld: outgoing-call-st, idle timeout, disconnecting!", (long)SECOND);
  997                         (*ctrl_desc[cd->controller].N_DISCONNECT_REQUEST)(cd->cdid, (CAUSET_I4B << 8) | CAUSE_I4B_NORMAL);
  998                         i4b_l4_idle_timeout_ind(cd);
  999                 }
 1000                 else
 1001                 {
 1002                         NDBGL4(L4_TIMO, "%ld: outgoing-call-st, activity, last_active=%ld, max_idle=%ld",
 1003                                         (long)SECOND, (long)i4b_get_idletime(cd), (long)cd->shorthold_data.idle_time);
 1004                         START_TIMER(cd->idle_timeout_handle, i4b_idle_check, cd, hz/2);
 1005                         cd->timeout_active = 1;
 1006                 }
 1007         }
 1008 
 1009         /* full shorthold mode calculation */
 1010 
 1011         else if((cd->shorthold_data.unitlen_time > 0)
 1012                  && (cd->shorthold_data.unitlen_time > (cd->shorthold_data.idle_time + cd->shorthold_data.earlyhup_time)))
 1013         {
 1014                 switch(cd->idletime_state)
 1015                 {
 1016 
 1017                 case IST_NONCHK:        /* end of non-check time */
 1018 
 1019                         START_TIMER(cd->idle_timeout_handle, i4b_idle_check, cd, hz*(cd->shorthold_data.idle_time));
 1020                         cd->idletimechk_start = SECOND;
 1021                         cd->idletime_state = IST_CHECK;
 1022                         cd->timeout_active = 1;
 1023                         NDBGL4(L4_TIMO, "%ld: outgoing-call, idletime check window reached!", (long)SECOND);
 1024                         break;
 1025 
 1026                 case IST_CHECK:         /* end of idletime chk */
 1027                         if((i4b_get_idletime(cd) > cd->idletimechk_start) &&
 1028                            (i4b_get_idletime(cd) <= SECOND))
 1029                         {       /* activity detected */
 1030                                 START_TIMER(cd->idle_timeout_handle, i4b_idle_check, cd, hz*(cd->shorthold_data.earlyhup_time));
 1031                                 cd->timeout_active = 1;
 1032                                 cd->idletime_state = IST_SAFE;
 1033                                 NDBGL4(L4_TIMO, "%ld: outgoing-call, activity at %ld, wait earlyhup-end", (long)SECOND, (long)i4b_get_idletime(cd));
 1034                         }
 1035                         else
 1036                         {       /* no activity, hangup */
 1037                                 NDBGL4(L4_TIMO, "%ld: outgoing-call, idle timeout, last activity at %ld", (long)SECOND, (long)i4b_get_idletime(cd));
 1038                                 (*ctrl_desc[cd->controller].N_DISCONNECT_REQUEST)(cd->cdid, (CAUSET_I4B << 8) | CAUSE_I4B_NORMAL);
 1039                                 i4b_l4_idle_timeout_ind(cd);
 1040                                 cd->idletime_state = IST_IDLE;
 1041                         }
 1042                         break;
 1043 
 1044                 case IST_SAFE:  /* end of earlyhup time */
 1045 
 1046                         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)));
 1047                         cd->timeout_active = 1;
 1048                         cd->idletime_state = IST_NONCHK;
 1049 
 1050                         if(cd->aocd_flag == 0)
 1051                         {
 1052                                 cd->units_type = CHARGE_CALC;
 1053                                 cd->cunits++;
 1054                                 i4b_l4_charging_ind(cd);
 1055                         }
 1056                         
 1057                         NDBGL4(L4_TIMO, "%ld: outgoing-call, earlyhup end, wait for idletime start", (long)SECOND);
 1058                         break;
 1059 
 1060                 default:
 1061                         NDBGL4(L4_ERR, "outgoing-call: invalid idletime_state value!");
 1062                         cd->idletime_state = IST_IDLE;
 1063                         break;
 1064                 }
 1065         }
 1066 }
 1067 
 1068 /*---------------------------------------------------------------------------*
 1069  *      variable unit algorithm B channel idle check timeout function
 1070  *---------------------------------------------------------------------------*/
 1071 static void
 1072 i4b_idle_check_var_unit(call_desc_t *cd)
 1073 {
 1074         switch(cd->idletime_state)
 1075         {
 1076 
 1077         /* see if there has been any activity within the last idle_time seconds */
 1078         case IST_CHECK:
 1079                 if( i4b_get_idletime(cd) > (SECOND - cd->shorthold_data.idle_time))
 1080                 {       /* activity detected */
 1081                         /* check again in one second */         
 1082                         cd->idle_timeout_handle =
 1083                                 START_TIMER (cd->idle_timeout_handle, i4b_idle_check, cd, hz);
 1084                         cd->timeout_active = 1;
 1085                         cd->idletime_state = IST_CHECK;
 1086                         NDBGL4(L4_TIMO, "%ld: outgoing-call, var idle timeout - activity at %ld, continuing", (long)SECOND, (long)i4b_get_idletime(cd));
 1087                 }
 1088                 else
 1089                 {       /* no activity, hangup */
 1090                         NDBGL4(L4_TIMO, "%ld: outgoing-call, var idle timeout - last activity at %ld", (long)SECOND, (long)i4b_get_idletime(cd));
 1091                         (*ctrl_desc[cd->controller].N_DISCONNECT_REQUEST)(cd->cdid, (CAUSET_I4B << 8) | CAUSE_I4B_NORMAL);
 1092                         i4b_l4_idle_timeout_ind(cd);
 1093                         cd->idletime_state = IST_IDLE;
 1094                 }
 1095                 break;
 1096 
 1097         default:
 1098                 NDBGL4(L4_ERR, "outgoing-call: var idle timeout invalid idletime_state value!");
 1099                 cd->idletime_state = IST_IDLE;
 1100                 break;
 1101         }
 1102 }

Cache object: 32a5c901a29eebd1194011746b8c3467


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