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 daemon - misc support routines
28 * ----------------------------------
30 * $FreeBSD: src/usr.sbin/i4b/isdnd/support.c,v 1.6.2.2 2001/12/16 15:13:38 hm Exp $
31 * $DragonFly: src/usr.sbin/i4b/isdnd/support.c,v 1.2 2003/06/17 04:29:54 dillon Exp $
33 * last edit-date: [Thu May 3 17:15:00 2001]
35 *---------------------------------------------------------------------------*/
39 static int isvalidtime(cfg_entry_t
*cep
);
41 /*---------------------------------------------------------------------------*
42 * find an active entry by driver type and driver unit
43 *---------------------------------------------------------------------------*/
45 find_active_entry_by_driver(int drivertype
, int driverunit
)
47 cfg_entry_t
*cep
= NULL
;
50 for(i
=0; i
< nentries
; i
++)
52 cep
= &cfg_entry_tab
[i
]; /* ptr to config entry */
54 if(!((cep
->usrdevicename
== drivertype
) &&
55 (cep
->usrdeviceunit
== driverunit
)))
60 /* check time interval */
62 if(isvalidtime(cep
) == 0)
64 DBGL(DL_VALID
, (log(LL_DBG
, "find_active_entry_by_driver: entry %d, time not valid!", i
)));
70 if(cep
->cdid
== CDID_UNUSED
)
72 DBGL(DL_MSG
, (log(LL_DBG
, "find_active_entry_by_driver: entry %d [%s%d], cdid=CDID_UNUSED !",
73 i
, bdrivername(drivertype
), driverunit
)));
76 else if(cep
->cdid
== CDID_RESERVED
)
78 DBGL(DL_MSG
, (log(LL_DBG
, "find_active_entry_by_driver: entry %d [%s%d], cdid=CDID_RESERVED!",
79 i
, bdrivername(drivertype
), driverunit
)));
87 /*---------------------------------------------------------------------------*
88 * find entry by drivertype and driverunit and setup for dialing out
89 *---------------------------------------------------------------------------*/
91 find_by_device_for_dialout(int drivertype
, int driverunit
)
93 cfg_entry_t
*cep
= NULL
;
96 for(i
=0; i
< nentries
; i
++)
98 cep
= &cfg_entry_tab
[i
]; /* ptr to config entry */
100 /* compare driver type and unit */
102 if(!((cep
->usrdevicename
== drivertype
) &&
103 (cep
->usrdeviceunit
== driverunit
)))
108 /* check time interval */
110 if(isvalidtime(cep
) == 0)
112 DBGL(DL_MSG
, (log(LL_DBG
, "find_by_device_for_dialout: entry %d, time not valid!", i
)));
116 /* found, check if already reserved */
118 if(cep
->cdid
== CDID_RESERVED
)
120 DBGL(DL_MSG
, (log(LL_DBG
, "find_by_device_for_dialout: entry %d, cdid reserved!", i
)));
124 /* check if this entry is already in use ? */
126 if(cep
->cdid
!= CDID_UNUSED
)
128 DBGL(DL_MSG
, (log(LL_DBG
, "find_by_device_for_dialout: entry %d, cdid in use", i
)));
132 if((setup_dialout(cep
)) == GOOD
)
134 /* found an entry to be used for calling out */
136 DBGL(DL_MSG
, (log(LL_DBG
, "find_by_device_for_dialout: found entry %d!", i
)));
141 DBGL(DL_MSG
, (log(LL_DBG
, "find_by_device_for_dialout: entry %d, setup_dialout() failed!", i
)));
146 DBGL(DL_MSG
, (log(LL_DBG
, "find_by_device_for_dialout: no entry found!")));
150 /*---------------------------------------------------------------------------*
151 * find entry by drivertype and driverunit and setup for dialing out
152 *---------------------------------------------------------------------------*/
154 find_by_device_for_dialoutnumber(int drivertype
, int driverunit
, int cmdlen
, char *cmd
)
156 cfg_entry_t
*cep
= NULL
;
159 for(i
=0; i
< nentries
; i
++)
161 cep
= &cfg_entry_tab
[i
]; /* ptr to config entry */
163 /* compare driver type and unit */
165 if(!((cep
->usrdevicename
== drivertype
) &&
166 (cep
->usrdeviceunit
== driverunit
)))
171 /* check time interval */
173 if(isvalidtime(cep
) == 0)
175 DBGL(DL_MSG
, (log(LL_DBG
, "find_by_device_for_dialoutnumber: entry %d, time not valid!", i
)));
179 /* found, check if already reserved */
181 if(cep
->cdid
== CDID_RESERVED
)
183 DBGL(DL_MSG
, (log(LL_DBG
, "find_by_device_for_dialoutnumber: entry %d, cdid reserved!", i
)));
187 /* check if this entry is already in use ? */
189 if(cep
->cdid
!= CDID_UNUSED
)
191 DBGL(DL_MSG
, (log(LL_DBG
, "find_by_device_for_dialoutnumber: entry %d, cdid in use", i
)));
195 cep
->keypad
[0] = '\0';
197 /* check number and copy to cep->remote_numbers[] */
199 for(j
= 0; j
< cmdlen
; j
++)
201 if(!(isdigit(*(cmd
+j
))))
203 DBGL(DL_MSG
, (log(LL_DBG
, "find_by_device_for_dialoutnumber: entry %d, dial string contains non-digit at pos %d", i
, j
)));
206 /* fill in number to dial */
207 cep
->remote_numbers
[0].number
[j
] = *(cmd
+j
);
209 cep
->remote_numbers
[0].number
[j
] = '\0';
210 cep
->remote_numbers_count
= 1;
212 if((setup_dialout(cep
)) == GOOD
)
214 /* found an entry to be used for calling out */
216 DBGL(DL_MSG
, (log(LL_DBG
, "find_by_device_for_dialoutnumber: found entry %d!", i
)));
221 DBGL(DL_MSG
, (log(LL_DBG
, "find_by_device_for_dialoutnumber: entry %d, setup_dialout() failed!", i
)));
226 DBGL(DL_MSG
, (log(LL_DBG
, "find_by_device_for_dialoutnumber: no entry found!")));
230 /*---------------------------------------------------------------------------*
231 * find entry by drivertype and driverunit and setup for send keypad
232 *---------------------------------------------------------------------------*/
234 find_by_device_for_keypad(int drivertype
, int driverunit
, int cmdlen
, char *cmd
)
236 cfg_entry_t
*cep
= NULL
;
239 for(i
=0; i
< nentries
; i
++)
241 cep
= &cfg_entry_tab
[i
]; /* ptr to config entry */
243 /* compare driver type and unit */
245 if(!((cep
->usrdevicename
== drivertype
) &&
246 (cep
->usrdeviceunit
== driverunit
)))
251 /* check time interval */
253 if(isvalidtime(cep
) == 0)
255 DBGL(DL_MSG
, (log(LL_DBG
, "find_by_device_for_keypad: entry %d, time not valid!", i
)));
259 /* found, check if already reserved */
261 if(cep
->cdid
== CDID_RESERVED
)
263 DBGL(DL_MSG
, (log(LL_DBG
, "find_by_device_for_keypad: entry %d, cdid reserved!", i
)));
267 /* check if this entry is already in use ? */
269 if(cep
->cdid
!= CDID_UNUSED
)
271 DBGL(DL_MSG
, (log(LL_DBG
, "find_by_device_for_keypad: entry %d, cdid in use", i
)));
275 cep
->remote_numbers
[0].number
[0] = '\0';
276 cep
->remote_numbers_count
= 0;
277 cep
->remote_phone_dialout
[0] = '\0';
279 bzero(cep
->keypad
, KEYPAD_MAX
);
280 strncpy(cep
->keypad
, cmd
, cmdlen
);
282 DBGL(DL_MSG
, (log(LL_DBG
, "find_by_device_for_keypad: entry %d, keypad string is %s", i
, cep
->keypad
)));
284 if((setup_dialout(cep
)) == GOOD
)
286 /* found an entry to be used for calling out */
288 DBGL(DL_MSG
, (log(LL_DBG
, "find_by_device_for_keypad: found entry %d!", i
)));
293 DBGL(DL_MSG
, (log(LL_DBG
, "find_by_device_for_keypad: entry %d, setup_dialout() failed!", i
)));
298 DBGL(DL_MSG
, (log(LL_DBG
, "find_by_device_for_keypad: no entry found!")));
302 /*---------------------------------------------------------------------------*
303 * find entry by drivertype and driverunit and setup for dialing out
304 *---------------------------------------------------------------------------*/
306 setup_dialout(cfg_entry_t
*cep
)
310 /* check controller operational */
312 if((get_controller_state(cep
->isdncontroller
)) != CTRL_UP
)
314 DBGL(DL_MSG
, (log(LL_DBG
, "setup_dialout: entry %s, controller is down", cep
->name
)));
318 cep
->isdncontrollerused
= cep
->isdncontroller
;
320 /* check channel available */
322 switch(cep
->isdnchannel
)
325 for (i
= 0; i
< isdn_ctrl_tab
[cep
->isdncontroller
].nbch
; i
++)
327 if(ret_channel_state(cep
->isdncontroller
, i
) == CHAN_IDLE
)
331 if (i
== isdn_ctrl_tab
[cep
->isdncontroller
].nbch
)
333 DBGL(DL_MSG
, (log(LL_DBG
, "setup_dialout: entry %s, no channel free", cep
->name
)));
336 cep
->isdnchannelused
= CHAN_ANY
;
340 if((ret_channel_state(cep
->isdncontroller
, cep
->isdnchannel
)) != CHAN_IDLE
)
342 DBGL(DL_MSG
, (log(LL_DBG
, "setup_dialout: entry %s, channel not free", cep
->name
)));
345 cep
->isdnchannelused
= cep
->isdnchannel
;
349 DBGL(DL_MSG
, (log(LL_DBG
, "setup_dialout: entry %s ok!", cep
->name
)));
351 /* preset disconnect cause */
353 SET_CAUSE_TYPE(cep
->disc_cause
, CAUSET_I4B
);
354 SET_CAUSE_VAL(cep
->disc_cause
, CAUSE_I4B_NORMAL
);
359 /*---------------------------------------------------------------------------*
360 * find entry by drivertype and driverunit
361 *---------------------------------------------------------------------------*/
363 get_cep_by_driver(int drivertype
, int driverunit
)
365 cfg_entry_t
*cep
= NULL
;
368 for(i
=0; i
< nentries
; i
++)
370 cep
= &cfg_entry_tab
[i
]; /* ptr to config entry */
372 if(!((cep
->usrdevicename
== drivertype
) &&
373 (cep
->usrdeviceunit
== driverunit
)))
378 /* check time interval */
380 if(isvalidtime(cep
) == 0)
382 DBGL(DL_MSG
, (log(LL_DBG
, "get_cep_by_driver: entry %d, time not valid!", i
)));
386 DBGL(DL_MSG
, (log(LL_DBG
, "get_cep_by_driver: found entry %d!", i
)));
392 /*---------------------------------------------------------------------------*
393 * find a matching entry for an incoming call
395 * - not found/no match: log output with LL_CHD and return NULL
396 * - found/match: make entry in free cep, return address
397 *---------------------------------------------------------------------------*/
399 find_matching_entry_incoming(msg_connect_ind_t
*mp
)
401 cfg_entry_t
*cep
= NULL
;
404 /* check for CW (call waiting) early */
406 if(mp
->channel
== CHAN_NO
)
410 char *src_tela
= "ERROR-src_tela";
411 char *dst_tela
= "ERROR-dst_tela";
413 src_tela
= get_alias(mp
->src_telno
);
414 dst_tela
= get_alias(mp
->dst_telno
);
416 log(LL_CHD
, "%05d <unknown> CW from %s to %s (no channel free)",
417 mp
->header
.cdid
, src_tela
, dst_tela
);
421 log(LL_CHD
, "%05d <unknown> call waiting from %s to %s (no channel free)",
422 mp
->header
.cdid
, mp
->src_telno
, mp
->dst_telno
);
427 for(i
=0; i
< nentries
; i
++)
430 cep
= &cfg_entry_tab
[i
]; /* ptr to config entry */
432 /* check my number */
434 if(strncmp(cep
->local_phone_incoming
, mp
->dst_telno
, strlen(cep
->local_phone_incoming
)))
436 DBGL(DL_MSG
, (log(LL_DBG
, "find_matching_entry_incoming: entry %d, myno %s != incomingno %s", i
,
437 cep
->local_phone_incoming
, mp
->dst_telno
)));
441 /* check all allowed remote number's for this entry */
443 for (n
= 0; n
< cep
->incoming_numbers_count
; n
++)
445 incoming_number_t
*in
= &cep
->remote_phone_incoming
[n
];
446 if(in
->number
[0] == '*')
448 if(strncmp(in
->number
, mp
->src_telno
, strlen(in
->number
)))
450 DBGL(DL_MSG
, (log(LL_DBG
, "find_matching_entry_incoming: entry %d, remno %s != incomingfromno %s", i
,
451 in
->number
, mp
->src_telno
)));
456 if (n
>= cep
->incoming_numbers_count
)
459 /* check b protocol */
461 if(cep
->b1protocol
!= mp
->bprot
)
463 DBGL(DL_MSG
, (log(LL_DBG
, "find_matching_entry_incoming: entry %d, bprot %d != incomingprot %d", i
,
464 cep
->b1protocol
, mp
->bprot
)));
468 /* is this entry currently in use ? */
470 if(cep
->cdid
!= CDID_UNUSED
)
472 if(cep
->cdid
== CDID_RESERVED
)
474 DBGL(DL_MSG
, (log(LL_DBG
, "find_matching_entry_incoming: entry %d, cdid is reserved", i
)));
476 else if (cep
->dialin_reaction
== REACT_ACCEPT
477 && cep
->dialouttype
== DIALOUT_CALLEDBACK
)
480 * We might consider doing this even if this is
481 * not a calledback config entry - BUT: there are
482 * severe race conditions and timinig problems
483 * ex. if both sides run I4B with no callback
484 * delay - both may shutdown the outgoing call
485 * and never be able to establish a connection.
486 * In the called-back case this should not happen.
488 DBGL(DL_MSG
, (log(LL_DBG
, "find_matching_entry_incoming: entry %d, incoming call for callback in progress (cdid %05d)", i
, cep
->cdid
)));
490 /* save the current call state, we're going to overwrite it with the
491 * new incoming state below... */
492 cep
->saved_call
.cdid
= cep
->cdid
;
493 cep
->saved_call
.controller
= cep
->isdncontrollerused
;
494 cep
->saved_call
.channel
= cep
->isdnchannelused
;
498 DBGL(DL_MSG
, (log(LL_DBG
, "find_matching_entry_incoming: entry %d, cdid in use", i
)));
499 continue; /* yes, next */
503 /* check controller value ok */
505 if(mp
->controller
> ncontroller
)
507 log(LL_CHD
, "%05d %s incoming call with invalid controller %d",
508 mp
->header
.cdid
, cep
->name
, mp
->controller
);
512 /* check controller marked up */
514 if((get_controller_state(mp
->controller
)) != CTRL_UP
)
516 log(LL_CHD
, "%05d %s incoming call, controller %d DOWN!",
517 mp
->header
.cdid
, cep
->name
, mp
->controller
);
522 * check controller he wants, check for any
523 * controller or specific controller
526 if( (mp
->controller
!= -1) &&
527 (mp
->controller
!= cep
->isdncontroller
) )
529 log(LL_CHD
, "%05d %s incoming call, controller %d != incoming %d",
530 mp
->header
.cdid
, cep
->name
,
531 cep
->isdncontroller
, mp
->controller
);
535 /* check channel he wants */
540 for (i
= 0; i
< isdn_ctrl_tab
[mp
->controller
].nbch
; i
++)
542 if(ret_channel_state(mp
->controller
, i
) == CHAN_IDLE
)
546 if (i
== isdn_ctrl_tab
[mp
->controller
].nbch
)
548 log(LL_CHD
, "%05d %s incoming call, no channel free!",
549 mp
->header
.cdid
, cep
->name
);
555 log(LL_CHD
, "%05d %s incoming call, call waiting (no channel available)!",
556 mp
->header
.cdid
, cep
->name
);
561 if((ret_channel_state(mp
->controller
, mp
->channel
)) != CHAN_IDLE
)
563 log(LL_CHD
, "%05d %s incoming call, channel B%d not free!",
564 mp
->header
.cdid
, cep
->name
, mp
->channel
+1);
570 /* check time interval */
572 if(isvalidtime(cep
) == 0)
574 DBGL(DL_MSG
, (log(LL_DBG
, "find_matching_entry_incoming: entry %d, time not valid!", i
)));
578 /* found a matching entry */
580 cep
->cdid
= mp
->header
.cdid
;
581 cep
->isdncontrollerused
= mp
->controller
;
582 cep
->isdnchannelused
= mp
->channel
;
583 /*XXX*/ cep
->disc_cause
= 0;
585 /* cp number to real one used */
587 strcpy(cep
->real_phone_incoming
, mp
->src_telno
);
589 /* copy display string */
591 strcpy(cep
->display
, mp
->display
);
593 /* entry currently down ? */
595 if(cep
->state
== ST_DOWN
)
597 msg_updown_ind_t mui
;
599 /* set interface up */
601 DBGL(DL_MSG
, (log(LL_DBG
, "find_matching_entry_incoming: entry %d, ", i
)));
603 mui
.driver
= cep
->usrdevicename
;
604 mui
.driver_unit
= cep
->usrdeviceunit
;
605 mui
.updown
= SOFT_ENA
;
607 if((ioctl(isdnfd
, I4B_UPDOWN_IND
, &mui
)) < 0)
609 log(LL_ERR
, "find_matching_entry_incoming: ioctl I4B_UPDOWN_IND failed: %s", strerror(errno
));
610 error_exit(1, "find_matching_entry_incoming: ioctl I4B_UPDOWN_IND failed: %s", strerror(errno
));
613 cep
->down_retry_count
= 0;
614 cep
->state
= ST_IDLE
;
621 char *src_tela
= "ERROR-src_tela";
622 char *dst_tela
= "ERROR-dst_tela";
624 src_tela
= get_alias(mp
->src_telno
);
625 dst_tela
= get_alias(mp
->dst_telno
);
627 log(LL_CHD
, "%05d Call from %s to %s",
628 mp
->header
.cdid
, src_tela
, dst_tela
);
632 log(LL_CHD
, "%05d <unknown> incoming call from %s to %s ctrl %d",
633 mp
->header
.cdid
, mp
->src_telno
, mp
->dst_telno
, mp
->controller
);
638 /*---------------------------------------------------------------------------*
639 * return address of ACTIVE config entry by controller and channel
640 *---------------------------------------------------------------------------*/
642 get_cep_by_cc(int ctrlr
, int chan
)
646 if((chan
< 0) || (chan
>= isdn_ctrl_tab
[ctrlr
].nbch
))
649 for(i
=0; i
< nentries
; i
++)
651 if((cfg_entry_tab
[i
].cdid
!= CDID_UNUSED
) &&
652 (cfg_entry_tab
[i
].cdid
!= CDID_RESERVED
) &&
653 (cfg_entry_tab
[i
].isdnchannelused
== chan
) &&
654 (cfg_entry_tab
[i
].isdncontrollerused
== ctrlr
) &&
655 ((ret_channel_state(ctrlr
, chan
)) == CHAN_RUN
))
657 return(&cfg_entry_tab
[i
]);
663 /*---------------------------------------------------------------------------*
664 * return address of config entry identified by cdid
665 *---------------------------------------------------------------------------*/
667 get_cep_by_cdid(int cdid
)
671 for(i
=0; i
< nentries
; i
++)
673 if(cfg_entry_tab
[i
].cdid
== cdid
674 || cfg_entry_tab
[i
].saved_call
.cdid
== cdid
)
675 return(&cfg_entry_tab
[i
]);
680 /*---------------------------------------------------------------------------*
681 * return b channel driver type name string
682 *---------------------------------------------------------------------------*/
684 bdrivername(int drivertype
)
686 static char *bdtab
[] = {
695 if(drivertype
>= BDRV_RBCH
&& drivertype
<= BDRV_ING
)
696 return(bdtab
[drivertype
]);
701 /*---------------------------------------------------------------------------*
702 * process AOCD charging messages
703 *---------------------------------------------------------------------------*/
705 handle_charge(cfg_entry_t
*cep
)
707 time_t now
= time(NULL
);
709 if(cep
->aoc_last
== 0) /* no last timestamp yet ? */
711 cep
->aoc_last
= now
; /* add time stamp */
713 else if(cep
->aoc_now
== 0) /* no current timestamp yet ? */
715 cep
->aoc_now
= now
; /* current timestamp */
719 cep
->aoc_last
= cep
->aoc_now
;
721 cep
->aoc_diff
= cep
->aoc_now
- cep
->aoc_last
;
722 cep
->aoc_valid
= AOC_VALID
;
730 #ifdef I4B_EXTERNAL_MONITOR
731 if(do_monitor
&& accepted
)
732 monitor_evnt_charge(cep
, cep
->charge
, 0);
735 if(cep
->aoc_valid
== AOC_VALID
)
737 if(cep
->aoc_diff
!= cep
->unitlength
)
739 DBGL(DL_MSG
, (log(LL_DBG
, "handle_charge: AOCD unit length updated %d -> %d secs", cep
->unitlength
, cep
->aoc_diff
)));
741 cep
->unitlength
= cep
->aoc_diff
;
748 DBGL(DL_MSG
, (log(LL_DBG
, "handle_charge: AOCD unit length still %d secs", cep
->unitlength
)));
754 /*---------------------------------------------------------------------------*
755 * update kernel idle_time, earlyhup_time and unitlen_time
756 *---------------------------------------------------------------------------*/
758 unitlen_chkupd(cfg_entry_t
*cep
)
760 msg_timeout_upd_t tupd
;
762 tupd
.cdid
= cep
->cdid
;
764 /* init the short hold data based on the shorthold algorithm type */
766 switch(cep
->shorthold_algorithm
)
769 tupd
.shorthold_data
.shorthold_algorithm
= SHA_FIXU
;
770 tupd
.shorthold_data
.unitlen_time
= cep
->unitlength
;
771 tupd
.shorthold_data
.idle_time
= cep
->idle_time_out
;
772 tupd
.shorthold_data
.earlyhup_time
= cep
->earlyhangup
;
776 tupd
.shorthold_data
.shorthold_algorithm
= SHA_VARU
;
777 tupd
.shorthold_data
.unitlen_time
= cep
->unitlength
;
778 tupd
.shorthold_data
.idle_time
= cep
->idle_time_out
;
779 tupd
.shorthold_data
.earlyhup_time
= 0;
782 log(LL_ERR
, "unitlen_chkupd bad shorthold_algorithm %d", cep
->shorthold_algorithm
);
787 if((ioctl(isdnfd
, I4B_TIMEOUT_UPD
, &tupd
)) < 0)
789 log(LL_ERR
, "ioctl I4B_TIMEOUT_UPD failed: %s", strerror(errno
));
790 error_exit(1, "ioctl I4B_TIMEOUT_UPD failed: %s", strerror(errno
));
794 /*--------------------------------------------------------------------------*
795 * this is intended to be called by do_exit and closes down all
796 * active connections before the daemon exits or is reconfigured.
797 *--------------------------------------------------------------------------*/
799 close_allactive(void)
802 cfg_entry_t
*cep
= NULL
;
806 for (i
= 0; i
< ncontroller
; i
++)
808 if((get_controller_state(i
)) != CTRL_UP
)
811 for (k
= 0; k
< isdn_ctrl_tab
[i
].nbch
; k
++)
813 if((ret_channel_state(i
, k
)) == CHAN_RUN
)
815 if((cep
= get_cep_by_cc(i
, k
)) != NULL
)
819 display_disconnect(cep
);
821 #ifdef I4B_EXTERNAL_MONITOR
822 monitor_evnt_disconnect(cep
);
824 next_state(cep
, EV_DRQ
);
833 log(LL_DMN
, "close_allactive: waiting for all connections terminated");
838 /*--------------------------------------------------------------------------*
839 * set an interface up
840 *--------------------------------------------------------------------------*/
842 if_up(cfg_entry_t
*cep
)
844 msg_updown_ind_t mui
;
846 /* set interface up */
848 DBGL(DL_MSG
, (log(LL_DBG
, "if_up: taking %s%d up", bdrivername(cep
->usrdevicename
), cep
->usrdeviceunit
)));
850 mui
.driver
= cep
->usrdevicename
;
851 mui
.driver_unit
= cep
->usrdeviceunit
;
852 mui
.updown
= SOFT_ENA
;
854 if((ioctl(isdnfd
, I4B_UPDOWN_IND
, &mui
)) < 0)
856 log(LL_ERR
, "if_up: ioctl I4B_UPDOWN_IND failed: %s", strerror(errno
));
857 error_exit(1, "if_up: ioctl I4B_UPDOWN_IND failed: %s", strerror(errno
));
859 cep
->down_retry_count
= 0;
863 display_updown(cep
, 1);
865 #ifdef I4B_EXTERNAL_MONITOR
866 monitor_evnt_updown(cep
, 1);
871 /*--------------------------------------------------------------------------*
872 * set an interface down
873 *--------------------------------------------------------------------------*/
875 if_down(cfg_entry_t
*cep
)
877 msg_updown_ind_t mui
;
879 /* set interface up */
881 DBGL(DL_MSG
, (log(LL_DBG
, "if_down: taking %s%d down", bdrivername(cep
->usrdevicename
), cep
->usrdeviceunit
)));
883 mui
.driver
= cep
->usrdevicename
;
884 mui
.driver_unit
= cep
->usrdeviceunit
;
885 mui
.updown
= SOFT_DIS
;
887 if((ioctl(isdnfd
, I4B_UPDOWN_IND
, &mui
)) < 0)
889 log(LL_ERR
, "if_down: ioctl I4B_UPDOWN_IND failed: %s", strerror(errno
));
890 error_exit(1, "if_down: ioctl I4B_UPDOWN_IND failed: %s", strerror(errno
));
892 cep
->went_down_time
= time(NULL
);
893 cep
->down_retry_count
= 0;
897 display_updown(cep
, 0);
899 #ifdef I4B_EXTERNAL_MONITOR
900 monitor_evnt_updown(cep
, 0);
905 /*--------------------------------------------------------------------------*
906 * send a dial response to (an interface in) the kernel
907 *--------------------------------------------------------------------------*/
909 dialresponse(cfg_entry_t
*cep
, int dstat
)
911 msg_dialout_resp_t mdr
;
913 static char *stattab
[] = {
917 "dialout not allowed"
920 if(dstat
< DSTAT_NONE
|| dstat
> DSTAT_INONLY
)
922 log(LL_ERR
, "dialresponse: dstat out of range %d!", dstat
);
926 mdr
.driver
= cep
->usrdevicename
;
927 mdr
.driver_unit
= cep
->usrdeviceunit
;
929 mdr
.cause
= cep
->disc_cause
;
931 if((ioctl(isdnfd
, I4B_DIALOUT_RESP
, &mdr
)) < 0)
933 log(LL_ERR
, "dialresponse: ioctl I4B_DIALOUT_RESP failed: %s", strerror(errno
));
934 error_exit(1, "dialresponse: ioctl I4B_DIALOUT_RESP failed: %s", strerror(errno
));
937 DBGL(DL_DRVR
, (log(LL_DBG
, "dialresponse: sent [%s]", stattab
[dstat
])));
940 /*--------------------------------------------------------------------------*
941 * screening/presentation indicator
942 *--------------------------------------------------------------------------*/
944 handle_scrprs(int cdid
, int scr
, int prs
, char *caller
)
946 /* screening indicator */
948 if(scr
< SCR_NONE
|| scr
> SCR_NET
)
950 log(LL_ERR
, "msg_connect_ind: invalid screening indicator value %d!", scr
);
954 static char *scrtab
[] = {
955 "no screening indicator",
956 "sreening user provided, not screened",
957 "screening user provided, verified & passed",
958 "screening user provided, verified & failed",
959 "screening network provided", };
963 log(LL_CHD
, "%05d %s %s", cdid
, caller
, scrtab
[scr
]);
967 DBGL(DL_MSG
, (log(LL_DBG
, "%s - %s", caller
, scrtab
[scr
])));
971 /* presentation indicator */
973 if(prs
< PRS_NONE
|| prs
> PRS_RESERVED
)
975 log(LL_ERR
, "msg_connect_ind: invalid presentation indicator value %d!", prs
);
979 static char *prstab
[] = {
980 "no presentation indicator",
981 "presentation allowed",
982 "presentation restricted",
983 "number not available due to interworking",
984 "reserved presentation value" };
988 log(LL_CHD
, "%05d %s %s", cdid
, caller
, prstab
[prs
]);
992 DBGL(DL_MSG
, (log(LL_DBG
, "%s - %s", caller
, prstab
[prs
])));
997 /*--------------------------------------------------------------------------*
998 * check if the time is valid for an entry
999 *--------------------------------------------------------------------------*/
1001 isvalidtime(cfg_entry_t
*cep
)
1014 if(isholiday(tp
->tm_mday
, (tp
->tm_mon
)+1, (tp
->tm_year
)+1900))
1016 DBGL(DL_VALID
, (log(LL_DBG
, "isvalidtime: holiday %d.%d.%d", tp
->tm_mday
, (tp
->tm_mon
)+1, (tp
->tm_year
)+1900)));
1021 if(cep
->day
& (1 << tp
->tm_wday
))
1023 DBGL(DL_VALID
, (log(LL_DBG
, "isvalidtime: day match")));
1030 if(cep
->fromhr
==0 && cep
->frommin
==0 && cep
->tohr
==0 && cep
->tomin
==0)
1032 DBGL(DL_VALID
, (log(LL_DBG
, "isvalidtime: no time specified, match!")));
1036 if(cep
->tohr
< cep
->fromhr
)
1040 if( (tp
->tm_hour
> cep
->fromhr
) ||
1041 (tp
->tm_hour
== cep
->fromhr
&& tp
->tm_min
> cep
->frommin
) )
1043 DBGL(DL_VALID
, (log(LL_DBG
, "isvalidtime: t<f-1, spec=%02d:%02d-%02d:%02d, curr=%02d:%02d, match!",
1044 cep
->fromhr
, cep
->frommin
,
1045 cep
->tohr
, cep
->tomin
,
1046 tp
->tm_hour
, tp
->tm_min
)));
1053 if( (tp
->tm_hour
< cep
->tohr
) ||
1054 (tp
->tm_hour
== cep
->tohr
&& tp
->tm_min
< cep
->tomin
) )
1056 DBGL(DL_VALID
, (log(LL_DBG
, "isvalidtime: t<f-2, spec=%02d:%02d-%02d:%02d, curr=%02d:%02d, match!",
1057 cep
->fromhr
, cep
->frommin
,
1058 cep
->tohr
, cep
->tomin
,
1059 tp
->tm_hour
, tp
->tm_min
)));
1064 else if(cep
->fromhr
== cep
->tohr
)
1066 if(tp
->tm_min
>= cep
->frommin
&& tp
->tm_min
< cep
->tomin
)
1068 DBGL(DL_VALID
, (log(LL_DBG
, "isvalidtime: f=t, spec=%02d:%02d-%02d:%02d, curr=%02d:%02d, match!",
1069 cep
->fromhr
, cep
->frommin
,
1070 cep
->tohr
, cep
->tomin
,
1071 tp
->tm_hour
, tp
->tm_min
)));
1078 if((tp
->tm_hour
> cep
->fromhr
&& tp
->tm_hour
< cep
->tohr
) ||
1079 (tp
->tm_hour
== cep
->fromhr
&& tp
->tm_min
>= cep
->frommin
) ||
1080 (tp
->tm_hour
== cep
->tohr
&& tp
->tm_min
< cep
->tomin
) )
1082 DBGL(DL_VALID
, (log(LL_DBG
, "isvalidtime: t>f, spec=%02d:%02d-%02d:%02d, curr=%02d:%02d, match!",
1083 cep
->fromhr
, cep
->frommin
,
1084 cep
->tohr
, cep
->tomin
,
1085 tp
->tm_hour
, tp
->tm_min
)));
1089 DBGL(DL_VALID
, (log(LL_DBG
, "isvalidtime: spec=%02d:%02d-%02d:%02d, curr=%02d:%02d, no match!",
1090 cep
->fromhr
, cep
->frommin
,
1091 cep
->tohr
, cep
->tomin
,
1092 tp
->tm_hour
, tp
->tm_min
)));