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 $
34 * last edit-date: [Sun Aug 27 14:53:42 2000]
36 *---------------------------------------------------------------------------*/
43 #include <sys/param.h>
44 #include <sys/kernel.h>
45 #include <sys/systm.h>
49 #include <sys/types.h>
52 #if defined(__NetBSD__) && __NetBSD_Version__ >= 104230000
53 #include <sys/callout.h>
56 #if defined(__FreeBSD__)
71 #include <machine/i4b_debug.h>
72 #include <machine/i4b_ioctl.h>
73 #include <machine/i4b_cause.h>
75 #include <i4b/i4b_debug.h>
76 #include <i4b/i4b_ioctl.h>
77 #include <i4b/i4b_cause.h>
80 #include <i4b/include/i4b_global.h>
81 #include <i4b/include/i4b_l3l4.h>
82 #include <i4b/include/i4b_mbuf.h>
83 #include <i4b/layer4/i4b_l4.h>
85 #if !defined(__FreeBSD__) && !defined(__NetBSD__)
86 #define memcpy(dst, src, len) bcopy((src), (dst), (len))
89 unsigned int i4b_l4_debug = L4_DEBUG_DEFAULT;
91 struct ctrl_type_desc ctrl_types[CTRL_NUMTYPES] = { { NULL, NULL} };
93 static int i4b_link_bchandrvr(call_desc_t *cd);
94 static void i4b_unlink_bchandrvr(call_desc_t *cd);
95 static void i4b_l4_setup_timeout(call_desc_t *cd);
96 static void i4b_idle_check_fix_unit(call_desc_t *cd);
97 static void i4b_idle_check_var_unit(call_desc_t *cd);
98 static void i4b_l4_setup_timeout_fix_unit(call_desc_t *cd);
99 static void i4b_l4_setup_timeout_var_unit(call_desc_t *cd);
100 static time_t i4b_get_idletime(call_desc_t *cd);
102 extern time_t i4bisppp_idletime(int);
105 /*---------------------------------------------------------------------------*
106 * send MSG_PDEACT_IND message to userland
107 *---------------------------------------------------------------------------*/
109 i4b_l4_pdeact(int controller, int numactive)
115 for(i=0; i < N_CALL_DESC; i++)
117 if((call_desc[i].cdid != CDID_UNUSED) &&
118 (ctrl_desc[call_desc[i].controller].ctrl_type == CTRL_PASSIVE) &&
119 (ctrl_desc[call_desc[i].controller].unit == controller))
123 if(cd->timeout_active)
125 STOP_TIMER(cd->idle_timeout_handle, i4b_idle_check, cd);
130 (*cd->dlt->line_disconnected)(cd->driver_unit, (void *)cd);
131 i4b_unlink_bchandrvr(cd);
134 if((cd->channelid >= 0) & (cd->channelid < ctrl_desc[cd->controller].nbch))
136 ctrl_desc[cd->controller].bch_state[cd->channelid] = BCH_ST_FREE;
139 cd->cdid = CDID_UNUSED;
143 if((m = i4b_Dgetmbuf(sizeof(msg_pdeact_ind_t))) != NULL)
145 msg_pdeact_ind_t *md = (msg_pdeact_ind_t *)m->m_data;
147 md->header.type = MSG_PDEACT_IND;
148 md->header.cdid = -1;
150 md->controller = controller;
151 md->numactive = numactive;
153 i4bputqueue_hipri(m); /* URGENT !!! */
157 /*---------------------------------------------------------------------------*
158 * send MSG_L12STAT_IND message to userland
159 *---------------------------------------------------------------------------*/
161 i4b_l4_l12stat(int controller, int layer, int state)
165 if((m = i4b_Dgetmbuf(sizeof(msg_l12stat_ind_t))) != NULL)
167 msg_l12stat_ind_t *md = (msg_l12stat_ind_t *)m->m_data;
169 md->header.type = MSG_L12STAT_IND;
170 md->header.cdid = -1;
172 md->controller = controller;
180 /*---------------------------------------------------------------------------*
181 * send MSG_TEIASG_IND message to userland
182 *---------------------------------------------------------------------------*/
184 i4b_l4_teiasg(int controller, int tei)
188 if((m = i4b_Dgetmbuf(sizeof(msg_teiasg_ind_t))) != NULL)
190 msg_teiasg_ind_t *md = (msg_teiasg_ind_t *)m->m_data;
192 md->header.type = MSG_TEIASG_IND;
193 md->header.cdid = -1;
195 md->controller = controller;
196 md->tei = ctrl_desc[controller].tei;
202 /*---------------------------------------------------------------------------*
203 * send MSG_DIALOUT_IND message to userland
204 *---------------------------------------------------------------------------*/
206 i4b_l4_dialout(int driver, int driver_unit)
210 if((m = i4b_Dgetmbuf(sizeof(msg_dialout_ind_t))) != NULL)
212 msg_dialout_ind_t *md = (msg_dialout_ind_t *)m->m_data;
214 md->header.type = MSG_DIALOUT_IND;
215 md->header.cdid = -1;
218 md->driver_unit = driver_unit;
224 /*---------------------------------------------------------------------------*
225 * send MSG_DIALOUTNUMBER_IND message to userland
226 *---------------------------------------------------------------------------*/
228 i4b_l4_dialoutnumber(int driver, int driver_unit, int cmdlen, char *cmd)
232 if((m = i4b_Dgetmbuf(sizeof(msg_dialoutnumber_ind_t))) != NULL)
234 msg_dialoutnumber_ind_t *md = (msg_dialoutnumber_ind_t *)m->m_data;
236 md->header.type = MSG_DIALOUTNUMBER_IND;
237 md->header.cdid = -1;
240 md->driver_unit = driver_unit;
242 if(cmdlen > TELNO_MAX)
246 bcopy(cmd, md->cmd, cmdlen);
251 /*---------------------------------------------------------------------------*
252 * send MSG_KEYPAD_IND message to userland
253 *---------------------------------------------------------------------------*/
255 i4b_l4_keypad(int driver, int driver_unit, int cmdlen, char *cmd)
259 if((m = i4b_Dgetmbuf(sizeof(msg_keypad_ind_t))) != NULL)
261 msg_keypad_ind_t *md = (msg_keypad_ind_t *)m->m_data;
263 md->header.type = MSG_KEYPAD_IND;
264 md->header.cdid = -1;
267 md->driver_unit = driver_unit;
269 if(cmdlen > KEYPAD_MAX)
273 bcopy(cmd, md->cmd, cmdlen);
278 /*---------------------------------------------------------------------------*
279 * send MSG_NEGOTIATION_COMPL message to userland
280 *---------------------------------------------------------------------------*/
282 i4b_l4_negcomplete(call_desc_t *cd)
286 if((m = i4b_Dgetmbuf(sizeof(msg_negcomplete_ind_t))) != NULL)
288 msg_negcomplete_ind_t *md = (msg_negcomplete_ind_t *)m->m_data;
290 md->header.type = MSG_NEGCOMP_IND;
291 md->header.cdid = cd->cdid;
297 /*---------------------------------------------------------------------------*
298 * send MSG_IFSTATE_CHANGED_IND message to userland
299 *---------------------------------------------------------------------------*/
301 i4b_l4_ifstate_changed(call_desc_t *cd, int new_state)
305 if((m = i4b_Dgetmbuf(sizeof(msg_ifstatechg_ind_t))) != NULL)
307 msg_ifstatechg_ind_t *md = (msg_ifstatechg_ind_t *)m->m_data;
309 md->header.type = MSG_IFSTATE_CHANGED_IND;
310 md->header.cdid = cd->cdid;
311 md->state = new_state;
317 /*---------------------------------------------------------------------------*
318 * send MSG_DRVRDISC_REQ message to userland
319 *---------------------------------------------------------------------------*/
321 i4b_l4_drvrdisc(int driver, int driver_unit)
325 if((m = i4b_Dgetmbuf(sizeof(msg_drvrdisc_req_t))) != NULL)
327 msg_drvrdisc_req_t *md = (msg_drvrdisc_req_t *)m->m_data;
329 md->header.type = MSG_DRVRDISC_REQ;
330 md->header.cdid = -1;
333 md->driver_unit = driver_unit;
339 /*---------------------------------------------------------------------------*
340 * send MSG_ACCT_IND message to userland
341 *---------------------------------------------------------------------------*/
343 i4b_l4_accounting(int driver, int driver_unit, int accttype, int ioutbytes,
344 int iinbytes, int ro, int ri, int outbytes, int inbytes)
348 if((m = i4b_Dgetmbuf(sizeof(msg_accounting_ind_t))) != NULL)
350 msg_accounting_ind_t *md = (msg_accounting_ind_t *)m->m_data;
352 md->header.type = MSG_ACCT_IND;
353 md->header.cdid = -1;
356 md->driver_unit = driver_unit;
358 md->accttype = accttype;
359 md->ioutbytes = ioutbytes;
360 md->iinbytes = iinbytes;
363 md->outbytes = outbytes;
364 md->inbytes = inbytes;
370 /*---------------------------------------------------------------------------*
371 * send MSG_CONNECT_IND message to userland
372 *---------------------------------------------------------------------------*/
374 i4b_l4_connect_ind(call_desc_t *cd)
378 if((m = i4b_Dgetmbuf(sizeof(msg_connect_ind_t))) != NULL)
380 msg_connect_ind_t *mp = (msg_connect_ind_t *)m->m_data;
382 mp->header.type = MSG_CONNECT_IND;
383 mp->header.cdid = cd->cdid;
385 mp->controller = cd->controller;
386 mp->channel = cd->channelid;
387 mp->bprot = cd->bprot;
389 cd->dir = DIR_INCOMING;
391 if(strlen(cd->dst_telno) > 0)
392 strcpy(mp->dst_telno, cd->dst_telno);
394 strcpy(mp->dst_telno, TELNO_EMPTY);
396 if(strlen(cd->src_telno) > 0)
397 strcpy(mp->src_telno, cd->src_telno);
399 strcpy(mp->src_telno, TELNO_EMPTY);
401 strcpy(mp->display, cd->display);
403 mp->scr_ind = cd->scr_ind;
404 mp->prs_ind = cd->prs_ind;
412 /*---------------------------------------------------------------------------*
413 * send MSG_CONNECT_ACTIVE_IND message to userland
414 *---------------------------------------------------------------------------*/
416 i4b_l4_connect_active_ind(call_desc_t *cd)
423 cd->last_active_time = cd->connect_time = SECOND;
425 NDBGL4(L4_TIMO, "last_active/connect_time=%ld", (long)cd->connect_time);
427 i4b_link_bchandrvr(cd);
429 (*cd->dlt->line_connected)(cd->driver_unit, (void *)cd);
431 i4b_l4_setup_timeout(cd);
435 if((m = i4b_Dgetmbuf(sizeof(msg_connect_active_ind_t))) != NULL)
437 msg_connect_active_ind_t *mp = (msg_connect_active_ind_t *)m->m_data;
439 mp->header.type = MSG_CONNECT_ACTIVE_IND;
440 mp->header.cdid = cd->cdid;
441 mp->controller = cd->controller;
442 mp->channel = cd->channelid;
443 if(cd->datetime[0] != '\0')
444 strcpy(mp->datetime, cd->datetime);
446 mp->datetime[0] = '\0';
451 /*---------------------------------------------------------------------------*
452 * send MSG_DISCONNECT_IND message to userland
453 *---------------------------------------------------------------------------*/
455 i4b_l4_disconnect_ind(call_desc_t *cd)
459 if(cd->timeout_active)
460 STOP_TIMER(cd->idle_timeout_handle, i4b_idle_check, cd);
464 (*cd->dlt->line_disconnected)(cd->driver_unit, (void *)cd);
465 i4b_unlink_bchandrvr(cd);
468 if((cd->channelid >= 0) && (cd->channelid < ctrl_desc[cd->controller].nbch))
470 ctrl_desc[cd->controller].bch_state[cd->channelid] = BCH_ST_FREE;
474 /* no error, might be hunting call for callback */
475 NDBGL4(L4_MSG, "channel free not valid but %d!", cd->channelid);
478 if((m = i4b_Dgetmbuf(sizeof(msg_disconnect_ind_t))) != NULL)
480 msg_disconnect_ind_t *mp = (msg_disconnect_ind_t *)m->m_data;
482 mp->header.type = MSG_DISCONNECT_IND;
483 mp->header.cdid = cd->cdid;
484 mp->cause = cd->cause_in;
490 /*---------------------------------------------------------------------------*
491 * send MSG_IDLE_TIMEOUT_IND message to userland
492 *---------------------------------------------------------------------------*/
494 i4b_l4_idle_timeout_ind(call_desc_t *cd)
498 if((m = i4b_Dgetmbuf(sizeof(msg_idle_timeout_ind_t))) != NULL)
500 msg_idle_timeout_ind_t *mp = (msg_idle_timeout_ind_t *)m->m_data;
502 mp->header.type = MSG_IDLE_TIMEOUT_IND;
503 mp->header.cdid = cd->cdid;
509 /*---------------------------------------------------------------------------*
510 * send MSG_CHARGING_IND message to userland
511 *---------------------------------------------------------------------------*/
513 i4b_l4_charging_ind(call_desc_t *cd)
517 if((m = i4b_Dgetmbuf(sizeof(msg_charging_ind_t))) != NULL)
519 msg_charging_ind_t *mp = (msg_charging_ind_t *)m->m_data;
521 mp->header.type = MSG_CHARGING_IND;
522 mp->header.cdid = cd->cdid;
523 mp->units_type = cd->units_type;
525 /*XXX*/ if(mp->units_type == CHARGE_CALC)
526 mp->units = cd->cunits;
528 mp->units = cd->units;
534 /*---------------------------------------------------------------------------*
535 * send MSG_STATUS_IND message to userland
536 *---------------------------------------------------------------------------*/
538 i4b_l4_status_ind(call_desc_t *cd)
542 /*---------------------------------------------------------------------------*
543 * send MSG_ALERT_IND message to userland
544 *---------------------------------------------------------------------------*/
546 i4b_l4_alert_ind(call_desc_t *cd)
550 if((m = i4b_Dgetmbuf(sizeof(msg_alert_ind_t))) != NULL)
552 msg_alert_ind_t *mp = (msg_alert_ind_t *)m->m_data;
554 mp->header.type = MSG_ALERT_IND;
555 mp->header.cdid = cd->cdid;
561 /*---------------------------------------------------------------------------*
562 * send MSG_INFO_IND message to userland
563 *---------------------------------------------------------------------------*/
565 i4b_l4_info_ind(call_desc_t *cd)
569 /*---------------------------------------------------------------------------*
570 * send MSG_INFO_IND message to userland
571 *---------------------------------------------------------------------------*/
573 i4b_l4_proceeding_ind(call_desc_t *cd)
577 if((m = i4b_Dgetmbuf(sizeof(msg_proceeding_ind_t))) != NULL)
579 msg_proceeding_ind_t *mp = (msg_proceeding_ind_t *)m->m_data;
581 mp->header.type = MSG_PROCEEDING_IND;
582 mp->header.cdid = cd->cdid;
583 mp->controller = cd->controller;
584 mp->channel = cd->channelid;
589 /*---------------------------------------------------------------------------*
590 * send MSG_PACKET_IND message to userland
591 *---------------------------------------------------------------------------*/
593 i4b_l4_packet_ind(int driver, int driver_unit, int dir, struct mbuf *pkt)
596 int len = pkt->m_pkthdr.len;
597 unsigned char *ip = pkt->m_data;
599 if((m = i4b_Dgetmbuf(sizeof(msg_packet_ind_t))) != NULL)
601 msg_packet_ind_t *mp = (msg_packet_ind_t *)m->m_data;
603 mp->header.type = MSG_PACKET_IND;
604 mp->header.cdid = -1;
606 mp->driver_unit = driver_unit;
608 memcpy(mp->pktdata, ip,
609 len <MAX_PACKET_LOG ? len : MAX_PACKET_LOG);
614 /*---------------------------------------------------------------------------*
615 * link a driver(unit) to a B-channel(controller,unit,channel)
616 *---------------------------------------------------------------------------*/
618 i4b_link_bchandrvr(call_desc_t *cd)
620 int t = ctrl_desc[cd->controller].ctrl_type;
622 if(t < 0 || t >= CTRL_NUMTYPES || ctrl_types[t].get_linktab == NULL)
628 cd->ilt = ctrl_types[t].get_linktab(
629 ctrl_desc[cd->controller].unit,
637 cd->dlt = rbch_ret_linktab(cd->driver_unit);
643 cd->dlt = tel_ret_linktab(cd->driver_unit);
649 cd->dlt = ipr_ret_linktab(cd->driver_unit);
655 cd->dlt = i4bisppp_ret_linktab(cd->driver_unit);
659 #if defined(__bsdi__) && NIBC > 0
661 cd->dlt = ibc_ret_linktab(cd->driver_unit);
667 cd->dlt = ing_ret_linktab(cd->driver_unit);
676 if(cd->dlt == NULL || cd->ilt == NULL)
679 if(t >= 0 && t < CTRL_NUMTYPES && ctrl_types[t].set_linktab != NULL)
681 ctrl_types[t].set_linktab(
682 ctrl_desc[cd->controller].unit,
691 rbch_set_linktab(cd->driver_unit, cd->ilt);
697 tel_set_linktab(cd->driver_unit, cd->ilt);
703 ipr_set_linktab(cd->driver_unit, cd->ilt);
709 i4bisppp_set_linktab(cd->driver_unit, cd->ilt);
713 #if defined(__bsdi__) && NIBC > 0
715 ibc_set_linktab(cd->driver_unit, cd->ilt);
721 ing_set_linktab(cd->driver_unit, cd->ilt);
730 /* activate B channel */
732 (*cd->ilt->bch_config)(cd->ilt->unit, cd->ilt->channel, cd->bprot, 1);
737 /*---------------------------------------------------------------------------*
738 * unlink a driver(unit) from a B-channel(controller,unit,channel)
739 *---------------------------------------------------------------------------*/
741 i4b_unlink_bchandrvr(call_desc_t *cd)
743 int t = ctrl_desc[cd->controller].ctrl_type;
745 if(t < 0 || t >= CTRL_NUMTYPES || ctrl_types[t].get_linktab == NULL)
752 cd->ilt = ctrl_types[t].get_linktab(
753 ctrl_desc[cd->controller].unit,
757 /* deactivate B channel */
759 (*cd->ilt->bch_config)(cd->ilt->unit, cd->ilt->channel, cd->bprot, 0);
762 /*---------------------------------------------------------------------------
764 How shorthold mode works for OUTGOING connections
765 =================================================
767 |<---- unchecked-window ------->|<-checkwindow->|<-safetywindow>|
769 idletime_state: IST_NONCHK IST_CHECK IST_SAFE
772 time>>+-------------------------------+---------------+---------------+-...
774 | |<--idle_time-->|<--earlyhup--->|
775 |<-----------------------unitlen------------------------------->|
778 unitlen - specifies the time a charging unit lasts
779 idle_time - specifies the thime the line must be idle at the
780 end of the unit to be elected for hangup
781 earlyhup - is the beginning of a timing safety zone before the
782 next charging unit starts
784 The algorithm works as follows: lets assume the unitlen is 100
785 secons, idle_time is 40 seconds and earlyhup is 10 seconds.
786 The line then must be idle 50 seconds after the begin of the
787 current unit and it must then be quiet for 40 seconds. if it
788 has been quiet for this 40 seconds, the line is closed 10
789 seconds before the next charging unit starts. In case there was
790 any traffic within the idle_time, the line is not closed.
791 It does not matter whether there was any traffic between second
792 0 and second 50 or not.
795 How shorthold mode works for INCOMING connections
796 =================================================
798 it is just possible to specify a maximum idle time for incoming
799 connections, after this time of no activity on the line the line
802 ---------------------------------------------------------------------------*/
805 i4b_get_idletime(call_desc_t *cd)
807 switch (cd->driver) {
810 return i4bisppp_idletime(cd->driver_unit);
814 return cd->last_active_time;
818 /*---------------------------------------------------------------------------*
819 * B channel idle check timeout setup
820 *---------------------------------------------------------------------------*/
822 i4b_l4_setup_timeout(call_desc_t *cd)
824 NDBGL4(L4_TIMO, "%ld: direction %d, shorthold algorithm %d",
825 (long)SECOND, cd->dir, cd->shorthold_data.shorthold_algorithm);
827 cd->timeout_active = 0;
828 cd->idletime_state = IST_IDLE;
830 if((cd->dir == DIR_INCOMING) && (cd->max_idle_time > 0))
832 /* incoming call: simple max idletime check */
834 START_TIMER(cd->idle_timeout_handle, i4b_idle_check, cd, hz/2);
835 cd->timeout_active = 1;
836 NDBGL4(L4_TIMO, "%ld: incoming-call, setup max_idle_time to %ld", (long)SECOND, (long)cd->max_idle_time);
838 else if((cd->dir == DIR_OUTGOING) && (cd->shorthold_data.idle_time > 0))
840 switch( cd->shorthold_data.shorthold_algorithm )
842 default: /* fall into the old fix algorithm */
844 i4b_l4_setup_timeout_fix_unit( cd );
848 i4b_l4_setup_timeout_var_unit( cd );
854 NDBGL4(L4_TIMO, "no idle_timeout configured");
858 /*---------------------------------------------------------------------------*
859 * fixed unit algorithm B channel idle check timeout setup
860 *---------------------------------------------------------------------------*/
862 i4b_l4_setup_timeout_fix_unit(call_desc_t *cd)
866 if((cd->shorthold_data.idle_time > 0) && (cd->shorthold_data.unitlen_time == 0))
868 /* outgoing call: simple max idletime check */
870 START_TIMER(cd->idle_timeout_handle, i4b_idle_check, cd, hz/2);
871 cd->timeout_active = 1;
872 NDBGL4(L4_TIMO, "%ld: outgoing-call, setup idle_time to %ld",
873 (long)SECOND, (long)cd->shorthold_data.idle_time);
875 else if((cd->shorthold_data.unitlen_time > 0) && (cd->shorthold_data.unitlen_time > (cd->shorthold_data.idle_time + cd->shorthold_data.earlyhup_time)))
877 /* outgoing call: full shorthold mode check */
879 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)));
880 cd->timeout_active = 1;
881 cd->idletime_state = IST_NONCHK;
882 NDBGL4(L4_TIMO, "%ld: outgoing-call, start %ld sec nocheck window",
883 (long)SECOND, (long)(cd->shorthold_data.unitlen_time - (cd->shorthold_data.idle_time + cd->shorthold_data.earlyhup_time)));
885 if(cd->aocd_flag == 0)
887 cd->units_type = CHARGE_CALC;
889 i4b_l4_charging_ind(cd);
894 /* parms somehow got wrong .. */
896 NDBGL4(L4_ERR, "%ld: ERROR: idletime[%ld]+earlyhup[%ld] > unitlength[%ld]!",
897 (long)SECOND, (long)cd->shorthold_data.idle_time, (long)cd->shorthold_data.earlyhup_time, (long)cd->shorthold_data.unitlen_time);
901 /*---------------------------------------------------------------------------*
902 * variable unit algorithm B channel idle check timeout setup
903 *---------------------------------------------------------------------------*/
905 i4b_l4_setup_timeout_var_unit(call_desc_t *cd)
907 /* outgoing call: variable unit idletime check */
910 * start checking for an idle connect one second before the end of the unit.
911 * The one second takes into account of rounding due to the driver only
912 * using the seconds and not the uSeconds of the current time
914 cd->idletime_state = IST_CHECK; /* move directly to the checking state */
916 START_TIMER(cd->idle_timeout_handle, i4b_idle_check, cd, hz * (cd->shorthold_data.unitlen_time - 1) );
917 cd->timeout_active = 1;
918 NDBGL4(L4_TIMO, "%ld: outgoing-call, var idle time - setup to %ld",
919 (long)SECOND, (long)cd->shorthold_data.unitlen_time);
923 /*---------------------------------------------------------------------------*
924 * B channel idle check timeout function
925 *---------------------------------------------------------------------------*/
927 i4b_idle_check(call_desc_t *cd)
931 if(cd->cdid == CDID_UNUSED)
938 if(cd->timeout_active == 0)
940 NDBGL4(L4_ERR, "ERROR: timeout_active == 0 !!!");
944 cd->timeout_active = 0;
947 /* incoming connections, simple idletime check */
949 if(cd->dir == DIR_INCOMING)
951 if((i4b_get_idletime(cd) + cd->max_idle_time) <= SECOND)
953 NDBGL4(L4_TIMO, "%ld: incoming-call, line idle timeout, disconnecting!", (long)SECOND);
954 (*ctrl_desc[cd->controller].N_DISCONNECT_REQUEST)(cd->cdid,
955 (CAUSET_I4B << 8) | CAUSE_I4B_NORMAL);
956 i4b_l4_idle_timeout_ind(cd);
960 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);
962 START_TIMER(cd->idle_timeout_handle, i4b_idle_check, cd, hz/2);
963 cd->timeout_active = 1;
967 /* outgoing connections */
969 else if(cd->dir == DIR_OUTGOING)
971 switch( cd->shorthold_data.shorthold_algorithm )
974 i4b_idle_check_fix_unit( cd );
977 i4b_idle_check_var_unit( cd );
980 NDBGL4(L4_TIMO, "%ld: bad value for shorthold_algorithm of %d",
981 (long)SECOND, cd->shorthold_data.shorthold_algorithm);
982 i4b_idle_check_fix_unit( cd );
989 /*---------------------------------------------------------------------------*
990 * fixed unit algorithm B channel idle check timeout function
991 *---------------------------------------------------------------------------*/
993 i4b_idle_check_fix_unit(call_desc_t *cd)
996 /* simple idletime calculation */
998 if((cd->shorthold_data.idle_time > 0) && (cd->shorthold_data.unitlen_time == 0))
1000 if((i4b_get_idletime(cd) + cd->shorthold_data.idle_time) <= SECOND)
1002 NDBGL4(L4_TIMO, "%ld: outgoing-call-st, idle timeout, disconnecting!", (long)SECOND);
1003 (*ctrl_desc[cd->controller].N_DISCONNECT_REQUEST)(cd->cdid, (CAUSET_I4B << 8) | CAUSE_I4B_NORMAL);
1004 i4b_l4_idle_timeout_ind(cd);
1008 NDBGL4(L4_TIMO, "%ld: outgoing-call-st, activity, last_active=%ld, max_idle=%ld",
1009 (long)SECOND, (long)i4b_get_idletime(cd), (long)cd->shorthold_data.idle_time);
1010 START_TIMER(cd->idle_timeout_handle, i4b_idle_check, cd, hz/2);
1011 cd->timeout_active = 1;
1015 /* full shorthold mode calculation */
1017 else if((cd->shorthold_data.unitlen_time > 0)
1018 && (cd->shorthold_data.unitlen_time > (cd->shorthold_data.idle_time + cd->shorthold_data.earlyhup_time)))
1020 switch(cd->idletime_state)
1023 case IST_NONCHK: /* end of non-check time */
1025 START_TIMER(cd->idle_timeout_handle, i4b_idle_check, cd, hz*(cd->shorthold_data.idle_time));
1026 cd->idletimechk_start = SECOND;
1027 cd->idletime_state = IST_CHECK;
1028 cd->timeout_active = 1;
1029 NDBGL4(L4_TIMO, "%ld: outgoing-call, idletime check window reached!", (long)SECOND);
1032 case IST_CHECK: /* end of idletime chk */
1033 if((i4b_get_idletime(cd) > cd->idletimechk_start) &&
1034 (i4b_get_idletime(cd) <= SECOND))
1035 { /* activity detected */
1036 START_TIMER(cd->idle_timeout_handle, i4b_idle_check, cd, hz*(cd->shorthold_data.earlyhup_time));
1037 cd->timeout_active = 1;
1038 cd->idletime_state = IST_SAFE;
1039 NDBGL4(L4_TIMO, "%ld: outgoing-call, activity at %ld, wait earlyhup-end", (long)SECOND, (long)i4b_get_idletime(cd));
1042 { /* no activity, hangup */
1043 NDBGL4(L4_TIMO, "%ld: outgoing-call, idle timeout, last activity at %ld", (long)SECOND, (long)i4b_get_idletime(cd));
1044 (*ctrl_desc[cd->controller].N_DISCONNECT_REQUEST)(cd->cdid, (CAUSET_I4B << 8) | CAUSE_I4B_NORMAL);
1045 i4b_l4_idle_timeout_ind(cd);
1046 cd->idletime_state = IST_IDLE;
1050 case IST_SAFE: /* end of earlyhup time */
1052 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)));
1053 cd->timeout_active = 1;
1054 cd->idletime_state = IST_NONCHK;
1056 if(cd->aocd_flag == 0)
1058 cd->units_type = CHARGE_CALC;
1060 i4b_l4_charging_ind(cd);
1063 NDBGL4(L4_TIMO, "%ld: outgoing-call, earlyhup end, wait for idletime start", (long)SECOND);
1067 NDBGL4(L4_ERR, "outgoing-call: invalid idletime_state value!");
1068 cd->idletime_state = IST_IDLE;
1074 /*---------------------------------------------------------------------------*
1075 * variable unit algorithm B channel idle check timeout function
1076 *---------------------------------------------------------------------------*/
1078 i4b_idle_check_var_unit(call_desc_t *cd)
1080 switch(cd->idletime_state)
1083 /* see if there has been any activity within the last idle_time seconds */
1085 if( i4b_get_idletime(cd) > (SECOND - cd->shorthold_data.idle_time))
1086 { /* activity detected */
1087 #if defined(__FreeBSD_version) && __FreeBSD_version >= 300001
1088 cd->idle_timeout_handle =
1090 /* check again in one second */
1091 START_TIMER(cd->idle_timeout_handle, i4b_idle_check, cd, hz);
1092 cd->timeout_active = 1;
1093 cd->idletime_state = IST_CHECK;
1094 NDBGL4(L4_TIMO, "%ld: outgoing-call, var idle timeout - activity at %ld, continuing", (long)SECOND, (long)i4b_get_idletime(cd));
1097 { /* no activity, hangup */
1098 NDBGL4(L4_TIMO, "%ld: outgoing-call, var idle timeout - last activity at %ld", (long)SECOND, (long)i4b_get_idletime(cd));
1099 (*ctrl_desc[cd->controller].N_DISCONNECT_REQUEST)(cd->cdid, (CAUSET_I4B << 8) | CAUSE_I4B_NORMAL);
1100 i4b_l4_idle_timeout_ind(cd);
1101 cd->idletime_state = IST_IDLE;
1106 NDBGL4(L4_ERR, "outgoing-call: var idle timeout invalid idletime_state value!");
1107 cd->idletime_state = IST_IDLE;
1112 #endif /* NI4B > 0 */