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.7 2005/06/14 21:19:19 joerg Exp $
35 * last edit-date: [Sun Aug 27 14:53:42 2000]
37 *---------------------------------------------------------------------------*/
40 #include "use_i4bipr.h"
44 #include <sys/param.h>
45 #include <sys/kernel.h>
46 #include <sys/systm.h>
48 #include <sys/thread2.h>
50 #include "use_i4bing.h"
51 #include "use_i4bisppp.h"
52 #include "use_i4brbch.h"
53 #include "use_i4btel.h"
55 #include <net/i4b/include/machine/i4b_debug.h>
56 #include <net/i4b/include/machine/i4b_ioctl.h>
57 #include <net/i4b/include/machine/i4b_cause.h>
59 #include "../include/i4b_global.h"
60 #include "../include/i4b_l3l4.h"
61 #include "../include/i4b_mbuf.h"
64 unsigned int i4b_l4_debug
= L4_DEBUG_DEFAULT
;
66 struct ctrl_type_desc ctrl_types
[CTRL_NUMTYPES
] = { { NULL
, NULL
} };
68 static int i4b_link_bchandrvr(call_desc_t
*cd
);
69 static void i4b_unlink_bchandrvr(call_desc_t
*cd
);
70 static void i4b_l4_setup_timeout(call_desc_t
*cd
);
71 static void i4b_idle_check_fix_unit(call_desc_t
*cd
);
72 static void i4b_idle_check_var_unit(call_desc_t
*cd
);
73 static void i4b_l4_setup_timeout_fix_unit(call_desc_t
*cd
);
74 static void i4b_l4_setup_timeout_var_unit(call_desc_t
*cd
);
75 static time_t i4b_get_idletime(call_desc_t
*cd
);
77 extern time_t i4bisppp_idletime(int);
80 /*---------------------------------------------------------------------------*
81 * send MSG_PDEACT_IND message to userland
82 *---------------------------------------------------------------------------*/
84 i4b_l4_pdeact(int controller
, int numactive
)
90 for(i
=0; i
< N_CALL_DESC
; i
++)
92 if((call_desc
[i
].cdid
!= CDID_UNUSED
) &&
93 (ctrl_desc
[call_desc
[i
].controller
].ctrl_type
== CTRL_PASSIVE
) &&
94 (ctrl_desc
[call_desc
[i
].controller
].unit
== controller
))
98 if(cd
->timeout_active
)
100 callout_stop(&cd
->idle_timeout
);
105 (*cd
->dlt
->line_disconnected
)(cd
->driver_unit
, (void *)cd
);
106 i4b_unlink_bchandrvr(cd
);
109 if((cd
->channelid
>= 0) & (cd
->channelid
< ctrl_desc
[cd
->controller
].nbch
))
111 ctrl_desc
[cd
->controller
].bch_state
[cd
->channelid
] = BCH_ST_FREE
;
114 cd
->cdid
= CDID_UNUSED
;
118 if((m
= i4b_Dgetmbuf(sizeof(msg_pdeact_ind_t
))) != NULL
)
120 msg_pdeact_ind_t
*md
= (msg_pdeact_ind_t
*)m
->m_data
;
122 md
->header
.type
= MSG_PDEACT_IND
;
123 md
->header
.cdid
= -1;
125 md
->controller
= controller
;
126 md
->numactive
= numactive
;
128 i4bputqueue_hipri(m
); /* URGENT !!! */
132 /*---------------------------------------------------------------------------*
133 * send MSG_L12STAT_IND message to userland
134 *---------------------------------------------------------------------------*/
136 i4b_l4_l12stat(int controller
, int layer
, int state
)
140 if((m
= i4b_Dgetmbuf(sizeof(msg_l12stat_ind_t
))) != NULL
)
142 msg_l12stat_ind_t
*md
= (msg_l12stat_ind_t
*)m
->m_data
;
144 md
->header
.type
= MSG_L12STAT_IND
;
145 md
->header
.cdid
= -1;
147 md
->controller
= controller
;
155 /*---------------------------------------------------------------------------*
156 * send MSG_TEIASG_IND message to userland
157 *---------------------------------------------------------------------------*/
159 i4b_l4_teiasg(int controller
, int tei
)
163 if((m
= i4b_Dgetmbuf(sizeof(msg_teiasg_ind_t
))) != NULL
)
165 msg_teiasg_ind_t
*md
= (msg_teiasg_ind_t
*)m
->m_data
;
167 md
->header
.type
= MSG_TEIASG_IND
;
168 md
->header
.cdid
= -1;
170 md
->controller
= controller
;
171 md
->tei
= ctrl_desc
[controller
].tei
;
177 /*---------------------------------------------------------------------------*
178 * send MSG_DIALOUT_IND message to userland
179 *---------------------------------------------------------------------------*/
181 i4b_l4_dialout(int driver
, int driver_unit
)
185 if((m
= i4b_Dgetmbuf(sizeof(msg_dialout_ind_t
))) != NULL
)
187 msg_dialout_ind_t
*md
= (msg_dialout_ind_t
*)m
->m_data
;
189 md
->header
.type
= MSG_DIALOUT_IND
;
190 md
->header
.cdid
= -1;
193 md
->driver_unit
= driver_unit
;
199 /*---------------------------------------------------------------------------*
200 * send MSG_DIALOUTNUMBER_IND message to userland
201 *---------------------------------------------------------------------------*/
203 i4b_l4_dialoutnumber(int driver
, int driver_unit
, int cmdlen
, char *cmd
)
207 if((m
= i4b_Dgetmbuf(sizeof(msg_dialoutnumber_ind_t
))) != NULL
)
209 msg_dialoutnumber_ind_t
*md
= (msg_dialoutnumber_ind_t
*)m
->m_data
;
211 md
->header
.type
= MSG_DIALOUTNUMBER_IND
;
212 md
->header
.cdid
= -1;
215 md
->driver_unit
= driver_unit
;
217 if(cmdlen
> TELNO_MAX
)
221 bcopy(cmd
, md
->cmd
, cmdlen
);
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
;
364 cd
->dir
= DIR_INCOMING
;
366 if(strlen(cd
->dst_telno
) > 0)
367 strcpy(mp
->dst_telno
, cd
->dst_telno
);
369 strcpy(mp
->dst_telno
, TELNO_EMPTY
);
371 if(strlen(cd
->src_telno
) > 0)
372 strcpy(mp
->src_telno
, cd
->src_telno
);
374 strcpy(mp
->src_telno
, TELNO_EMPTY
);
376 strcpy(mp
->display
, cd
->display
);
378 mp
->scr_ind
= cd
->scr_ind
;
379 mp
->prs_ind
= cd
->prs_ind
;
387 /*---------------------------------------------------------------------------*
388 * send MSG_CONNECT_ACTIVE_IND message to userland
389 *---------------------------------------------------------------------------*/
391 i4b_l4_connect_active_ind(call_desc_t
*cd
)
397 cd
->last_active_time
= cd
->connect_time
= SECOND
;
399 NDBGL4(L4_TIMO
, "last_active/connect_time=%ld", (long)cd
->connect_time
);
401 i4b_link_bchandrvr(cd
);
403 (*cd
->dlt
->line_connected
)(cd
->driver_unit
, (void *)cd
);
405 i4b_l4_setup_timeout(cd
);
409 if((m
= i4b_Dgetmbuf(sizeof(msg_connect_active_ind_t
))) != NULL
)
411 msg_connect_active_ind_t
*mp
= (msg_connect_active_ind_t
*)m
->m_data
;
413 mp
->header
.type
= MSG_CONNECT_ACTIVE_IND
;
414 mp
->header
.cdid
= cd
->cdid
;
415 mp
->controller
= cd
->controller
;
416 mp
->channel
= cd
->channelid
;
417 if(cd
->datetime
[0] != '\0')
418 strcpy(mp
->datetime
, cd
->datetime
);
420 mp
->datetime
[0] = '\0';
425 /*---------------------------------------------------------------------------*
426 * send MSG_DISCONNECT_IND message to userland
427 *---------------------------------------------------------------------------*/
429 i4b_l4_disconnect_ind(call_desc_t
*cd
)
433 if(cd
->timeout_active
)
434 callout_stop(&cd
->idle_timeout
);
438 (*cd
->dlt
->line_disconnected
)(cd
->driver_unit
, (void *)cd
);
439 i4b_unlink_bchandrvr(cd
);
442 if((cd
->channelid
>= 0) && (cd
->channelid
< ctrl_desc
[cd
->controller
].nbch
))
444 ctrl_desc
[cd
->controller
].bch_state
[cd
->channelid
] = BCH_ST_FREE
;
448 /* no error, might be hunting call for callback */
449 NDBGL4(L4_MSG
, "channel free not valid but %d!", cd
->channelid
);
452 if((m
= i4b_Dgetmbuf(sizeof(msg_disconnect_ind_t
))) != NULL
)
454 msg_disconnect_ind_t
*mp
= (msg_disconnect_ind_t
*)m
->m_data
;
456 mp
->header
.type
= MSG_DISCONNECT_IND
;
457 mp
->header
.cdid
= cd
->cdid
;
458 mp
->cause
= cd
->cause_in
;
464 /*---------------------------------------------------------------------------*
465 * send MSG_IDLE_TIMEOUT_IND message to userland
466 *---------------------------------------------------------------------------*/
468 i4b_l4_idle_timeout_ind(call_desc_t
*cd
)
472 if((m
= i4b_Dgetmbuf(sizeof(msg_idle_timeout_ind_t
))) != NULL
)
474 msg_idle_timeout_ind_t
*mp
= (msg_idle_timeout_ind_t
*)m
->m_data
;
476 mp
->header
.type
= MSG_IDLE_TIMEOUT_IND
;
477 mp
->header
.cdid
= cd
->cdid
;
483 /*---------------------------------------------------------------------------*
484 * send MSG_CHARGING_IND message to userland
485 *---------------------------------------------------------------------------*/
487 i4b_l4_charging_ind(call_desc_t
*cd
)
491 if((m
= i4b_Dgetmbuf(sizeof(msg_charging_ind_t
))) != NULL
)
493 msg_charging_ind_t
*mp
= (msg_charging_ind_t
*)m
->m_data
;
495 mp
->header
.type
= MSG_CHARGING_IND
;
496 mp
->header
.cdid
= cd
->cdid
;
497 mp
->units_type
= cd
->units_type
;
499 /*XXX*/ if(mp
->units_type
== CHARGE_CALC
)
500 mp
->units
= cd
->cunits
;
502 mp
->units
= cd
->units
;
508 /*---------------------------------------------------------------------------*
509 * send MSG_STATUS_IND message to userland
510 *---------------------------------------------------------------------------*/
512 i4b_l4_status_ind(call_desc_t
*cd
)
516 /*---------------------------------------------------------------------------*
517 * send MSG_ALERT_IND message to userland
518 *---------------------------------------------------------------------------*/
520 i4b_l4_alert_ind(call_desc_t
*cd
)
524 if((m
= i4b_Dgetmbuf(sizeof(msg_alert_ind_t
))) != NULL
)
526 msg_alert_ind_t
*mp
= (msg_alert_ind_t
*)m
->m_data
;
528 mp
->header
.type
= MSG_ALERT_IND
;
529 mp
->header
.cdid
= cd
->cdid
;
535 /*---------------------------------------------------------------------------*
536 * send MSG_INFO_IND message to userland
537 *---------------------------------------------------------------------------*/
539 i4b_l4_info_ind(call_desc_t
*cd
)
543 /*---------------------------------------------------------------------------*
544 * send MSG_INFO_IND message to userland
545 *---------------------------------------------------------------------------*/
547 i4b_l4_proceeding_ind(call_desc_t
*cd
)
551 if((m
= i4b_Dgetmbuf(sizeof(msg_proceeding_ind_t
))) != NULL
)
553 msg_proceeding_ind_t
*mp
= (msg_proceeding_ind_t
*)m
->m_data
;
555 mp
->header
.type
= MSG_PROCEEDING_IND
;
556 mp
->header
.cdid
= cd
->cdid
;
557 mp
->controller
= cd
->controller
;
558 mp
->channel
= cd
->channelid
;
563 /*---------------------------------------------------------------------------*
564 * send MSG_PACKET_IND message to userland
565 *---------------------------------------------------------------------------*/
567 i4b_l4_packet_ind(int driver
, int driver_unit
, int dir
, struct mbuf
*pkt
)
570 int len
= pkt
->m_pkthdr
.len
;
571 unsigned char *ip
= pkt
->m_data
;
573 if((m
= i4b_Dgetmbuf(sizeof(msg_packet_ind_t
))) != NULL
)
575 msg_packet_ind_t
*mp
= (msg_packet_ind_t
*)m
->m_data
;
577 mp
->header
.type
= MSG_PACKET_IND
;
578 mp
->header
.cdid
= -1;
580 mp
->driver_unit
= driver_unit
;
582 memcpy(mp
->pktdata
, ip
,
583 len
<MAX_PACKET_LOG
? len
: MAX_PACKET_LOG
);
588 /*---------------------------------------------------------------------------*
589 * link a driver(unit) to a B-channel(controller,unit,channel)
590 *---------------------------------------------------------------------------*/
592 i4b_link_bchandrvr(call_desc_t
*cd
)
594 int t
= ctrl_desc
[cd
->controller
].ctrl_type
;
596 if(t
< 0 || t
>= CTRL_NUMTYPES
|| ctrl_types
[t
].get_linktab
== NULL
)
602 cd
->ilt
= ctrl_types
[t
].get_linktab(
603 ctrl_desc
[cd
->controller
].unit
,
611 cd
->dlt
= rbch_ret_linktab(cd
->driver_unit
);
617 cd
->dlt
= tel_ret_linktab(cd
->driver_unit
);
623 cd
->dlt
= ipr_ret_linktab(cd
->driver_unit
);
629 cd
->dlt
= i4bisppp_ret_linktab(cd
->driver_unit
);
635 cd
->dlt
= ing_ret_linktab(cd
->driver_unit
);
644 if(cd
->dlt
== NULL
|| cd
->ilt
== NULL
)
647 if(t
>= 0 && t
< CTRL_NUMTYPES
&& ctrl_types
[t
].set_linktab
!= NULL
)
649 ctrl_types
[t
].set_linktab(
650 ctrl_desc
[cd
->controller
].unit
,
659 rbch_set_linktab(cd
->driver_unit
, cd
->ilt
);
665 tel_set_linktab(cd
->driver_unit
, cd
->ilt
);
671 ipr_set_linktab(cd
->driver_unit
, cd
->ilt
);
677 i4bisppp_set_linktab(cd
->driver_unit
, cd
->ilt
);
683 ing_set_linktab(cd
->driver_unit
, cd
->ilt
);
692 /* activate B channel */
694 (*cd
->ilt
->bch_config
)(cd
->ilt
->unit
, cd
->ilt
->channel
, cd
->bprot
, 1);
699 /*---------------------------------------------------------------------------*
700 * unlink a driver(unit) from a B-channel(controller,unit,channel)
701 *---------------------------------------------------------------------------*/
703 i4b_unlink_bchandrvr(call_desc_t
*cd
)
705 int t
= ctrl_desc
[cd
->controller
].ctrl_type
;
707 if(t
< 0 || t
>= CTRL_NUMTYPES
|| ctrl_types
[t
].get_linktab
== NULL
)
714 cd
->ilt
= ctrl_types
[t
].get_linktab(
715 ctrl_desc
[cd
->controller
].unit
,
719 /* deactivate B channel */
721 (*cd
->ilt
->bch_config
)(cd
->ilt
->unit
, cd
->ilt
->channel
, cd
->bprot
, 0);
724 /*---------------------------------------------------------------------------
726 How shorthold mode works for OUTGOING connections
727 =================================================
729 |<---- unchecked-window ------->|<-checkwindow->|<-safetywindow>|
731 idletime_state: IST_NONCHK IST_CHECK IST_SAFE
734 time>>+-------------------------------+---------------+---------------+-...
736 | |<--idle_time-->|<--earlyhup--->|
737 |<-----------------------unitlen------------------------------->|
740 unitlen - specifies the time a charging unit lasts
741 idle_time - specifies the thime the line must be idle at the
742 end of the unit to be elected for hangup
743 earlyhup - is the beginning of a timing safety zone before the
744 next charging unit starts
746 The algorithm works as follows: lets assume the unitlen is 100
747 secons, idle_time is 40 seconds and earlyhup is 10 seconds.
748 The line then must be idle 50 seconds after the begin of the
749 current unit and it must then be quiet for 40 seconds. if it
750 has been quiet for this 40 seconds, the line is closed 10
751 seconds before the next charging unit starts. In case there was
752 any traffic within the idle_time, the line is not closed.
753 It does not matter whether there was any traffic between second
754 0 and second 50 or not.
757 How shorthold mode works for INCOMING connections
758 =================================================
760 it is just possible to specify a maximum idle time for incoming
761 connections, after this time of no activity on the line the line
764 ---------------------------------------------------------------------------*/
767 i4b_get_idletime(call_desc_t
*cd
)
769 switch (cd
->driver
) {
772 return i4bisppp_idletime(cd
->driver_unit
);
776 return cd
->last_active_time
;
780 /*---------------------------------------------------------------------------*
781 * B channel idle check timeout setup
782 *---------------------------------------------------------------------------*/
784 i4b_l4_setup_timeout(call_desc_t
*cd
)
786 NDBGL4(L4_TIMO
, "%ld: direction %d, shorthold algorithm %d",
787 (long)SECOND
, cd
->dir
, cd
->shorthold_data
.shorthold_algorithm
);
789 cd
->timeout_active
= 0;
790 cd
->idletime_state
= IST_IDLE
;
792 if((cd
->dir
== DIR_INCOMING
) && (cd
->max_idle_time
> 0))
794 /* incoming call: simple max idletime check */
796 callout_reset(&cd
->idle_timeout
, hz
/ 2,
797 (void *)i4b_idle_check
, cd
);
798 cd
->timeout_active
= 1;
799 NDBGL4(L4_TIMO
, "%ld: incoming-call, setup max_idle_time to %ld", (long)SECOND
, (long)cd
->max_idle_time
);
801 else if((cd
->dir
== DIR_OUTGOING
) && (cd
->shorthold_data
.idle_time
> 0))
803 switch( cd
->shorthold_data
.shorthold_algorithm
)
805 default: /* fall into the old fix algorithm */
807 i4b_l4_setup_timeout_fix_unit( cd
);
811 i4b_l4_setup_timeout_var_unit( cd
);
817 NDBGL4(L4_TIMO
, "no idle_timeout configured");
821 /*---------------------------------------------------------------------------*
822 * fixed unit algorithm B channel idle check timeout setup
823 *---------------------------------------------------------------------------*/
825 i4b_l4_setup_timeout_fix_unit(call_desc_t
*cd
)
829 if((cd
->shorthold_data
.idle_time
> 0) && (cd
->shorthold_data
.unitlen_time
== 0))
831 /* outgoing call: simple max idletime check */
833 callout_reset(&cd
->idle_timeout
, hz
/ 2,
834 (void *)i4b_idle_check
, cd
);
835 cd
->timeout_active
= 1;
836 NDBGL4(L4_TIMO
, "%ld: outgoing-call, setup idle_time to %ld",
837 (long)SECOND
, (long)cd
->shorthold_data
.idle_time
);
839 else if((cd
->shorthold_data
.unitlen_time
> 0) && (cd
->shorthold_data
.unitlen_time
> (cd
->shorthold_data
.idle_time
+ cd
->shorthold_data
.earlyhup_time
)))
841 /* outgoing call: full shorthold mode check */
843 callout_reset(&cd
->idle_timeout
,
844 hz
* (cd
->shorthold_data
.unitlen_time
-
845 (cd
->shorthold_data
.idle_time
+
846 cd
->shorthold_data
.earlyhup_time
)),
847 (void *)i4b_idle_check
, cd
);
848 cd
->timeout_active
= 1;
849 cd
->idletime_state
= IST_NONCHK
;
850 NDBGL4(L4_TIMO
, "%ld: outgoing-call, start %ld sec nocheck window",
851 (long)SECOND
, (long)(cd
->shorthold_data
.unitlen_time
- (cd
->shorthold_data
.idle_time
+ cd
->shorthold_data
.earlyhup_time
)));
853 if(cd
->aocd_flag
== 0)
855 cd
->units_type
= CHARGE_CALC
;
857 i4b_l4_charging_ind(cd
);
862 /* parms somehow got wrong .. */
864 NDBGL4(L4_ERR
, "%ld: ERROR: idletime[%ld]+earlyhup[%ld] > unitlength[%ld]!",
865 (long)SECOND
, (long)cd
->shorthold_data
.idle_time
, (long)cd
->shorthold_data
.earlyhup_time
, (long)cd
->shorthold_data
.unitlen_time
);
869 /*---------------------------------------------------------------------------*
870 * variable unit algorithm B channel idle check timeout setup
871 *---------------------------------------------------------------------------*/
873 i4b_l4_setup_timeout_var_unit(call_desc_t
*cd
)
875 /* outgoing call: variable unit idletime check */
878 * start checking for an idle connect one second before the end of the unit.
879 * The one second takes into account of rounding due to the driver only
880 * using the seconds and not the uSeconds of the current time
882 cd
->idletime_state
= IST_CHECK
; /* move directly to the checking state */
884 callout_reset(&cd
->idle_timeout
,
885 hz
* (cd
->shorthold_data
.unitlen_time
- 1),
886 (void *)i4b_idle_check
, cd
);
887 cd
->timeout_active
= 1;
888 NDBGL4(L4_TIMO
, "%ld: outgoing-call, var idle time - setup to %ld",
889 (long)SECOND
, (long)cd
->shorthold_data
.unitlen_time
);
893 /*---------------------------------------------------------------------------*
894 * B channel idle check timeout function
895 *---------------------------------------------------------------------------*/
897 i4b_idle_check(call_desc_t
*cd
)
899 if(cd
->cdid
== CDID_UNUSED
)
906 if(cd
->timeout_active
== 0)
908 NDBGL4(L4_ERR
, "ERROR: timeout_active == 0 !!!");
912 cd
->timeout_active
= 0;
915 /* incoming connections, simple idletime check */
917 if(cd
->dir
== DIR_INCOMING
)
919 if((i4b_get_idletime(cd
) + cd
->max_idle_time
) <= SECOND
)
921 NDBGL4(L4_TIMO
, "%ld: incoming-call, line idle timeout, disconnecting!", (long)SECOND
);
922 (*ctrl_desc
[cd
->controller
].N_DISCONNECT_REQUEST
)(cd
->cdid
,
923 (CAUSET_I4B
<< 8) | CAUSE_I4B_NORMAL
);
924 i4b_l4_idle_timeout_ind(cd
);
928 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
);
930 callout_reset(&cd
->idle_timeout
, hz
/ 2,
931 (void *)i4b_idle_check
, cd
);
932 cd
->timeout_active
= 1;
936 /* outgoing connections */
938 else if(cd
->dir
== DIR_OUTGOING
)
940 switch( cd
->shorthold_data
.shorthold_algorithm
)
943 i4b_idle_check_fix_unit( cd
);
946 i4b_idle_check_var_unit( cd
);
949 NDBGL4(L4_TIMO
, "%ld: bad value for shorthold_algorithm of %d",
950 (long)SECOND
, cd
->shorthold_data
.shorthold_algorithm
);
951 i4b_idle_check_fix_unit( cd
);
958 /*---------------------------------------------------------------------------*
959 * fixed unit algorithm B channel idle check timeout function
960 *---------------------------------------------------------------------------*/
962 i4b_idle_check_fix_unit(call_desc_t
*cd
)
965 /* simple idletime calculation */
967 if((cd
->shorthold_data
.idle_time
> 0) && (cd
->shorthold_data
.unitlen_time
== 0))
969 if((i4b_get_idletime(cd
) + cd
->shorthold_data
.idle_time
) <= SECOND
)
971 NDBGL4(L4_TIMO
, "%ld: outgoing-call-st, idle timeout, disconnecting!", (long)SECOND
);
972 (*ctrl_desc
[cd
->controller
].N_DISCONNECT_REQUEST
)(cd
->cdid
, (CAUSET_I4B
<< 8) | CAUSE_I4B_NORMAL
);
973 i4b_l4_idle_timeout_ind(cd
);
977 NDBGL4(L4_TIMO
, "%ld: outgoing-call-st, activity, last_active=%ld, max_idle=%ld",
978 (long)SECOND
, (long)i4b_get_idletime(cd
), (long)cd
->shorthold_data
.idle_time
);
979 callout_reset(&cd
->idle_timeout
, hz
/ 2,
980 (void *)i4b_idle_check
, cd
);
981 cd
->timeout_active
= 1;
985 /* full shorthold mode calculation */
987 else if((cd
->shorthold_data
.unitlen_time
> 0)
988 && (cd
->shorthold_data
.unitlen_time
> (cd
->shorthold_data
.idle_time
+ cd
->shorthold_data
.earlyhup_time
)))
990 switch(cd
->idletime_state
)
993 case IST_NONCHK
: /* end of non-check time */
995 callout_reset(&cd
->idle_timeout
,
996 hz
*(cd
->shorthold_data
.idle_time
),
997 (void *)i4b_idle_check
, cd
);
998 cd
->idletimechk_start
= SECOND
;
999 cd
->idletime_state
= IST_CHECK
;
1000 cd
->timeout_active
= 1;
1001 NDBGL4(L4_TIMO
, "%ld: outgoing-call, idletime check window reached!", (long)SECOND
);
1004 case IST_CHECK
: /* end of idletime chk */
1005 if((i4b_get_idletime(cd
) > cd
->idletimechk_start
) &&
1006 (i4b_get_idletime(cd
) <= SECOND
))
1007 { /* activity detected */
1008 callout_reset(&cd
->idle_timeout
,
1009 hz
*(cd
->shorthold_data
.earlyhup_time
),
1010 (void *)i4b_idle_check
, cd
);
1011 cd
->timeout_active
= 1;
1012 cd
->idletime_state
= IST_SAFE
;
1013 NDBGL4(L4_TIMO
, "%ld: outgoing-call, activity at %ld, wait earlyhup-end", (long)SECOND
, (long)i4b_get_idletime(cd
));
1016 { /* no activity, hangup */
1017 NDBGL4(L4_TIMO
, "%ld: outgoing-call, idle timeout, last activity at %ld", (long)SECOND
, (long)i4b_get_idletime(cd
));
1018 (*ctrl_desc
[cd
->controller
].N_DISCONNECT_REQUEST
)(cd
->cdid
, (CAUSET_I4B
<< 8) | CAUSE_I4B_NORMAL
);
1019 i4b_l4_idle_timeout_ind(cd
);
1020 cd
->idletime_state
= IST_IDLE
;
1024 case IST_SAFE
: /* end of earlyhup time */
1026 callout_reset(&cd
->idle_timeout
,
1027 hz
*(cd
->shorthold_data
.unitlen_time
-
1028 (cd
->shorthold_data
.idle_time
+
1029 cd
->shorthold_data
.earlyhup_time
)),
1030 (void *)i4b_idle_check
, cd
);
1031 cd
->timeout_active
= 1;
1032 cd
->idletime_state
= IST_NONCHK
;
1034 if(cd
->aocd_flag
== 0)
1036 cd
->units_type
= CHARGE_CALC
;
1038 i4b_l4_charging_ind(cd
);
1041 NDBGL4(L4_TIMO
, "%ld: outgoing-call, earlyhup end, wait for idletime start", (long)SECOND
);
1045 NDBGL4(L4_ERR
, "outgoing-call: invalid idletime_state value!");
1046 cd
->idletime_state
= IST_IDLE
;
1052 /*---------------------------------------------------------------------------*
1053 * variable unit algorithm B channel idle check timeout function
1054 *---------------------------------------------------------------------------*/
1056 i4b_idle_check_var_unit(call_desc_t
*cd
)
1058 switch(cd
->idletime_state
)
1061 /* see if there has been any activity within the last idle_time seconds */
1063 if( i4b_get_idletime(cd
) > (SECOND
- cd
->shorthold_data
.idle_time
))
1064 { /* activity detected */
1065 /* check again in one second */
1066 callout_reset(&cd
->idle_timeout
, hz
,
1067 (void *)i4b_idle_check
, cd
);
1068 cd
->timeout_active
= 1;
1069 cd
->idletime_state
= IST_CHECK
;
1070 NDBGL4(L4_TIMO
, "%ld: outgoing-call, var idle timeout - activity at %ld, continuing", (long)SECOND
, (long)i4b_get_idletime(cd
));
1073 { /* no activity, hangup */
1074 NDBGL4(L4_TIMO
, "%ld: outgoing-call, var idle timeout - last activity at %ld", (long)SECOND
, (long)i4b_get_idletime(cd
));
1075 (*ctrl_desc
[cd
->controller
].N_DISCONNECT_REQUEST
)(cd
->cdid
, (CAUSET_I4B
<< 8) | CAUSE_I4B_NORMAL
);
1076 i4b_l4_idle_timeout_ind(cd
);
1077 cd
->idletime_state
= IST_IDLE
;
1082 NDBGL4(L4_ERR
, "outgoing-call: var idle timeout invalid idletime_state value!");
1083 cd
->idletime_state
= IST_IDLE
;
1088 #endif /* NI4B > 0 */