2 * Copyright (c) 1997, 2001 Hellmuth Michaelis. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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
25 *---------------------------------------------------------------------------
27 * i4b_l4.c - kernel interface to userland
28 * -----------------------------------------
30 * $Id: i4b_l4.c,v 1.54 2000/08/28 07:24:59 hm Exp $
32 * $FreeBSD: src/sys/i4b/layer4/i4b_l4.c,v 1.6.2.2 2001/12/16 15:12:59 hm Exp $
33 * $DragonFly: src/sys/net/i4b/layer4/i4b_l4.c,v 1.2 2003/06/17 04:28:40 dillon Exp $
35 * last edit-date: [Sun Aug 27 14:53:42 2000]
37 *---------------------------------------------------------------------------*/
44 #include <sys/param.h>
45 #include <sys/kernel.h>
46 #include <sys/systm.h>
50 #include <sys/types.h>
53 #if defined(__NetBSD__) && __NetBSD_Version__ >= 104230000
54 #include <sys/callout.h>
57 #if defined(__FreeBSD__)
72 #include <machine/i4b_debug.h>
73 #include <machine/i4b_ioctl.h>
74 #include <machine/i4b_cause.h>
76 #include <i4b/i4b_debug.h>
77 #include <i4b/i4b_ioctl.h>
78 #include <i4b/i4b_cause.h>
81 #include <i4b/include/i4b_global.h>
82 #include <i4b/include/i4b_l3l4.h>
83 #include <i4b/include/i4b_mbuf.h>
84 #include <i4b/layer4/i4b_l4.h>
86 #if !defined(__FreeBSD__) && !defined(__NetBSD__)
87 #define memcpy(dst, src, len) bcopy((src), (dst), (len))
90 unsigned int i4b_l4_debug = L4_DEBUG_DEFAULT;
92 struct ctrl_type_desc ctrl_types[CTRL_NUMTYPES] = { { NULL, NULL} };
94 static int i4b_link_bchandrvr(call_desc_t *cd);
95 static void i4b_unlink_bchandrvr(call_desc_t *cd);
96 static void i4b_l4_setup_timeout(call_desc_t *cd);
97 static void i4b_idle_check_fix_unit(call_desc_t *cd);
98 static void i4b_idle_check_var_unit(call_desc_t *cd);
99 static void i4b_l4_setup_timeout_fix_unit(call_desc_t *cd);
100 static void i4b_l4_setup_timeout_var_unit(call_desc_t *cd);
101 static time_t i4b_get_idletime(call_desc_t *cd);
103 extern time_t i4bisppp_idletime(int);
106 /*---------------------------------------------------------------------------*
107 * send MSG_PDEACT_IND message to userland
108 *---------------------------------------------------------------------------*/
110 i4b_l4_pdeact(int controller, int numactive)
116 for(i=0; i < N_CALL_DESC; i++)
118 if((call_desc[i].cdid != CDID_UNUSED) &&
119 (ctrl_desc[call_desc[i].controller].ctrl_type == CTRL_PASSIVE) &&
120 (ctrl_desc[call_desc[i].controller].unit == controller))
124 if(cd->timeout_active)
126 STOP_TIMER(cd->idle_timeout_handle, i4b_idle_check, cd);
131 (*cd->dlt->line_disconnected)(cd->driver_unit, (void *)cd);
132 i4b_unlink_bchandrvr(cd);
135 if((cd->channelid >= 0) & (cd->channelid < ctrl_desc[cd->controller].nbch))
137 ctrl_desc[cd->controller].bch_state[cd->channelid] = BCH_ST_FREE;
140 cd->cdid = CDID_UNUSED;
144 if((m = i4b_Dgetmbuf(sizeof(msg_pdeact_ind_t))) != NULL)
146 msg_pdeact_ind_t *md = (msg_pdeact_ind_t *)m->m_data;
148 md->header.type = MSG_PDEACT_IND;
149 md->header.cdid = -1;
151 md->controller = controller;
152 md->numactive = numactive;
154 i4bputqueue_hipri(m); /* URGENT !!! */
158 /*---------------------------------------------------------------------------*
159 * send MSG_L12STAT_IND message to userland
160 *---------------------------------------------------------------------------*/
162 i4b_l4_l12stat(int controller, int layer, int state)
166 if((m = i4b_Dgetmbuf(sizeof(msg_l12stat_ind_t))) != NULL)
168 msg_l12stat_ind_t *md = (msg_l12stat_ind_t *)m->m_data;
170 md->header.type = MSG_L12STAT_IND;
171 md->header.cdid = -1;
173 md->controller = controller;
181 /*---------------------------------------------------------------------------*
182 * send MSG_TEIASG_IND message to userland
183 *---------------------------------------------------------------------------*/
185 i4b_l4_teiasg(int controller, int tei)
189 if((m = i4b_Dgetmbuf(sizeof(msg_teiasg_ind_t))) != NULL)
191 msg_teiasg_ind_t *md = (msg_teiasg_ind_t *)m->m_data;
193 md->header.type = MSG_TEIASG_IND;
194 md->header.cdid = -1;
196 md->controller = controller;
197 md->tei = ctrl_desc[controller].tei;
203 /*---------------------------------------------------------------------------*
204 * send MSG_DIALOUT_IND message to userland
205 *---------------------------------------------------------------------------*/
207 i4b_l4_dialout(int driver, int driver_unit)
211 if((m = i4b_Dgetmbuf(sizeof(msg_dialout_ind_t))) != NULL)
213 msg_dialout_ind_t *md = (msg_dialout_ind_t *)m->m_data;
215 md->header.type = MSG_DIALOUT_IND;
216 md->header.cdid = -1;
219 md->driver_unit = driver_unit;
225 /*---------------------------------------------------------------------------*
226 * send MSG_DIALOUTNUMBER_IND message to userland
227 *---------------------------------------------------------------------------*/
229 i4b_l4_dialoutnumber(int driver, int driver_unit, int cmdlen, char *cmd)
233 if((m = i4b_Dgetmbuf(sizeof(msg_dialoutnumber_ind_t))) != NULL)
235 msg_dialoutnumber_ind_t *md = (msg_dialoutnumber_ind_t *)m->m_data;
237 md->header.type = MSG_DIALOUTNUMBER_IND;
238 md->header.cdid = -1;
241 md->driver_unit = driver_unit;
243 if(cmdlen > TELNO_MAX)
247 bcopy(cmd, md->cmd, cmdlen);
252 /*---------------------------------------------------------------------------*
253 * send MSG_KEYPAD_IND message to userland
254 *---------------------------------------------------------------------------*/
256 i4b_l4_keypad(int driver, int driver_unit, int cmdlen, char *cmd)
260 if((m = i4b_Dgetmbuf(sizeof(msg_keypad_ind_t))) != NULL)
262 msg_keypad_ind_t *md = (msg_keypad_ind_t *)m->m_data;
264 md->header.type = MSG_KEYPAD_IND;
265 md->header.cdid = -1;
268 md->driver_unit = driver_unit;
270 if(cmdlen > KEYPAD_MAX)
274 bcopy(cmd, md->cmd, cmdlen);
279 /*---------------------------------------------------------------------------*
280 * send MSG_NEGOTIATION_COMPL message to userland
281 *---------------------------------------------------------------------------*/
283 i4b_l4_negcomplete(call_desc_t *cd)
287 if((m = i4b_Dgetmbuf(sizeof(msg_negcomplete_ind_t))) != NULL)
289 msg_negcomplete_ind_t *md = (msg_negcomplete_ind_t *)m->m_data;
291 md->header.type = MSG_NEGCOMP_IND;
292 md->header.cdid = cd->cdid;
298 /*---------------------------------------------------------------------------*
299 * send MSG_IFSTATE_CHANGED_IND message to userland
300 *---------------------------------------------------------------------------*/
302 i4b_l4_ifstate_changed(call_desc_t *cd, int new_state)
306 if((m = i4b_Dgetmbuf(sizeof(msg_ifstatechg_ind_t))) != NULL)
308 msg_ifstatechg_ind_t *md = (msg_ifstatechg_ind_t *)m->m_data;
310 md->header.type = MSG_IFSTATE_CHANGED_IND;
311 md->header.cdid = cd->cdid;
312 md->state = new_state;
318 /*---------------------------------------------------------------------------*
319 * send MSG_DRVRDISC_REQ message to userland
320 *---------------------------------------------------------------------------*/
322 i4b_l4_drvrdisc(int driver, int driver_unit)
326 if((m = i4b_Dgetmbuf(sizeof(msg_drvrdisc_req_t))) != NULL)
328 msg_drvrdisc_req_t *md = (msg_drvrdisc_req_t *)m->m_data;
330 md->header.type = MSG_DRVRDISC_REQ;
331 md->header.cdid = -1;
334 md->driver_unit = driver_unit;
340 /*---------------------------------------------------------------------------*
341 * send MSG_ACCT_IND message to userland
342 *---------------------------------------------------------------------------*/
344 i4b_l4_accounting(int driver, int driver_unit, int accttype, int ioutbytes,
345 int iinbytes, int ro, int ri, int outbytes, int inbytes)
349 if((m = i4b_Dgetmbuf(sizeof(msg_accounting_ind_t))) != NULL)
351 msg_accounting_ind_t *md = (msg_accounting_ind_t *)m->m_data;
353 md->header.type = MSG_ACCT_IND;
354 md->header.cdid = -1;
357 md->driver_unit = driver_unit;
359 md->accttype = accttype;
360 md->ioutbytes = ioutbytes;
361 md->iinbytes = iinbytes;
364 md->outbytes = outbytes;
365 md->inbytes = inbytes;
371 /*---------------------------------------------------------------------------*
372 * send MSG_CONNECT_IND message to userland
373 *---------------------------------------------------------------------------*/
375 i4b_l4_connect_ind(call_desc_t *cd)
379 if((m = i4b_Dgetmbuf(sizeof(msg_connect_ind_t))) != NULL)
381 msg_connect_ind_t *mp = (msg_connect_ind_t *)m->m_data;
383 mp->header.type = MSG_CONNECT_IND;
384 mp->header.cdid = cd->cdid;
386 mp->controller = cd->controller;
387 mp->channel = cd->channelid;
388 mp->bprot = cd->bprot;
390 cd->dir = DIR_INCOMING;
392 if(strlen(cd->dst_telno) > 0)
393 strcpy(mp->dst_telno, cd->dst_telno);
395 strcpy(mp->dst_telno, TELNO_EMPTY);
397 if(strlen(cd->src_telno) > 0)
398 strcpy(mp->src_telno, cd->src_telno);
400 strcpy(mp->src_telno, TELNO_EMPTY);
402 strcpy(mp->display, cd->display);
404 mp->scr_ind = cd->scr_ind;
405 mp->prs_ind = cd->prs_ind;
413 /*---------------------------------------------------------------------------*
414 * send MSG_CONNECT_ACTIVE_IND message to userland
415 *---------------------------------------------------------------------------*/
417 i4b_l4_connect_active_ind(call_desc_t *cd)
424 cd->last_active_time = cd->connect_time = SECOND;
426 NDBGL4(L4_TIMO, "last_active/connect_time=%ld", (long)cd->connect_time);
428 i4b_link_bchandrvr(cd);
430 (*cd->dlt->line_connected)(cd->driver_unit, (void *)cd);
432 i4b_l4_setup_timeout(cd);
436 if((m = i4b_Dgetmbuf(sizeof(msg_connect_active_ind_t))) != NULL)
438 msg_connect_active_ind_t *mp = (msg_connect_active_ind_t *)m->m_data;
440 mp->header.type = MSG_CONNECT_ACTIVE_IND;
441 mp->header.cdid = cd->cdid;
442 mp->controller = cd->controller;
443 mp->channel = cd->channelid;
444 if(cd->datetime[0] != '\0')
445 strcpy(mp->datetime, cd->datetime);
447 mp->datetime[0] = '\0';
452 /*---------------------------------------------------------------------------*
453 * send MSG_DISCONNECT_IND message to userland
454 *---------------------------------------------------------------------------*/
456 i4b_l4_disconnect_ind(call_desc_t *cd)
460 if(cd->timeout_active)
461 STOP_TIMER(cd->idle_timeout_handle, i4b_idle_check, cd);
465 (*cd->dlt->line_disconnected)(cd->driver_unit, (void *)cd);
466 i4b_unlink_bchandrvr(cd);
469 if((cd->channelid >= 0) && (cd->channelid < ctrl_desc[cd->controller].nbch))
471 ctrl_desc[cd->controller].bch_state[cd->channelid] = BCH_ST_FREE;
475 /* no error, might be hunting call for callback */
476 NDBGL4(L4_MSG, "channel free not valid but %d!", cd->channelid);
479 if((m = i4b_Dgetmbuf(sizeof(msg_disconnect_ind_t))) != NULL)
481 msg_disconnect_ind_t *mp = (msg_disconnect_ind_t *)m->m_data;
483 mp->header.type = MSG_DISCONNECT_IND;
484 mp->header.cdid = cd->cdid;
485 mp->cause = cd->cause_in;
491 /*---------------------------------------------------------------------------*
492 * send MSG_IDLE_TIMEOUT_IND message to userland
493 *---------------------------------------------------------------------------*/
495 i4b_l4_idle_timeout_ind(call_desc_t *cd)
499 if((m = i4b_Dgetmbuf(sizeof(msg_idle_timeout_ind_t))) != NULL)
501 msg_idle_timeout_ind_t *mp = (msg_idle_timeout_ind_t *)m->m_data;
503 mp->header.type = MSG_IDLE_TIMEOUT_IND;
504 mp->header.cdid = cd->cdid;
510 /*---------------------------------------------------------------------------*
511 * send MSG_CHARGING_IND message to userland
512 *---------------------------------------------------------------------------*/
514 i4b_l4_charging_ind(call_desc_t *cd)
518 if((m = i4b_Dgetmbuf(sizeof(msg_charging_ind_t))) != NULL)
520 msg_charging_ind_t *mp = (msg_charging_ind_t *)m->m_data;
522 mp->header.type = MSG_CHARGING_IND;
523 mp->header.cdid = cd->cdid;
524 mp->units_type = cd->units_type;
526 /*XXX*/ if(mp->units_type == CHARGE_CALC)
527 mp->units = cd->cunits;
529 mp->units = cd->units;
535 /*---------------------------------------------------------------------------*
536 * send MSG_STATUS_IND message to userland
537 *---------------------------------------------------------------------------*/
539 i4b_l4_status_ind(call_desc_t *cd)
543 /*---------------------------------------------------------------------------*
544 * send MSG_ALERT_IND message to userland
545 *---------------------------------------------------------------------------*/
547 i4b_l4_alert_ind(call_desc_t *cd)
551 if((m = i4b_Dgetmbuf(sizeof(msg_alert_ind_t))) != NULL)
553 msg_alert_ind_t *mp = (msg_alert_ind_t *)m->m_data;
555 mp->header.type = MSG_ALERT_IND;
556 mp->header.cdid = cd->cdid;
562 /*---------------------------------------------------------------------------*
563 * send MSG_INFO_IND message to userland
564 *---------------------------------------------------------------------------*/
566 i4b_l4_info_ind(call_desc_t *cd)
570 /*---------------------------------------------------------------------------*
571 * send MSG_INFO_IND message to userland
572 *---------------------------------------------------------------------------*/
574 i4b_l4_proceeding_ind(call_desc_t *cd)
578 if((m = i4b_Dgetmbuf(sizeof(msg_proceeding_ind_t))) != NULL)
580 msg_proceeding_ind_t *mp = (msg_proceeding_ind_t *)m->m_data;
582 mp->header.type = MSG_PROCEEDING_IND;
583 mp->header.cdid = cd->cdid;
584 mp->controller = cd->controller;
585 mp->channel = cd->channelid;
590 /*---------------------------------------------------------------------------*
591 * send MSG_PACKET_IND message to userland
592 *---------------------------------------------------------------------------*/
594 i4b_l4_packet_ind(int driver, int driver_unit, int dir, struct mbuf *pkt)
597 int len = pkt->m_pkthdr.len;
598 unsigned char *ip = pkt->m_data;
600 if((m = i4b_Dgetmbuf(sizeof(msg_packet_ind_t))) != NULL)
602 msg_packet_ind_t *mp = (msg_packet_ind_t *)m->m_data;
604 mp->header.type = MSG_PACKET_IND;
605 mp->header.cdid = -1;
607 mp->driver_unit = driver_unit;
609 memcpy(mp->pktdata, ip,
610 len <MAX_PACKET_LOG ? len : MAX_PACKET_LOG);
615 /*---------------------------------------------------------------------------*
616 * link a driver(unit) to a B-channel(controller,unit,channel)
617 *---------------------------------------------------------------------------*/
619 i4b_link_bchandrvr(call_desc_t *cd)
621 int t = ctrl_desc[cd->controller].ctrl_type;
623 if(t < 0 || t >= CTRL_NUMTYPES || ctrl_types[t].get_linktab == NULL)
629 cd->ilt = ctrl_types[t].get_linktab(
630 ctrl_desc[cd->controller].unit,
638 cd->dlt = rbch_ret_linktab(cd->driver_unit);
644 cd->dlt = tel_ret_linktab(cd->driver_unit);
650 cd->dlt = ipr_ret_linktab(cd->driver_unit);
656 cd->dlt = i4bisppp_ret_linktab(cd->driver_unit);
660 #if defined(__bsdi__) && NIBC > 0
662 cd->dlt = ibc_ret_linktab(cd->driver_unit);
668 cd->dlt = ing_ret_linktab(cd->driver_unit);
677 if(cd->dlt == NULL || cd->ilt == NULL)
680 if(t >= 0 && t < CTRL_NUMTYPES && ctrl_types[t].set_linktab != NULL)
682 ctrl_types[t].set_linktab(
683 ctrl_desc[cd->controller].unit,
692 rbch_set_linktab(cd->driver_unit, cd->ilt);
698 tel_set_linktab(cd->driver_unit, cd->ilt);
704 ipr_set_linktab(cd->driver_unit, cd->ilt);
710 i4bisppp_set_linktab(cd->driver_unit, cd->ilt);
714 #if defined(__bsdi__) && NIBC > 0
716 ibc_set_linktab(cd->driver_unit, cd->ilt);
722 ing_set_linktab(cd->driver_unit, cd->ilt);
731 /* activate B channel */
733 (*cd->ilt->bch_config)(cd->ilt->unit, cd->ilt->channel, cd->bprot, 1);
738 /*---------------------------------------------------------------------------*
739 * unlink a driver(unit) from a B-channel(controller,unit,channel)
740 *---------------------------------------------------------------------------*/
742 i4b_unlink_bchandrvr(call_desc_t *cd)
744 int t = ctrl_desc[cd->controller].ctrl_type;
746 if(t < 0 || t >= CTRL_NUMTYPES || ctrl_types[t].get_linktab == NULL)
753 cd->ilt = ctrl_types[t].get_linktab(
754 ctrl_desc[cd->controller].unit,
758 /* deactivate B channel */
760 (*cd->ilt->bch_config)(cd->ilt->unit, cd->ilt->channel, cd->bprot, 0);
763 /*---------------------------------------------------------------------------
765 How shorthold mode works for OUTGOING connections
766 =================================================
768 |<---- unchecked-window ------->|<-checkwindow->|<-safetywindow>|
770 idletime_state: IST_NONCHK IST_CHECK IST_SAFE
773 time>>+-------------------------------+---------------+---------------+-...
775 | |<--idle_time-->|<--earlyhup--->|
776 |<-----------------------unitlen------------------------------->|
779 unitlen - specifies the time a charging unit lasts
780 idle_time - specifies the thime the line must be idle at the
781 end of the unit to be elected for hangup
782 earlyhup - is the beginning of a timing safety zone before the
783 next charging unit starts
785 The algorithm works as follows: lets assume the unitlen is 100
786 secons, idle_time is 40 seconds and earlyhup is 10 seconds.
787 The line then must be idle 50 seconds after the begin of the
788 current unit and it must then be quiet for 40 seconds. if it
789 has been quiet for this 40 seconds, the line is closed 10
790 seconds before the next charging unit starts. In case there was
791 any traffic within the idle_time, the line is not closed.
792 It does not matter whether there was any traffic between second
793 0 and second 50 or not.
796 How shorthold mode works for INCOMING connections
797 =================================================
799 it is just possible to specify a maximum idle time for incoming
800 connections, after this time of no activity on the line the line
803 ---------------------------------------------------------------------------*/
806 i4b_get_idletime(call_desc_t *cd)
808 switch (cd->driver) {
811 return i4bisppp_idletime(cd->driver_unit);
815 return cd->last_active_time;
819 /*---------------------------------------------------------------------------*
820 * B channel idle check timeout setup
821 *---------------------------------------------------------------------------*/
823 i4b_l4_setup_timeout(call_desc_t *cd)
825 NDBGL4(L4_TIMO, "%ld: direction %d, shorthold algorithm %d",
826 (long)SECOND, cd->dir, cd->shorthold_data.shorthold_algorithm);
828 cd->timeout_active = 0;
829 cd->idletime_state = IST_IDLE;
831 if((cd->dir == DIR_INCOMING) && (cd->max_idle_time > 0))
833 /* incoming call: simple max idletime check */
835 START_TIMER(cd->idle_timeout_handle, i4b_idle_check, cd, hz/2);
836 cd->timeout_active = 1;
837 NDBGL4(L4_TIMO, "%ld: incoming-call, setup max_idle_time to %ld", (long)SECOND, (long)cd->max_idle_time);
839 else if((cd->dir == DIR_OUTGOING) && (cd->shorthold_data.idle_time > 0))
841 switch( cd->shorthold_data.shorthold_algorithm )
843 default: /* fall into the old fix algorithm */
845 i4b_l4_setup_timeout_fix_unit( cd );
849 i4b_l4_setup_timeout_var_unit( cd );
855 NDBGL4(L4_TIMO, "no idle_timeout configured");
859 /*---------------------------------------------------------------------------*
860 * fixed unit algorithm B channel idle check timeout setup
861 *---------------------------------------------------------------------------*/
863 i4b_l4_setup_timeout_fix_unit(call_desc_t *cd)
867 if((cd->shorthold_data.idle_time > 0) && (cd->shorthold_data.unitlen_time == 0))
869 /* outgoing call: simple max idletime check */
871 START_TIMER(cd->idle_timeout_handle, i4b_idle_check, cd, hz/2);
872 cd->timeout_active = 1;
873 NDBGL4(L4_TIMO, "%ld: outgoing-call, setup idle_time to %ld",
874 (long)SECOND, (long)cd->shorthold_data.idle_time);
876 else if((cd->shorthold_data.unitlen_time > 0) && (cd->shorthold_data.unitlen_time > (cd->shorthold_data.idle_time + cd->shorthold_data.earlyhup_time)))
878 /* outgoing call: full shorthold mode check */
880 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)));
881 cd->timeout_active = 1;
882 cd->idletime_state = IST_NONCHK;
883 NDBGL4(L4_TIMO, "%ld: outgoing-call, start %ld sec nocheck window",
884 (long)SECOND, (long)(cd->shorthold_data.unitlen_time - (cd->shorthold_data.idle_time + cd->shorthold_data.earlyhup_time)));
886 if(cd->aocd_flag == 0)
888 cd->units_type = CHARGE_CALC;
890 i4b_l4_charging_ind(cd);
895 /* parms somehow got wrong .. */
897 NDBGL4(L4_ERR, "%ld: ERROR: idletime[%ld]+earlyhup[%ld] > unitlength[%ld]!",
898 (long)SECOND, (long)cd->shorthold_data.idle_time, (long)cd->shorthold_data.earlyhup_time, (long)cd->shorthold_data.unitlen_time);
902 /*---------------------------------------------------------------------------*
903 * variable unit algorithm B channel idle check timeout setup
904 *---------------------------------------------------------------------------*/
906 i4b_l4_setup_timeout_var_unit(call_desc_t *cd)
908 /* outgoing call: variable unit idletime check */
911 * start checking for an idle connect one second before the end of the unit.
912 * The one second takes into account of rounding due to the driver only
913 * using the seconds and not the uSeconds of the current time
915 cd->idletime_state = IST_CHECK; /* move directly to the checking state */
917 START_TIMER(cd->idle_timeout_handle, i4b_idle_check, cd, hz * (cd->shorthold_data.unitlen_time - 1) );
918 cd->timeout_active = 1;
919 NDBGL4(L4_TIMO, "%ld: outgoing-call, var idle time - setup to %ld",
920 (long)SECOND, (long)cd->shorthold_data.unitlen_time);
924 /*---------------------------------------------------------------------------*
925 * B channel idle check timeout function
926 *---------------------------------------------------------------------------*/
928 i4b_idle_check(call_desc_t *cd)
932 if(cd->cdid == CDID_UNUSED)
939 if(cd->timeout_active == 0)
941 NDBGL4(L4_ERR, "ERROR: timeout_active == 0 !!!");
945 cd->timeout_active = 0;
948 /* incoming connections, simple idletime check */
950 if(cd->dir == DIR_INCOMING)
952 if((i4b_get_idletime(cd) + cd->max_idle_time) <= SECOND)
954 NDBGL4(L4_TIMO, "%ld: incoming-call, line idle timeout, disconnecting!", (long)SECOND);
955 (*ctrl_desc[cd->controller].N_DISCONNECT_REQUEST)(cd->cdid,
956 (CAUSET_I4B << 8) | CAUSE_I4B_NORMAL);
957 i4b_l4_idle_timeout_ind(cd);
961 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);
963 START_TIMER(cd->idle_timeout_handle, i4b_idle_check, cd, hz/2);
964 cd->timeout_active = 1;
968 /* outgoing connections */
970 else if(cd->dir == DIR_OUTGOING)
972 switch( cd->shorthold_data.shorthold_algorithm )
975 i4b_idle_check_fix_unit( cd );
978 i4b_idle_check_var_unit( cd );
981 NDBGL4(L4_TIMO, "%ld: bad value for shorthold_algorithm of %d",
982 (long)SECOND, cd->shorthold_data.shorthold_algorithm);
983 i4b_idle_check_fix_unit( cd );
990 /*---------------------------------------------------------------------------*
991 * fixed unit algorithm B channel idle check timeout function
992 *---------------------------------------------------------------------------*/
994 i4b_idle_check_fix_unit(call_desc_t *cd)
997 /* simple idletime calculation */
999 if((cd->shorthold_data.idle_time > 0) && (cd->shorthold_data.unitlen_time == 0))
1001 if((i4b_get_idletime(cd) + cd->shorthold_data.idle_time) <= SECOND)
1003 NDBGL4(L4_TIMO, "%ld: outgoing-call-st, idle timeout, disconnecting!", (long)SECOND);
1004 (*ctrl_desc[cd->controller].N_DISCONNECT_REQUEST)(cd->cdid, (CAUSET_I4B << 8) | CAUSE_I4B_NORMAL);
1005 i4b_l4_idle_timeout_ind(cd);
1009 NDBGL4(L4_TIMO, "%ld: outgoing-call-st, activity, last_active=%ld, max_idle=%ld",
1010 (long)SECOND, (long)i4b_get_idletime(cd), (long)cd->shorthold_data.idle_time);
1011 START_TIMER(cd->idle_timeout_handle, i4b_idle_check, cd, hz/2);
1012 cd->timeout_active = 1;
1016 /* full shorthold mode calculation */
1018 else if((cd->shorthold_data.unitlen_time > 0)
1019 && (cd->shorthold_data.unitlen_time > (cd->shorthold_data.idle_time + cd->shorthold_data.earlyhup_time)))
1021 switch(cd->idletime_state)
1024 case IST_NONCHK: /* end of non-check time */
1026 START_TIMER(cd->idle_timeout_handle, i4b_idle_check, cd, hz*(cd->shorthold_data.idle_time));
1027 cd->idletimechk_start = SECOND;
1028 cd->idletime_state = IST_CHECK;
1029 cd->timeout_active = 1;
1030 NDBGL4(L4_TIMO, "%ld: outgoing-call, idletime check window reached!", (long)SECOND);
1033 case IST_CHECK: /* end of idletime chk */
1034 if((i4b_get_idletime(cd) > cd->idletimechk_start) &&
1035 (i4b_get_idletime(cd) <= SECOND))
1036 { /* activity detected */
1037 START_TIMER(cd->idle_timeout_handle, i4b_idle_check, cd, hz*(cd->shorthold_data.earlyhup_time));
1038 cd->timeout_active = 1;
1039 cd->idletime_state = IST_SAFE;
1040 NDBGL4(L4_TIMO, "%ld: outgoing-call, activity at %ld, wait earlyhup-end", (long)SECOND, (long)i4b_get_idletime(cd));
1043 { /* no activity, hangup */
1044 NDBGL4(L4_TIMO, "%ld: outgoing-call, idle timeout, last activity at %ld", (long)SECOND, (long)i4b_get_idletime(cd));
1045 (*ctrl_desc[cd->controller].N_DISCONNECT_REQUEST)(cd->cdid, (CAUSET_I4B << 8) | CAUSE_I4B_NORMAL);
1046 i4b_l4_idle_timeout_ind(cd);
1047 cd->idletime_state = IST_IDLE;
1051 case IST_SAFE: /* end of earlyhup time */
1053 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)));
1054 cd->timeout_active = 1;
1055 cd->idletime_state = IST_NONCHK;
1057 if(cd->aocd_flag == 0)
1059 cd->units_type = CHARGE_CALC;
1061 i4b_l4_charging_ind(cd);
1064 NDBGL4(L4_TIMO, "%ld: outgoing-call, earlyhup end, wait for idletime start", (long)SECOND);
1068 NDBGL4(L4_ERR, "outgoing-call: invalid idletime_state value!");
1069 cd->idletime_state = IST_IDLE;
1075 /*---------------------------------------------------------------------------*
1076 * variable unit algorithm B channel idle check timeout function
1077 *---------------------------------------------------------------------------*/
1079 i4b_idle_check_var_unit(call_desc_t *cd)
1081 switch(cd->idletime_state)
1084 /* see if there has been any activity within the last idle_time seconds */
1086 if( i4b_get_idletime(cd) > (SECOND - cd->shorthold_data.idle_time))
1087 { /* activity detected */
1088 #if defined(__FreeBSD_version) && __FreeBSD_version >= 300001
1089 cd->idle_timeout_handle =
1091 /* check again in one second */
1092 START_TIMER(cd->idle_timeout_handle, i4b_idle_check, cd, hz);
1093 cd->timeout_active = 1;
1094 cd->idletime_state = IST_CHECK;
1095 NDBGL4(L4_TIMO, "%ld: outgoing-call, var idle timeout - activity at %ld, continuing", (long)SECOND, (long)i4b_get_idletime(cd));
1098 { /* no activity, hangup */
1099 NDBGL4(L4_TIMO, "%ld: outgoing-call, var idle timeout - last activity at %ld", (long)SECOND, (long)i4b_get_idletime(cd));
1100 (*ctrl_desc[cd->controller].N_DISCONNECT_REQUEST)(cd->cdid, (CAUSET_I4B << 8) | CAUSE_I4B_NORMAL);
1101 i4b_l4_idle_timeout_ind(cd);
1102 cd->idletime_state = IST_IDLE;
1107 NDBGL4(L4_ERR, "outgoing-call: var idle timeout invalid idletime_state value!");
1108 cd->idletime_state = IST_IDLE;
1113 #endif /* NI4B > 0 */