2 * Copyright (c) 1997, 2002 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
26 /*---------------------------------------------------------------------------
28 * i4b_l4.c - kernel interface to userland
29 * -----------------------------------------
30 * last edit-date: [Sun Aug 11 12:43:14 2002]
32 *---------------------------------------------------------------------------*/
34 #include <sys/cdefs.h>
35 __FBSDID("$FreeBSD$");
39 #include <sys/param.h>
40 #include <sys/kernel.h>
41 #include <sys/systm.h>
44 #include <i4b/include/i4b_debug.h>
45 #include <i4b/include/i4b_ioctl.h>
46 #include <i4b/include/i4b_cause.h>
48 #include <i4b/include/i4b_global.h>
49 #include <i4b/include/i4b_l3l4.h>
50 #include <i4b/include/i4b_mbuf.h>
51 #include <i4b/layer4/i4b_l4.h>
53 unsigned int i4b_l4_debug = L4_DEBUG_DEFAULT;
55 struct ctrl_type_desc ctrl_types[CTRL_NUMTYPES] = { { NULL, NULL} };
57 static int i4b_link_bchandrvr(call_desc_t *cd);
58 static void i4b_unlink_bchandrvr(call_desc_t *cd);
59 static void i4b_l4_setup_timeout(call_desc_t *cd);
60 static void i4b_idle_check_fix_unit(call_desc_t *cd);
61 static void i4b_idle_check_var_unit(call_desc_t *cd);
62 static void i4b_l4_setup_timeout_fix_unit(call_desc_t *cd);
63 static void i4b_l4_setup_timeout_var_unit(call_desc_t *cd);
64 static time_t i4b_get_idletime(call_desc_t *cd);
66 #if defined(NI4BISPPP) && (NI4BISPPP > 0)
67 extern time_t i4bisppp_idletime(int);
70 /*---------------------------------------------------------------------------*
71 * send MSG_PDEACT_IND message to userland
72 *---------------------------------------------------------------------------*/
74 i4b_l4_pdeact(int controller, int numactive)
80 for(i=0; i < N_CALL_DESC; i++)
82 if((call_desc[i].cdid != CDID_UNUSED) &&
83 (ctrl_desc[call_desc[i].controller].ctrl_type == CTRL_PASSIVE) &&
84 (ctrl_desc[call_desc[i].controller].unit == controller))
88 if(cd->timeout_active)
90 STOP_TIMER(cd->idle_timeout_handle, i4b_idle_check, cd);
95 (*cd->dlt->line_disconnected)(cd->driver_unit, (void *)cd);
96 i4b_unlink_bchandrvr(cd);
99 if((cd->channelid >= 0) & (cd->channelid < ctrl_desc[cd->controller].nbch))
101 ctrl_desc[cd->controller].bch_state[cd->channelid] = BCH_ST_FREE;
104 cd->cdid = CDID_UNUSED;
108 if((m = i4b_Dgetmbuf(sizeof(msg_pdeact_ind_t))) != NULL)
110 msg_pdeact_ind_t *md = (msg_pdeact_ind_t *)m->m_data;
112 md->header.type = MSG_PDEACT_IND;
113 md->header.cdid = -1;
115 md->controller = controller;
116 md->numactive = numactive;
118 i4bputqueue_hipri(m); /* URGENT !!! */
122 /*---------------------------------------------------------------------------*
123 * send MSG_L12STAT_IND message to userland
124 *---------------------------------------------------------------------------*/
126 i4b_l4_l12stat(int controller, int layer, int state)
130 if((m = i4b_Dgetmbuf(sizeof(msg_l12stat_ind_t))) != NULL)
132 msg_l12stat_ind_t *md = (msg_l12stat_ind_t *)m->m_data;
134 md->header.type = MSG_L12STAT_IND;
135 md->header.cdid = -1;
137 md->controller = controller;
145 /*---------------------------------------------------------------------------*
146 * send MSG_TEIASG_IND message to userland
147 *---------------------------------------------------------------------------*/
149 i4b_l4_teiasg(int controller, int tei)
153 if((m = i4b_Dgetmbuf(sizeof(msg_teiasg_ind_t))) != NULL)
155 msg_teiasg_ind_t *md = (msg_teiasg_ind_t *)m->m_data;
157 md->header.type = MSG_TEIASG_IND;
158 md->header.cdid = -1;
160 md->controller = controller;
161 md->tei = ctrl_desc[controller].tei;
167 /*---------------------------------------------------------------------------*
168 * send MSG_DIALOUT_IND message to userland
169 *---------------------------------------------------------------------------*/
171 i4b_l4_dialout(int driver, int driver_unit)
175 if((m = i4b_Dgetmbuf(sizeof(msg_dialout_ind_t))) != NULL)
177 msg_dialout_ind_t *md = (msg_dialout_ind_t *)m->m_data;
179 md->header.type = MSG_DIALOUT_IND;
180 md->header.cdid = -1;
183 md->driver_unit = driver_unit;
189 /*---------------------------------------------------------------------------*
190 * send MSG_DIALOUTNUMBER_IND message to userland
191 *---------------------------------------------------------------------------*/
193 i4b_l4_dialoutnumber(int driver, int driver_unit, int cmdlen, char *cmd)
197 if((m = i4b_Dgetmbuf(sizeof(msg_dialoutnumber_ind_t))) != NULL)
199 msg_dialoutnumber_ind_t *md = (msg_dialoutnumber_ind_t *)m->m_data;
202 md->header.type = MSG_DIALOUTNUMBER_IND;
203 md->header.cdid = -1;
206 md->driver_unit = driver_unit;
208 for (i = 0; i < cmdlen; i++)
212 /* XXX: TELNO_MAX is _with_ tailing '\0', so max is actually TELNO_MAX - 1 */
213 md->cmdlen = (i < TELNO_MAX - 1 ? i : TELNO_MAX - 1);
214 /* skip the (first) '*' */
215 md->subaddrlen = (cmdlen - i - 1 < SUBADDR_MAX - 1 ? cmdlen - i - 1 : SUBADDR_MAX - 1);
217 bcopy(cmd, md->cmd, md->cmdlen);
218 if (md->subaddrlen != -1)
219 bcopy(cmd+i+1, md->subaddr, md->subaddrlen);
221 NDBGL4(L4_TIMO, "cmd[%d]=%s, subaddr[%d]=%s", md->cmdlen, md->cmd, md->subaddrlen, md->subaddr);
226 /*---------------------------------------------------------------------------*
227 * send MSG_KEYPAD_IND message to userland
228 *---------------------------------------------------------------------------*/
230 i4b_l4_keypad(int driver, int driver_unit, int cmdlen, char *cmd)
234 if((m = i4b_Dgetmbuf(sizeof(msg_keypad_ind_t))) != NULL)
236 msg_keypad_ind_t *md = (msg_keypad_ind_t *)m->m_data;
238 md->header.type = MSG_KEYPAD_IND;
239 md->header.cdid = -1;
242 md->driver_unit = driver_unit;
244 if(cmdlen > KEYPAD_MAX)
248 bcopy(cmd, md->cmd, cmdlen);
253 /*---------------------------------------------------------------------------*
254 * send MSG_NEGOTIATION_COMPL message to userland
255 *---------------------------------------------------------------------------*/
257 i4b_l4_negcomplete(call_desc_t *cd)
261 if((m = i4b_Dgetmbuf(sizeof(msg_negcomplete_ind_t))) != NULL)
263 msg_negcomplete_ind_t *md = (msg_negcomplete_ind_t *)m->m_data;
265 md->header.type = MSG_NEGCOMP_IND;
266 md->header.cdid = cd->cdid;
272 /*---------------------------------------------------------------------------*
273 * send MSG_IFSTATE_CHANGED_IND message to userland
274 *---------------------------------------------------------------------------*/
276 i4b_l4_ifstate_changed(call_desc_t *cd, int new_state)
280 if((m = i4b_Dgetmbuf(sizeof(msg_ifstatechg_ind_t))) != NULL)
282 msg_ifstatechg_ind_t *md = (msg_ifstatechg_ind_t *)m->m_data;
284 md->header.type = MSG_IFSTATE_CHANGED_IND;
285 md->header.cdid = cd->cdid;
286 md->state = new_state;
292 /*---------------------------------------------------------------------------*
293 * send MSG_DRVRDISC_REQ message to userland
294 *---------------------------------------------------------------------------*/
296 i4b_l4_drvrdisc(int driver, int driver_unit)
300 if((m = i4b_Dgetmbuf(sizeof(msg_drvrdisc_req_t))) != NULL)
302 msg_drvrdisc_req_t *md = (msg_drvrdisc_req_t *)m->m_data;
304 md->header.type = MSG_DRVRDISC_REQ;
305 md->header.cdid = -1;
308 md->driver_unit = driver_unit;
314 /*---------------------------------------------------------------------------*
315 * send MSG_ACCT_IND message to userland
316 *---------------------------------------------------------------------------*/
318 i4b_l4_accounting(int driver, int driver_unit, int accttype, int ioutbytes,
319 int iinbytes, int ro, int ri, int outbytes, int inbytes)
323 if((m = i4b_Dgetmbuf(sizeof(msg_accounting_ind_t))) != NULL)
325 msg_accounting_ind_t *md = (msg_accounting_ind_t *)m->m_data;
327 md->header.type = MSG_ACCT_IND;
328 md->header.cdid = -1;
331 md->driver_unit = driver_unit;
333 md->accttype = accttype;
334 md->ioutbytes = ioutbytes;
335 md->iinbytes = iinbytes;
338 md->outbytes = outbytes;
339 md->inbytes = inbytes;
345 /*---------------------------------------------------------------------------*
346 * send MSG_CONNECT_IND message to userland
347 *---------------------------------------------------------------------------*/
349 i4b_l4_connect_ind(call_desc_t *cd)
353 if((m = i4b_Dgetmbuf(sizeof(msg_connect_ind_t))) != NULL)
355 msg_connect_ind_t *mp = (msg_connect_ind_t *)m->m_data;
357 mp->header.type = MSG_CONNECT_IND;
358 mp->header.cdid = cd->cdid;
360 mp->controller = cd->controller;
361 mp->channel = cd->channelid;
362 mp->bprot = cd->bprot;
365 cd->dir = DIR_INCOMING;
367 if(strlen(cd->dst_telno) > 0)
368 strcpy(mp->dst_telno, cd->dst_telno);
370 strcpy(mp->dst_telno, TELNO_EMPTY);
372 if(strlen(cd->dst_subaddr) > 0)
373 strcpy(mp->dst_subaddr, cd->dst_subaddr);
375 strcpy(mp->dst_subaddr, TELNO_EMPTY);
377 if(strlen(cd->src_telno) > 0)
378 strcpy(mp->src_telno, cd->src_telno);
380 strcpy(mp->src_telno, TELNO_EMPTY);
382 if(strlen(cd->src_subaddr) > 0)
383 strcpy(mp->src_subaddr, cd->src_subaddr);
385 strcpy(mp->src_subaddr, TELNO_EMPTY);
387 mp->src_ton = cd->src_ton;
388 mp->dst_ton = cd->dst_ton;
390 strcpy(mp->display, cd->display);
392 mp->scr_ind = cd->scr_ind;
393 mp->prs_ind = cd->prs_ind;
401 /*---------------------------------------------------------------------------*
402 * send MSG_CONNECT_ACTIVE_IND message to userland
403 *---------------------------------------------------------------------------*/
405 i4b_l4_connect_active_ind(call_desc_t *cd)
412 cd->last_active_time = cd->connect_time = SECOND;
414 NDBGL4(L4_TIMO, "last_active/connect_time=%ld", (long)cd->connect_time);
416 i4b_link_bchandrvr(cd);
418 (*cd->dlt->line_connected)(cd->driver_unit, (void *)cd);
420 i4b_l4_setup_timeout(cd);
424 if((m = i4b_Dgetmbuf(sizeof(msg_connect_active_ind_t))) != NULL)
426 msg_connect_active_ind_t *mp = (msg_connect_active_ind_t *)m->m_data;
428 mp->header.type = MSG_CONNECT_ACTIVE_IND;
429 mp->header.cdid = cd->cdid;
430 mp->controller = cd->controller;
431 mp->channel = cd->channelid;
432 if(cd->datetime[0] != '\0')
433 strcpy(mp->datetime, cd->datetime);
435 mp->datetime[0] = '\0';
440 /*---------------------------------------------------------------------------*
441 * send MSG_DISCONNECT_IND message to userland
442 *---------------------------------------------------------------------------*/
444 i4b_l4_disconnect_ind(call_desc_t *cd)
448 if(cd->timeout_active)
449 STOP_TIMER(cd->idle_timeout_handle, i4b_idle_check, cd);
453 (*cd->dlt->line_disconnected)(cd->driver_unit, (void *)cd);
454 i4b_unlink_bchandrvr(cd);
457 if((cd->channelid >= 0) && (cd->channelid < ctrl_desc[cd->controller].nbch))
459 ctrl_desc[cd->controller].bch_state[cd->channelid] = BCH_ST_FREE;
463 /* no error, might be hunting call for callback */
464 NDBGL4(L4_MSG, "channel free not valid but %d!", cd->channelid);
467 if((m = i4b_Dgetmbuf(sizeof(msg_disconnect_ind_t))) != NULL)
469 msg_disconnect_ind_t *mp = (msg_disconnect_ind_t *)m->m_data;
471 mp->header.type = MSG_DISCONNECT_IND;
472 mp->header.cdid = cd->cdid;
473 mp->cause = cd->cause_in;
479 /*---------------------------------------------------------------------------*
480 * send MSG_IDLE_TIMEOUT_IND message to userland
481 *---------------------------------------------------------------------------*/
483 i4b_l4_idle_timeout_ind(call_desc_t *cd)
487 if((m = i4b_Dgetmbuf(sizeof(msg_idle_timeout_ind_t))) != NULL)
489 msg_idle_timeout_ind_t *mp = (msg_idle_timeout_ind_t *)m->m_data;
491 mp->header.type = MSG_IDLE_TIMEOUT_IND;
492 mp->header.cdid = cd->cdid;
498 /*---------------------------------------------------------------------------*
499 * send MSG_CHARGING_IND message to userland
500 *---------------------------------------------------------------------------*/
502 i4b_l4_charging_ind(call_desc_t *cd)
506 if((m = i4b_Dgetmbuf(sizeof(msg_charging_ind_t))) != NULL)
508 msg_charging_ind_t *mp = (msg_charging_ind_t *)m->m_data;
510 mp->header.type = MSG_CHARGING_IND;
511 mp->header.cdid = cd->cdid;
512 mp->units_type = cd->units_type;
514 /*XXX*/ if(mp->units_type == CHARGE_CALC)
515 mp->units = cd->cunits;
517 mp->units = cd->units;
523 /*---------------------------------------------------------------------------*
524 * send MSG_STATUS_IND message to userland
525 *---------------------------------------------------------------------------*/
527 i4b_l4_status_ind(call_desc_t *cd)
531 /*---------------------------------------------------------------------------*
532 * send MSG_ALERT_IND message to userland
533 *---------------------------------------------------------------------------*/
535 i4b_l4_alert_ind(call_desc_t *cd)
539 if((m = i4b_Dgetmbuf(sizeof(msg_alert_ind_t))) != NULL)
541 msg_alert_ind_t *mp = (msg_alert_ind_t *)m->m_data;
543 mp->header.type = MSG_ALERT_IND;
544 mp->header.cdid = cd->cdid;
550 /*---------------------------------------------------------------------------*
551 * send MSG_INFO_IND message to userland
552 *---------------------------------------------------------------------------*/
554 i4b_l4_info_ind(call_desc_t *cd)
558 /*---------------------------------------------------------------------------*
559 * send MSG_INFO_IND message to userland
560 *---------------------------------------------------------------------------*/
562 i4b_l4_proceeding_ind(call_desc_t *cd)
566 if((m = i4b_Dgetmbuf(sizeof(msg_proceeding_ind_t))) != NULL)
568 msg_proceeding_ind_t *mp = (msg_proceeding_ind_t *)m->m_data;
570 mp->header.type = MSG_PROCEEDING_IND;
571 mp->header.cdid = cd->cdid;
572 mp->controller = cd->controller;
573 mp->channel = cd->channelid;
578 /*---------------------------------------------------------------------------*
579 * send MSG_PACKET_IND message to userland
580 *---------------------------------------------------------------------------*/
582 i4b_l4_packet_ind(int driver, int driver_unit, int dir, struct mbuf *pkt)
585 int len = pkt->m_pkthdr.len;
586 unsigned char *ip = pkt->m_data;
588 if((m = i4b_Dgetmbuf(sizeof(msg_packet_ind_t))) != NULL)
590 msg_packet_ind_t *mp = (msg_packet_ind_t *)m->m_data;
592 mp->header.type = MSG_PACKET_IND;
593 mp->header.cdid = -1;
595 mp->driver_unit = driver_unit;
597 memcpy(mp->pktdata, ip,
598 len <MAX_PACKET_LOG ? len : MAX_PACKET_LOG);
603 /*---------------------------------------------------------------------------*
604 * link a driver(unit) to a B-channel(controller,unit,channel)
605 *---------------------------------------------------------------------------*/
607 i4b_link_bchandrvr(call_desc_t *cd)
609 int t = ctrl_desc[cd->controller].ctrl_type;
611 if(t < 0 || t >= CTRL_NUMTYPES || ctrl_types[t].get_linktab == NULL)
617 cd->ilt = ctrl_types[t].get_linktab(
618 ctrl_desc[cd->controller].unit,
624 #if defined(NI4BRBCH) && (NI4BRBCH > 0)
626 cd->dlt = rbch_ret_linktab(cd->driver_unit);
630 #if defined(NI4BTEL) && (NI4BTEL > 0)
632 cd->dlt = tel_ret_linktab(cd->driver_unit);
636 #if defined(NI4BIPR) && (NI4BIPR > 0)
638 cd->dlt = ipr_ret_linktab(cd->driver_unit);
642 #if defined(NI4BISPPP) && (NI4BISPPP > 0)
644 cd->dlt = i4bisppp_ret_linktab(cd->driver_unit);
648 #if defined(NIBC) && NIBC > 0
650 cd->dlt = ibc_ret_linktab(cd->driver_unit);
654 #if defined(NI4BING) && (NI4BING > 0)
656 cd->dlt = ing_ret_linktab(cd->driver_unit);
665 if(cd->dlt == NULL || cd->ilt == NULL)
668 if(t >= 0 && t < CTRL_NUMTYPES && ctrl_types[t].set_linktab != NULL)
670 ctrl_types[t].set_linktab(
671 ctrl_desc[cd->controller].unit,
678 #if defined(NI4BRBCH) && (NI4BRBCH > 0)
680 rbch_set_linktab(cd->driver_unit, cd->ilt);
684 #if defined(NI4BTEL) && (NI4BTEL > 0)
686 tel_set_linktab(cd->driver_unit, cd->ilt);
690 #if defined(NI4BIPR) && (NI4BIPR > 0)
692 ipr_set_linktab(cd->driver_unit, cd->ilt);
696 #if defined(NI4BISPPP) && (NI4BISPPP > 0)
698 i4bisppp_set_linktab(cd->driver_unit, cd->ilt);
702 #if defined(NIBC) && NIBC > 0
704 ibc_set_linktab(cd->driver_unit, cd->ilt);
708 #if defined(NI4BING) && (NI4BING > 0)
710 ing_set_linktab(cd->driver_unit, cd->ilt);
719 /* activate B channel */
721 (*cd->ilt->bch_config)(cd->ilt->unit, cd->ilt->channel, cd->bprot, 1);
726 /*---------------------------------------------------------------------------*
727 * unlink a driver(unit) from a B-channel(controller,unit,channel)
728 *---------------------------------------------------------------------------*/
730 i4b_unlink_bchandrvr(call_desc_t *cd)
732 int t = ctrl_desc[cd->controller].ctrl_type;
734 if(t < 0 || t >= CTRL_NUMTYPES || ctrl_types[t].get_linktab == NULL)
741 cd->ilt = ctrl_types[t].get_linktab(
742 ctrl_desc[cd->controller].unit,
746 /* deactivate B channel */
748 (*cd->ilt->bch_config)(cd->ilt->unit, cd->ilt->channel, cd->bprot, 0);
751 /*---------------------------------------------------------------------------
753 How shorthold mode works for OUTGOING connections
754 =================================================
756 |<---- unchecked-window ------->|<-checkwindow->|<-safetywindow>|
758 idletime_state: IST_NONCHK IST_CHECK IST_SAFE
761 time>>+-------------------------------+---------------+---------------+-...
763 | |<--idle_time-->|<--earlyhup--->|
764 |<-----------------------unitlen------------------------------->|
767 unitlen - specifies the time a charging unit lasts
768 idle_time - specifies the thime the line must be idle at the
769 end of the unit to be elected for hangup
770 earlyhup - is the beginning of a timing safety zone before the
771 next charging unit starts
773 The algorithm works as follows: lets assume the unitlen is 100
774 secons, idle_time is 40 seconds and earlyhup is 10 seconds.
775 The line then must be idle 50 seconds after the begin of the
776 current unit and it must then be quiet for 40 seconds. if it
777 has been quiet for this 40 seconds, the line is closed 10
778 seconds before the next charging unit starts. In case there was
779 any traffic within the idle_time, the line is not closed.
780 It does not matter whether there was any traffic between second
781 0 and second 50 or not.
784 How shorthold mode works for INCOMING connections
785 =================================================
787 it is just possible to specify a maximum idle time for incoming
788 connections, after this time of no activity on the line the line
791 ---------------------------------------------------------------------------*/
794 i4b_get_idletime(call_desc_t *cd)
796 switch (cd->driver) {
797 #if defined(NI4BISPPP) && (NI4BISPPP > 0)
799 return i4bisppp_idletime(cd->driver_unit);
803 return cd->last_active_time;
807 /*---------------------------------------------------------------------------*
808 * B channel idle check timeout setup
809 *---------------------------------------------------------------------------*/
811 i4b_l4_setup_timeout(call_desc_t *cd)
813 NDBGL4(L4_TIMO, "%ld: direction %d, shorthold algorithm %d",
814 (long)SECOND, cd->dir, cd->shorthold_data.shorthold_algorithm);
816 cd->timeout_active = 0;
817 cd->idletime_state = IST_IDLE;
819 if((cd->dir == DIR_INCOMING) && (cd->max_idle_time > 0))
821 /* incoming call: simple max idletime check */
823 START_TIMER(cd->idle_timeout_handle, i4b_idle_check, cd, hz/2);
824 cd->timeout_active = 1;
825 NDBGL4(L4_TIMO, "%ld: incoming-call, setup max_idle_time to %ld", (long)SECOND, (long)cd->max_idle_time);
827 else if((cd->dir == DIR_OUTGOING) && (cd->shorthold_data.idle_time > 0))
829 switch( cd->shorthold_data.shorthold_algorithm )
831 default: /* fall into the old fix algorithm */
833 i4b_l4_setup_timeout_fix_unit( cd );
837 i4b_l4_setup_timeout_var_unit( cd );
843 NDBGL4(L4_TIMO, "no idle_timeout configured");
847 /*---------------------------------------------------------------------------*
848 * fixed unit algorithm B channel idle check timeout setup
849 *---------------------------------------------------------------------------*/
851 i4b_l4_setup_timeout_fix_unit(call_desc_t *cd)
855 if((cd->shorthold_data.idle_time > 0) && (cd->shorthold_data.unitlen_time == 0))
857 /* outgoing call: simple max idletime check */
859 START_TIMER(cd->idle_timeout_handle, i4b_idle_check, cd, hz/2);
860 cd->timeout_active = 1;
861 NDBGL4(L4_TIMO, "%ld: outgoing-call, setup idle_time to %ld",
862 (long)SECOND, (long)cd->shorthold_data.idle_time);
864 else if((cd->shorthold_data.unitlen_time > 0) && (cd->shorthold_data.unitlen_time > (cd->shorthold_data.idle_time + cd->shorthold_data.earlyhup_time)))
866 /* outgoing call: full shorthold mode check */
868 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)));
869 cd->timeout_active = 1;
870 cd->idletime_state = IST_NONCHK;
871 NDBGL4(L4_TIMO, "%ld: outgoing-call, start %ld sec nocheck window",
872 (long)SECOND, (long)(cd->shorthold_data.unitlen_time - (cd->shorthold_data.idle_time + cd->shorthold_data.earlyhup_time)));
874 if(cd->aocd_flag == 0)
876 cd->units_type = CHARGE_CALC;
878 i4b_l4_charging_ind(cd);
883 /* parms somehow got wrong .. */
885 NDBGL4(L4_ERR, "%ld: ERROR: idletime[%ld]+earlyhup[%ld] > unitlength[%ld]!",
886 (long)SECOND, (long)cd->shorthold_data.idle_time, (long)cd->shorthold_data.earlyhup_time, (long)cd->shorthold_data.unitlen_time);
890 /*---------------------------------------------------------------------------*
891 * variable unit algorithm B channel idle check timeout setup
892 *---------------------------------------------------------------------------*/
894 i4b_l4_setup_timeout_var_unit(call_desc_t *cd)
896 /* outgoing call: variable unit idletime check */
899 * start checking for an idle connect one second before the end of the unit.
900 * The one second takes into account of rounding due to the driver only
901 * using the seconds and not the uSeconds of the current time
903 cd->idletime_state = IST_CHECK; /* move directly to the checking state */
905 START_TIMER(cd->idle_timeout_handle, i4b_idle_check, cd, hz * (cd->shorthold_data.unitlen_time - 1) );
906 cd->timeout_active = 1;
907 NDBGL4(L4_TIMO, "%ld: outgoing-call, var idle time - setup to %ld",
908 (long)SECOND, (long)cd->shorthold_data.unitlen_time);
912 /*---------------------------------------------------------------------------*
913 * B channel idle check timeout function
914 *---------------------------------------------------------------------------*/
916 i4b_idle_check(call_desc_t *cd)
920 if(cd->cdid == CDID_UNUSED)
927 if(cd->timeout_active == 0)
929 NDBGL4(L4_ERR, "ERROR: timeout_active == 0 !!!");
933 cd->timeout_active = 0;
936 /* incoming connections, simple idletime check */
938 if(cd->dir == DIR_INCOMING)
940 if((i4b_get_idletime(cd) + cd->max_idle_time) <= SECOND)
942 NDBGL4(L4_TIMO, "%ld: incoming-call, line idle timeout, disconnecting!", (long)SECOND);
943 (*ctrl_desc[cd->controller].N_DISCONNECT_REQUEST)(cd->cdid,
944 (CAUSET_I4B << 8) | CAUSE_I4B_NORMAL);
945 i4b_l4_idle_timeout_ind(cd);
949 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);
951 START_TIMER(cd->idle_timeout_handle, i4b_idle_check, cd, hz/2);
952 cd->timeout_active = 1;
956 /* outgoing connections */
958 else if(cd->dir == DIR_OUTGOING)
960 switch( cd->shorthold_data.shorthold_algorithm )
963 i4b_idle_check_fix_unit( cd );
966 i4b_idle_check_var_unit( cd );
969 NDBGL4(L4_TIMO, "%ld: bad value for shorthold_algorithm of %d",
970 (long)SECOND, cd->shorthold_data.shorthold_algorithm);
971 i4b_idle_check_fix_unit( cd );
978 /*---------------------------------------------------------------------------*
979 * fixed unit algorithm B channel idle check timeout function
980 *---------------------------------------------------------------------------*/
982 i4b_idle_check_fix_unit(call_desc_t *cd)
985 /* simple idletime calculation */
987 if((cd->shorthold_data.idle_time > 0) && (cd->shorthold_data.unitlen_time == 0))
989 if((i4b_get_idletime(cd) + cd->shorthold_data.idle_time) <= SECOND)
991 NDBGL4(L4_TIMO, "%ld: outgoing-call-st, idle timeout, disconnecting!", (long)SECOND);
992 (*ctrl_desc[cd->controller].N_DISCONNECT_REQUEST)(cd->cdid, (CAUSET_I4B << 8) | CAUSE_I4B_NORMAL);
993 i4b_l4_idle_timeout_ind(cd);
997 NDBGL4(L4_TIMO, "%ld: outgoing-call-st, activity, last_active=%ld, max_idle=%ld",
998 (long)SECOND, (long)i4b_get_idletime(cd), (long)cd->shorthold_data.idle_time);
999 START_TIMER(cd->idle_timeout_handle, i4b_idle_check, cd, hz/2);
1000 cd->timeout_active = 1;
1004 /* full shorthold mode calculation */
1006 else if((cd->shorthold_data.unitlen_time > 0)
1007 && (cd->shorthold_data.unitlen_time > (cd->shorthold_data.idle_time + cd->shorthold_data.earlyhup_time)))
1009 switch(cd->idletime_state)
1012 case IST_NONCHK: /* end of non-check time */
1014 START_TIMER(cd->idle_timeout_handle, i4b_idle_check, cd, hz*(cd->shorthold_data.idle_time));
1015 cd->idletimechk_start = SECOND;
1016 cd->idletime_state = IST_CHECK;
1017 cd->timeout_active = 1;
1018 NDBGL4(L4_TIMO, "%ld: outgoing-call, idletime check window reached!", (long)SECOND);
1021 case IST_CHECK: /* end of idletime chk */
1022 if((i4b_get_idletime(cd) > cd->idletimechk_start) &&
1023 (i4b_get_idletime(cd) <= SECOND))
1024 { /* activity detected */
1025 START_TIMER(cd->idle_timeout_handle, i4b_idle_check, cd, hz*(cd->shorthold_data.earlyhup_time));
1026 cd->timeout_active = 1;
1027 cd->idletime_state = IST_SAFE;
1028 NDBGL4(L4_TIMO, "%ld: outgoing-call, activity at %ld, wait earlyhup-end", (long)SECOND, (long)i4b_get_idletime(cd));
1031 { /* no activity, hangup */
1032 NDBGL4(L4_TIMO, "%ld: outgoing-call, idle timeout, last activity at %ld", (long)SECOND, (long)i4b_get_idletime(cd));
1033 (*ctrl_desc[cd->controller].N_DISCONNECT_REQUEST)(cd->cdid, (CAUSET_I4B << 8) | CAUSE_I4B_NORMAL);
1034 i4b_l4_idle_timeout_ind(cd);
1035 cd->idletime_state = IST_IDLE;
1039 case IST_SAFE: /* end of earlyhup time */
1041 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)));
1042 cd->timeout_active = 1;
1043 cd->idletime_state = IST_NONCHK;
1045 if(cd->aocd_flag == 0)
1047 cd->units_type = CHARGE_CALC;
1049 i4b_l4_charging_ind(cd);
1052 NDBGL4(L4_TIMO, "%ld: outgoing-call, earlyhup end, wait for idletime start", (long)SECOND);
1056 NDBGL4(L4_ERR, "outgoing-call: invalid idletime_state value!");
1057 cd->idletime_state = IST_IDLE;
1063 /*---------------------------------------------------------------------------*
1064 * variable unit algorithm B channel idle check timeout function
1065 *---------------------------------------------------------------------------*/
1067 i4b_idle_check_var_unit(call_desc_t *cd)
1069 switch(cd->idletime_state)
1072 /* see if there has been any activity within the last idle_time seconds */
1074 if( i4b_get_idletime(cd) > (SECOND - cd->shorthold_data.idle_time))
1075 { /* activity detected */
1076 /* check again in one second */
1077 cd->idle_timeout_handle =
1078 START_TIMER (cd->idle_timeout_handle, i4b_idle_check, cd, hz);
1079 cd->timeout_active = 1;
1080 cd->idletime_state = IST_CHECK;
1081 NDBGL4(L4_TIMO, "%ld: outgoing-call, var idle timeout - activity at %ld, continuing", (long)SECOND, (long)i4b_get_idletime(cd));
1084 { /* no activity, hangup */
1085 NDBGL4(L4_TIMO, "%ld: outgoing-call, var idle timeout - last activity at %ld", (long)SECOND, (long)i4b_get_idletime(cd));
1086 (*ctrl_desc[cd->controller].N_DISCONNECT_REQUEST)(cd->cdid, (CAUSET_I4B << 8) | CAUSE_I4B_NORMAL);
1087 i4b_l4_idle_timeout_ind(cd);
1088 cd->idletime_state = IST_IDLE;
1093 NDBGL4(L4_ERR, "outgoing-call: var idle timeout invalid idletime_state value!");
1094 cd->idletime_state = IST_IDLE;