summaryrefslogtreecommitdiffstats
path: root/usr.sbin/i4b/isdnd/msghdl.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/i4b/isdnd/msghdl.c')
-rw-r--r--usr.sbin/i4b/isdnd/msghdl.c983
1 files changed, 983 insertions, 0 deletions
diff --git a/usr.sbin/i4b/isdnd/msghdl.c b/usr.sbin/i4b/isdnd/msghdl.c
new file mode 100644
index 0000000..61ac0ed
--- /dev/null
+++ b/usr.sbin/i4b/isdnd/msghdl.c
@@ -0,0 +1,983 @@
+/*
+ * Copyright (c) 1997, 1998 Hellmuth Michaelis. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *---------------------------------------------------------------------------
+ *
+ * i4b daemon - message from kernel handling routines
+ * --------------------------------------------------
+ *
+ * $Id: msghdl.c,v 1.54 1998/12/19 09:03:16 hm Exp $
+ *
+ * last edit-date: [Sat Dec 19 09:57:16 1998]
+ *
+ *---------------------------------------------------------------------------*/
+
+#include "isdnd.h"
+
+/*---------------------------------------------------------------------------*
+ * handle incoming CONNECT_IND (=SETUP) message
+ *---------------------------------------------------------------------------*/
+void
+msg_connect_ind(msg_connect_ind_t *mp)
+{
+ cfg_entry_t *cep;
+ char *src_tela = "ERROR-src_tela";
+ char *dst_tela = "ERROR-dst_tela";
+
+#define SRC (aliasing == 0 ? mp->src_telno : src_tela)
+#define DST (aliasing == 0 ? mp->dst_telno : dst_tela)
+
+ if((cep = find_matching_entry_incoming(mp)) == NULL)
+ {
+ /* log message generated in find_matching_entry_incoming() */
+ sendm_connect_resp(NULL, mp->header.cdid, SETUP_RESP_DNTCRE, 0);
+ return;
+ }
+
+ if(cep->cdid != CDID_UNUSED && cep->cdid != CDID_RESERVED)
+ {
+ /*
+ * This is an incoming call on a number we just dialed out.
+ * Stop our dial-out and accept the incoming call.
+ */
+ if(cep->saved_call.cdid != CDID_UNUSED &&
+ cep->saved_call.cdid != CDID_RESERVED)
+ {
+ int cdid;
+
+ /* disconnect old, not new */
+
+ cdid = cep->cdid;
+ cep->cdid = cep->saved_call.cdid;
+ sendm_disconnect_req(cep, (CAUSET_I4B << 8) | CAUSE_I4B_NORMAL);
+ cep->cdid = cdid;
+
+ /*
+ * Shortcut the state machine and mark this
+ * entry as free
+ */
+/* XXX */ cep->state = ST_IDLE; /* this is an invalid */
+ /* transition, */
+ /* so no next_state() */
+ /* we have to wait here for an incoming */
+ /* disconnect message !!! (-hm) */
+ }
+ }
+
+ if(aliasing)
+ {
+ src_tela = get_alias(mp->src_telno);
+ dst_tela = get_alias(mp->dst_telno);
+ }
+
+ if(cep->inout == DIR_OUTONLY)
+ {
+ log(LL_CHD, "%05d %s incoming call from %s to %s not allowed by configuration!",
+ mp->header.cdid, cep->name, SRC, DST);
+ sendm_connect_resp(NULL, mp->header.cdid, SETUP_RESP_DNTCRE, 0);
+ return;
+ }
+
+ cep->charge = 0;
+ cep->last_charge = 0;
+
+ switch(cep->dialin_reaction)
+ {
+ case REACT_ACCEPT:
+ log(LL_CHD, "%05d %s accepting: incoming call from %s to %s",
+ mp->header.cdid, cep->name, SRC, DST);
+ decr_free_channels(mp->controller);
+ next_state(cep, EV_MCI);
+ break;
+
+ case REACT_REJECT:
+ log(LL_CHD, "%05d %s rejecting: incoming call from %s to %s",
+ mp->header.cdid, cep->name, SRC, DST);
+ sendm_connect_resp(cep, mp->header.cdid, SETUP_RESP_REJECT,
+ (CAUSET_I4B << 8) | CAUSE_I4B_REJECT);
+ cep->cdid = CDID_UNUSED;
+ break;
+
+ case REACT_IGNORE:
+ log(LL_CHD, "%05d %s ignoring: incoming call from %s to %s",
+ mp->header.cdid, cep->name, SRC, DST);
+ sendm_connect_resp(NULL, mp->header.cdid, SETUP_RESP_DNTCRE, 0);
+ break;
+
+ case REACT_ANSWER:
+ decr_free_channels(mp->controller);
+ if(cep->alert)
+ {
+ if(mp->display)
+ {
+ log(LL_CHD, "%05d %s alerting: incoming call from %s to %s (%s)",
+ mp->header.cdid, cep->name, SRC, DST, mp->display);
+ }
+ else
+ {
+ log(LL_CHD, "%05d %s alerting: incoming call from %s to %s",
+ mp->header.cdid, cep->name, SRC, DST);
+ }
+ next_state(cep, EV_ALRT);
+ }
+ else
+ {
+ if(mp->display)
+ {
+ log(LL_CHD, "%05d %s answering: incoming call from %s to %s (%s)",
+ mp->header.cdid, cep->name, SRC, DST, mp->display);
+ }
+ else
+ {
+ log(LL_CHD, "%05d %s answering: incoming call from %s to %s",
+ mp->header.cdid, cep->name, SRC, DST);
+ }
+ next_state(cep, EV_MCI);
+ }
+ break;
+
+ case REACT_CALLBACK:
+#ifdef NOTDEF
+/*XXX reserve channel ??? */ decr_free_channels(mp->controller);
+#endif
+ if(cep->cdid == CDID_RESERVED)
+ {
+ log(LL_CHD, "%05d %s reserved: incoming call from %s to %s",
+ mp->header.cdid, cep->name, SRC, DST);
+ sendm_connect_resp(cep, mp->header.cdid, SETUP_RESP_REJECT,
+ (CAUSET_I4B << 8) | CAUSE_I4B_NORMAL);
+ /* no state change */
+ }
+ else
+ {
+ log(LL_CHD, "%05d %s callback: incoming call from %s to %s",
+ mp->header.cdid, cep->name, SRC, DST);
+ sendm_connect_resp(cep, mp->header.cdid, SETUP_RESP_REJECT,
+ (CAUSET_I4B << 8) | CAUSE_I4B_NORMAL);
+ cep->last_release_time = time(NULL);
+ cep->cdid = CDID_RESERVED;
+ next_state(cep, EV_CBRQ);
+ }
+ break;
+
+ default:
+ log(LL_WRN, "msg_connect_ind: unknown response type, tx SETUP_RESP_DNTCRE");
+ sendm_connect_resp(NULL, mp->header.cdid, SETUP_RESP_DNTCRE, 0);
+ break;
+ }
+#undef SRC
+#undef DST
+}
+
+/*---------------------------------------------------------------------------*
+ * handle incoming CONNECT_ACTIVE_IND message
+ *---------------------------------------------------------------------------*/
+void
+msg_connect_active_ind(msg_connect_active_ind_t *mp)
+{
+ cfg_entry_t *cep;
+
+ if((cep = get_cep_by_cdid(mp->header.cdid)) == NULL)
+ {
+ log(LL_WRN, "msg_connect_active_ind: cdid not found!");
+ return;
+ }
+
+ cep->isdncontrollerused = mp->controller;
+ cep->isdnchannelused = mp->channel;
+
+ cep->aoc_now = cep->connect_time = time(NULL);
+ cep->aoc_last = 0;
+ cep->aoc_diff = 0;
+ cep->aoc_valid = AOC_INVALID;
+
+ cep->local_disconnect = DISCON_REM;
+
+ cep->inbytes = INVALID;
+ cep->outbytes = INVALID;
+ cep->hangup = 0;
+
+ /* set the B-channel to active */
+
+ if((set_channel_busy(cep->isdncontrollerused, cep->isdnchannelused)) == ERROR)
+ log(LL_ERR, "msg_connect_active_ind: set_channel_busy failed!");
+
+ if(cep->direction == DIR_OUT)
+ {
+ log(LL_CHD, "%05d %s outgoing call active (ctl %d, ch %d)",
+ cep->cdid, cep->name,
+ cep->isdncontrollerused, cep->isdnchannelused);
+ }
+ else
+ {
+ log(LL_CHD, "%05d %s incoming call active (ctl %d, ch %d)",
+ cep->cdid, cep->name,
+ cep->isdncontrollerused, cep->isdnchannelused);
+ }
+
+#ifdef USE_CURSES
+ if(do_fullscreen)
+ display_connect(cep);
+#endif
+#ifdef I4B_EXTERNAL_MONITOR
+ if(do_monitor && accepted)
+ monitor_evnt_connect(cep);
+#endif
+
+ if(isdntime && (mp->datetime[0] != '\0'))
+ {
+ log(LL_DMN, "date/time from exchange = %s", mp->datetime);
+ }
+
+ next_state(cep, EV_MCAI);
+}
+
+/*---------------------------------------------------------------------------*
+ * handle incoming PROCEEDING_IND message
+ *---------------------------------------------------------------------------*/
+void
+msg_proceeding_ind(msg_proceeding_ind_t *mp)
+{
+ cfg_entry_t *cep;
+
+ if((cep = get_cep_by_cdid(mp->header.cdid)) == NULL)
+ {
+ log(LL_WRN, "msg_proceeding_ind: cdid not found!");
+ return;
+ }
+
+ cep->isdncontrollerused = mp->controller;
+ cep->isdnchannelused = mp->channel;
+
+ /* set the B-channels active */
+
+ if((set_channel_busy(cep->isdncontrollerused, cep->isdnchannelused)) == ERROR)
+ log(LL_ERR, "msg_proceeding_ind: set_channel_busy failed!");
+
+ log(LL_CHD, "%05d %s outgoing call proceeding (ctl %d, ch %d)",
+ cep->cdid, cep->name,
+ cep->isdncontrollerused, cep->isdnchannelused);
+}
+
+/*---------------------------------------------------------------------------*
+ * handle incoming ALERT_IND message
+ *---------------------------------------------------------------------------*/
+void
+msg_alert_ind(msg_alert_ind_t *mp)
+{
+ cfg_entry_t *cep;
+
+ if((cep = get_cep_by_cdid(mp->header.cdid)) == NULL)
+ {
+ log(LL_WRN, "msg_alert_ind: cdid not found!");
+ return;
+ }
+#ifdef NOTDEF
+ log(LL_CHD, "%05d %s incoming alert", cep->cdid, cep->name);
+#endif
+}
+
+/*---------------------------------------------------------------------------*
+ * handle incoming L12STAT_IND message
+ *---------------------------------------------------------------------------*/
+void
+msg_l12stat_ind(msg_l12stat_ind_t *ml)
+{
+#ifdef USE_CURSES
+ if(do_fullscreen)
+ display_l12stat(ml->controller, ml->layer, ml->state);
+#endif
+
+ DBGL(DL_CNST, (log(LL_DBG, "msg_l12stat_ind: unit %d, layer %d, state %d",
+ ml->controller, ml->layer, ml->state)));
+}
+
+/*---------------------------------------------------------------------------*
+ * handle incoming TEIASG_IND message
+ *---------------------------------------------------------------------------*/
+void
+msg_teiasg_ind(msg_teiasg_ind_t *mt)
+{
+#ifdef USE_CURSES
+ if(do_fullscreen)
+ display_tei(mt->controller, mt->tei);
+#endif
+
+ DBGL(DL_CNST, (log(LL_DBG, "msg_teiasg_ind: unit %d, tei = %d",
+ mt->controller, mt->tei)));
+}
+
+/*---------------------------------------------------------------------------*
+ * handle incoming L12STAT_IND message
+ *---------------------------------------------------------------------------*/
+void
+msg_pdeact_ind(msg_pdeact_ind_t *md)
+{
+ int i;
+ int ctrl = md->controller;
+ cfg_entry_t *cep;
+
+#ifdef USE_CURSES
+ if(do_fullscreen)
+ {
+ display_l12stat(ctrl, LAYER_ONE, LAYER_IDLE);
+ display_l12stat(ctrl, LAYER_TWO, LAYER_IDLE);
+ display_tei(ctrl, -1);
+ }
+#endif
+
+ DBGL(DL_CNST, (log(LL_DBG, "msg_pdeact_ind: unit %d, persistent deactivation", ctrl)));
+
+ for(i=0; i < nentries; i++)
+ {
+ if((cfg_entry_tab[i].cdid != CDID_UNUSED) &&
+ (cfg_entry_tab[i].isdncontrollerused == ctrl))
+ {
+ cep = &cfg_entry_tab[i];
+
+ if(cep->cdid == CDID_RESERVED)
+ {
+ cep->cdid = CDID_UNUSED;
+ continue;
+ }
+
+ cep->cdid = CDID_UNUSED;
+
+ cep->last_release_time = time(NULL);
+
+ SET_CAUSE_TYPE(cep->disc_cause, CAUSET_I4B);
+ SET_CAUSE_VAL(cep->disc_cause, CAUSE_I4B_L1ERROR);
+
+ if(cep->direction == DIR_OUT)
+ {
+ log(LL_CHD, "%05d %s outgoing call disconnected (local)",
+ cep->cdid, cep->name);
+ }
+ else
+ {
+ log(LL_CHD, "%05d %s incoming call disconnected (local)",
+ cep->cdid, cep->name);
+ }
+
+ log(LL_CHD, "%05d %s cause %s",
+ cep->cdid, cep->name, print_i4b_cause(cep->disc_cause));
+
+#ifdef USE_CURSES
+ if(do_fullscreen && (cep->connect_time > 0))
+ display_disconnect(cep);
+#endif
+
+#ifdef I4B_EXTERNAL_MONITOR
+ if(do_monitor && accepted)
+ monitor_evnt_disconnect(cep);
+#endif
+ if(cep->disconnectprog)
+ exec_connect_prog(cep, cep->disconnectprog, 1);
+
+ if(cep->connect_time > 0)
+ {
+ if(cep->direction == DIR_OUT)
+ {
+ log(LL_CHD, "%05d %s charging: %d units, %d seconds",
+ cep->cdid, cep->name, cep->charge,
+ (int)difftime(time(NULL), cep->connect_time));
+ }
+ else
+ {
+ log(LL_CHD, "%05d %s connected %d seconds",
+ cep->cdid, cep->name,
+ (int)difftime(time(NULL), cep->connect_time));
+ }
+
+ if((cep->inbytes != INVALID) && (cep->outbytes != INVALID))
+ {
+ if((cep->ioutbytes != cep->outbytes) ||
+ (cep->iinbytes != cep->inbytes))
+ {
+ log(LL_CHD, "%05d %s accounting: in %d, out %d (in %d, out %d)",
+ cep->cdid, cep->name,
+ cep->inbytes, cep->outbytes,
+ cep->iinbytes, cep->ioutbytes);
+ }
+ else
+ {
+ log(LL_CHD, "%05d %s accounting: in %d, out %d",
+ cep->cdid, cep->name,
+ cep->inbytes, cep->outbytes);
+ }
+ }
+ }
+
+ if(useacctfile && (cep->connect_time > 0))
+ {
+ int con_secs;
+ char logdatetime[41];
+ struct tm *tp;
+
+ con_secs = difftime(time(NULL), cep->connect_time);
+
+ tp = localtime(&cep->connect_time);
+
+ strftime(logdatetime,40,I4B_TIME_FORMAT,tp);
+
+ if(cep->inbytes != INVALID && cep->outbytes != INVALID)
+ {
+ fprintf(acctfp, "%s - %s %s %d (%d) (%d/%d)\n",
+ logdatetime, getlogdatetime(),
+ cep->name, cep->charge, con_secs,
+ cep->inbytes, cep->outbytes);
+ }
+ else
+ {
+ fprintf(acctfp, "%s - %s %s %d (%d)\n",
+ logdatetime, getlogdatetime(),
+ cep->name, cep->charge, con_secs);
+ }
+ }
+
+ /* set the B-channel inactive */
+
+ if((set_channel_idle(cep->isdncontrollerused, cep->isdnchannelused)) == ERROR)
+ log(LL_ERR, "msg_pdeact_ind: set_channel_idle failed!");
+
+ incr_free_channels(cep->isdncontrollerused);
+
+ cep->connect_time = 0;
+ }
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * handle incoming NEGCOMP_IND message
+ *---------------------------------------------------------------------------*/
+void
+msg_negcomplete_ind(msg_negcomplete_ind_t *mp)
+{
+ cfg_entry_t *cep;
+
+ if((cep = get_cep_by_cdid(mp->header.cdid)) == NULL)
+ {
+ log(LL_WRN, "msg_negcomp_ind: cdid not found");
+ return;
+ }
+
+ if(cep->connectprog)
+ exec_connect_prog(cep, cep->connectprog, 0);
+}
+
+/*---------------------------------------------------------------------------*
+ * handle incoming IFSTATE_CHANGED indication
+ *---------------------------------------------------------------------------*/
+void
+msg_ifstatechg_ind(msg_ifstatechg_ind_t *mp)
+{
+ cfg_entry_t *cep;
+ char *device;
+
+ if((cep = get_cep_by_cdid(mp->header.cdid)) == NULL)
+ {
+ log(LL_WRN, "msg_negcomp_ind: cdid not found");
+ return;
+ }
+
+ device = bdrivername(cep->usrdevicename);
+ log(LL_DBG, "%s%d: switched to state %d\n", device, cep->usrdeviceunit, mp->state);
+}
+
+/*---------------------------------------------------------------------------*
+ * handle incoming DISCONNECT_IND message
+ *---------------------------------------------------------------------------*/
+void
+msg_disconnect_ind(msg_disconnect_ind_t *mp)
+{
+ cfg_entry_t *cep;
+
+ if((cep = get_cep_by_cdid(mp->header.cdid)) == NULL)
+ {
+ log(LL_WRN, "msg_disconnect_ind: cdid not found");
+ return;
+ }
+
+ /* is this an aborted out-call prematurely called back? */
+ if (cep->saved_call.cdid == mp->header.cdid)
+ {
+ DBGL(DL_CNST, (log(LL_DBG, "aborted outcall %05d disconnected",
+ mp->header.cdid)));
+ cep->saved_call.cdid = CDID_UNUSED;
+
+ if((set_channel_idle(cep->saved_call.controller, cep->saved_call.channel)) == ERROR)
+ log(LL_ERR, "msg_disconnect_ind: set_channel_idle failed!");
+
+ incr_free_channels(cep->saved_call.controller);
+ return;
+ }
+
+ cep->last_release_time = time(NULL);
+ cep->disc_cause = mp->cause;
+
+ if(cep->direction == DIR_OUT)
+ {
+ log(LL_CHD, "%05d %s outgoing call disconnected %s",
+ cep->cdid, cep->name,
+ cep->local_disconnect == DISCON_LOC ?
+ "(local)" : "(remote)");
+ }
+ else
+ {
+ log(LL_CHD, "%05d %s incoming call disconnected %s",
+ cep->cdid, cep->name,
+ cep->local_disconnect == DISCON_LOC ?
+ "(local)" : "(remote)");
+ }
+
+ log(LL_CHD, "%05d %s cause %s",
+ cep->cdid, cep->name, print_i4b_cause(mp->cause));
+
+#ifdef USE_CURSES
+ if(do_fullscreen && (cep->connect_time > 0))
+ display_disconnect(cep);
+#endif
+
+#ifdef I4B_EXTERNAL_MONITOR
+ if(do_monitor && accepted)
+ monitor_evnt_disconnect(cep);
+#endif
+
+ if(cep->disconnectprog)
+ exec_connect_prog(cep, cep->disconnectprog, 1);
+
+ if(cep->connect_time > 0)
+ {
+ if(cep->direction == DIR_OUT)
+ {
+ log(LL_CHD, "%05d %s charging: %d units, %d seconds",
+ cep->cdid, cep->name, cep->charge,
+ (int)difftime(time(NULL), cep->connect_time));
+ }
+ else
+ {
+ log(LL_CHD, "%05d %s connected %d seconds",
+ cep->cdid, cep->name,
+ (int)difftime(time(NULL), cep->connect_time));
+ }
+
+ if((cep->inbytes != INVALID) && (cep->outbytes != INVALID))
+ {
+ if((cep->ioutbytes != cep->outbytes) ||
+ (cep->iinbytes != cep->inbytes))
+ {
+ log(LL_CHD, "%05d %s accounting: in %d, out %d (in %d, out %d)",
+ cep->cdid, cep->name,
+ cep->inbytes, cep->outbytes,
+ cep->iinbytes, cep->ioutbytes);
+ }
+ else
+ {
+ log(LL_CHD, "%05d %s accounting: in %d, out %d",
+ cep->cdid, cep->name,
+ cep->inbytes, cep->outbytes);
+ }
+ }
+ }
+
+ if(useacctfile && (cep->connect_time > 0))
+ {
+ int con_secs;
+ char logdatetime[41];
+ struct tm *tp;
+
+ con_secs = difftime(time(NULL), cep->connect_time);
+
+ tp = localtime(&cep->connect_time);
+
+ strftime(logdatetime,40,I4B_TIME_FORMAT,tp);
+
+ if(cep->inbytes != INVALID && cep->outbytes != INVALID)
+ {
+ fprintf(acctfp, "%s - %s %s %d (%d) (%d/%d)\n",
+ logdatetime, getlogdatetime(),
+ cep->name, cep->charge, con_secs,
+ cep->inbytes, cep->outbytes);
+ }
+ else
+ {
+ fprintf(acctfp, "%s - %s %s %d (%d)\n",
+ logdatetime, getlogdatetime(),
+ cep->name, cep->charge, con_secs);
+ }
+ }
+
+ /* set the B-channel inactive */
+
+ if((set_channel_idle(cep->isdncontrollerused, cep->isdnchannelused)) == ERROR)
+ log(LL_ERR, "msg_disconnect_ind: set_channel_idle failed!");
+
+ incr_free_channels(cep->isdncontrollerused);
+
+ cep->connect_time = 0;
+
+ next_state(cep, EV_MDI);
+}
+
+/*---------------------------------------------------------------------------*
+ * handle incoming DIALOUT message
+ *---------------------------------------------------------------------------*/
+void
+msg_dialout(msg_dialout_ind_t *mp)
+{
+ cfg_entry_t *cep;
+
+ DBGL(DL_DRVR, (log(LL_DBG, "msg_dialout: dial req from %s, unit %d", bdrivername(mp->driver), mp->driver_unit)));
+
+ if((cep = find_by_device_for_dialout(mp->driver, mp->driver_unit)) == NULL)
+ {
+ DBGL(DL_DRVR, (log(LL_DBG, "msg_dialout: config entry reserved or no match")));
+ return;
+ }
+
+ if(cep->inout == DIR_INONLY)
+ {
+ dialresponse(cep, DSTAT_INONLY);
+ return;
+ }
+
+ if((cep->cdid = get_cdid()) == 0)
+ {
+ DBGL(DL_DRVR, (log(LL_DBG, "msg_dialout: get_cdid() returned 0!")));
+ return;
+ }
+
+ cep->charge = 0;
+ cep->last_charge = 0;
+
+ next_state(cep, EV_MDO);
+}
+
+/*---------------------------------------------------------------------------*
+ * handle incoming DRVRDISC_REQ message
+ *---------------------------------------------------------------------------*/
+void
+msg_drvrdisc_req(msg_drvrdisc_req_t *mp)
+{
+ cfg_entry_t *cep;
+
+ DBGL(DL_DRVR, (log(LL_DBG, "msg_drvrdisc_req: req from %s, unit %d", bdrivername(mp->driver), mp->driver_unit)));
+
+ if((cep = get_cep_by_driver(mp->driver, mp->driver_unit)) == NULL)
+ {
+ DBGL(DL_DRVR, (log(LL_DBG, "msg_drvrdisc_req: config entry not found")));
+ return;
+ }
+ next_state(cep, EV_DRQ);
+}
+
+/*---------------------------------------------------------------------------*
+ * handle incoming ACCOUNTING message
+ *---------------------------------------------------------------------------*/
+void
+msg_accounting(msg_accounting_ind_t *mp)
+{
+ cfg_entry_t *cep;
+
+ if((cep = find_active_entry_by_driver(mp->driver, mp->driver_unit)) == NULL)
+ {
+ log(LL_WRN, "msg_accounting: no config entry found!");
+ return;
+ }
+
+ cep->inbytes = mp->inbytes;
+ cep->iinbytes = mp->iinbytes;
+ cep->outbytes = mp->outbytes;
+ cep->ioutbytes = mp->ioutbytes;
+ cep->inbps = mp->inbps;
+ cep->outbps = mp->outbps;
+
+ if(mp->accttype == ACCT_DURING)
+ {
+#ifdef USE_CURSES
+ if(do_fullscreen)
+ display_acct(cep);
+#endif
+#ifdef NOTDEF
+ else
+ DBGL(DL_DRVR, (log(LL_DBG, "msg_accounting: %s%d, ioutb=%d, iinb=%d, outb=%d, inb=%d, outbps=%d, inbps=%d",
+ bdrivername(mp->driver), mp->driver_unit,
+ mp->ioutbytes, mp->iinbytes,
+ mp->outbytes, mp->inbytes,
+ mp->outbps, mp->inbps)));
+#endif
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * handle incoming CHARGING message
+ *---------------------------------------------------------------------------*/
+void
+msg_charging_ind(msg_charging_ind_t *mp)
+{
+ static char *cttab[] = {
+ "invalid",
+ "AOCD",
+ "AOCE",
+ "estimated" };
+
+ cfg_entry_t *cep;
+
+ if((cep = get_cep_by_cdid(mp->header.cdid)) == NULL)
+ {
+ log(LL_WRN, "msg_charging_ind: cdid not found");
+ return;
+ }
+
+ if(mp->units_type < CHARGE_INVALID || mp->units_type > CHARGE_CALC)
+ {
+ log(LL_ERR, "msg_charging: units_type %d out of range!", mp->units_type);
+ do_exit(1);
+ }
+
+ DBGL(DL_DRVR, (log(LL_DBG, "msg_charging: %d unit(s) (%s)",
+ mp->units, cttab[mp->units_type])));
+
+ switch(mp->units_type)
+ {
+ case CHARGE_AOCD:
+ cep->charge = mp->units;
+
+ if((cep->unitlengthsrc == ULSRC_DYN) &&
+ (cep->charge != cep->last_charge))
+ {
+ cep->last_charge = cep->charge;
+ handle_charge(cep);
+ }
+ break;
+
+ case CHARGE_AOCE:
+ cep->charge = mp->units;
+ break;
+
+ case CHARGE_CALC:
+ cep->charge = mp->units;
+#ifdef USE_CURSES
+ if(do_fullscreen)
+ display_ccharge(cep, mp->units);
+#endif
+#ifdef I4B_EXTERNAL_MONITOR
+ if(do_monitor && accepted)
+ monitor_evnt_charge(cep, mp->units, 1);
+#endif
+ break;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * handle incoming IDLE_TIMEOUT_IND message
+ *---------------------------------------------------------------------------*/
+void
+msg_idle_timeout_ind(msg_idle_timeout_ind_t *mp)
+{
+ cfg_entry_t *cep;
+
+ if((cep = get_cep_by_cdid(mp->header.cdid)) == NULL)
+ {
+ log(LL_WRN, "msg_idle_timeout_ind: cdid not found!");
+ return;
+ }
+
+ cep->local_disconnect = DISCON_LOC;
+
+ DBGL(DL_DRVR, (log(LL_DBG, "msg_idle_timeout_ind: idletimeout, kernel sent disconnect!")));
+
+ check_and_kill(cep);
+}
+
+/*---------------------------------------------------------------------------*
+ * get a cdid from kernel
+ *---------------------------------------------------------------------------*/
+int
+get_cdid(void)
+{
+ msg_cdid_req_t mcr;
+
+ mcr.cdid = 0;
+
+ if((ioctl(isdnfd, I4B_CDID_REQ, &mcr)) < 0)
+ {
+ log(LL_ERR, "get_cdid: ioctl I4B_CDID_REQ failed: %s", strerror(errno));
+ do_exit(1);
+ }
+
+ return(mcr.cdid);
+}
+
+/*---------------------------------------------------------------------------*
+ * send message "connect request" to kernel
+ *---------------------------------------------------------------------------*/
+int
+sendm_connect_req(cfg_entry_t *cep)
+{
+ msg_connect_req_t mcr;
+ int ret;
+
+ cep->local_disconnect = DISCON_REM;
+
+ cep->unitlength = get_current_rate(cep, 1);
+
+ mcr.cdid = cep->cdid;
+
+ mcr.controller = cep->isdncontrollerused;
+ mcr.channel = cep->isdnchannelused;
+ mcr.txdelay = cep->isdntxdelout;
+
+ mcr.bprot = cep->b1protocol;
+
+ mcr.driver = cep->usrdevicename;
+ mcr.driver_unit = cep->usrdeviceunit;
+
+ mcr.unitlen_time = cep->unitlength;
+ mcr.idle_time = cep->idle_time_out;
+ mcr.earlyhup_time = cep->earlyhangup;
+
+ if(cep->unitlengthsrc == ULSRC_DYN)
+ mcr.unitlen_method = ULEN_METHOD_DYNAMIC;
+ else
+ mcr.unitlen_method = ULEN_METHOD_STATIC;
+
+ strcpy(mcr.dst_telno, cep->remote_phone_dialout);
+ strcpy(mcr.src_telno, cep->local_phone_dialout);
+
+ cep->last_dial_time = time(NULL);
+ cep->direction = DIR_OUT;
+
+ DBGL(DL_CNST, (log(LL_DBG, "sendm_connect_req: ctrl = %d, chan = %d", cep->isdncontrollerused, cep->isdnchannelused)));
+
+ if((ret = ioctl(isdnfd, I4B_CONNECT_REQ, &mcr)) < 0)
+ {
+ log(LL_ERR, "sendm_connect_req: ioctl I4B_CONNECT_REQ failed: %s", strerror(errno));
+ do_exit(1);
+ }
+
+ decr_free_channels(cep->isdncontrollerused);
+
+ log(LL_CHD, "%05d %s dialing out from %s to %s",
+ cep->cdid,
+ cep->name,
+ aliasing ? get_alias(cep->local_phone_dialout) : cep->local_phone_dialout,
+ aliasing ? get_alias(cep->remote_phone_dialout) : cep->remote_phone_dialout);
+
+ return(ret);
+}
+
+/*---------------------------------------------------------------------------*
+ * send message "connect response" to kernel
+ *---------------------------------------------------------------------------*/
+int
+sendm_connect_resp(cfg_entry_t *cep, int cdid, int response, int cause)
+{
+ msg_connect_resp_t mcr;
+ int ret;
+
+ mcr.cdid = cdid;
+
+ mcr.response = response;
+
+ if(response == SETUP_RESP_REJECT)
+ {
+ mcr.cause = cause;
+ }
+ else if(response == SETUP_RESP_ACCEPT)
+ {
+ cep->direction = DIR_IN;
+
+ mcr.txdelay = cep->isdntxdelin;
+
+ mcr.bprot = cep->b1protocol;
+
+ mcr.driver = cep->usrdevicename;
+ mcr.driver_unit = cep->usrdeviceunit;
+
+ mcr.max_idle_time = cep->idle_time_in;
+ }
+
+ if((ret = ioctl(isdnfd, I4B_CONNECT_RESP, &mcr)) < 0)
+ {
+ log(LL_ERR, "sendm_connect_resp: ioctl I4B_CONNECT_RESP failed: %s", strerror(errno));
+ do_exit(1);
+ }
+
+ DBGL(DL_DRVR, (log(LL_DBG, "sendm_connect_resp: sent CONNECT_RESP")));
+
+ return(ret);
+}
+
+/*---------------------------------------------------------------------------*
+ * send message "disconnect request" to kernel
+ *---------------------------------------------------------------------------*/
+int
+sendm_disconnect_req(cfg_entry_t *cep, int cause)
+{
+ msg_discon_req_t mcr;
+ int ret;
+
+ mcr.cdid = cep->cdid;
+
+ mcr.cause = cause;
+
+ cep->local_disconnect = DISCON_LOC;
+
+ if((ret = ioctl(isdnfd, I4B_DISCONNECT_REQ, &mcr)) < 0)
+ {
+ log(LL_ERR, "sendm_disconnect_req: ioctl I4B_DISCONNECT_REQ failed: %s", strerror(errno));
+ do_exit(1);
+ }
+ else
+ {
+ DBGL(DL_DRVR, (log(LL_DBG, "sendm_disconnect_req: sent DISCONNECT_REQ")));
+ }
+ return(ret);
+}
+
+/*---------------------------------------------------------------------------*
+ * send message "alert request" to kernel
+ *---------------------------------------------------------------------------*/
+int
+sendm_alert_req(cfg_entry_t *cep)
+{
+ msg_alert_req_t mar;
+ int ret;
+
+ mar.cdid = cep->cdid;
+
+ if((ret = ioctl(isdnfd, I4B_ALERT_REQ, &mar)) < 0)
+ {
+ log(LL_ERR, "sendm_alert_req: ioctl I4B_ALERT_REQ failed: %s", strerror(errno));
+ do_exit(1);
+ }
+ else
+ {
+ DBGL(DL_DRVR, (log(LL_DBG, "sendm_alert_req: sent ALERT_REQ")));
+ }
+ return(ret);
+}
+
+/* EOF */
OpenPOWER on IntegriCloud