]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
chan_misdn: Remove deprecated module.
authorJoshua C. Colp <jcolp@sangoma.com>
Mon, 16 Aug 2021 18:18:14 +0000 (15:18 -0300)
committerJoshua C. Colp <jcolp@sangoma.com>
Tue, 17 Aug 2021 13:46:42 +0000 (10:46 -0300)
ASTERISK-29596

Change-Id: Ibae9490c1b35cadbf7028d24610f745277c8535e

18 files changed:
build_tools/menuselect-deps.in
channels/Makefile
channels/chan_misdn.c [deleted file]
channels/misdn/Makefile [deleted file]
channels/misdn/chan_misdn_config.h [deleted file]
channels/misdn/ie.c [deleted file]
channels/misdn/isdn_lib.c [deleted file]
channels/misdn/isdn_lib.h [deleted file]
channels/misdn/isdn_lib_intern.h [deleted file]
channels/misdn/isdn_msg_parser.c [deleted file]
channels/misdn/portinfo.c [deleted file]
channels/misdn_config.c [deleted file]
configs/samples/misdn.conf.sample [deleted file]
configure
configure.ac
doc/UPGRADE-staging/chan_misdn_removal.txt [new file with mode: 0644]
include/asterisk/autoconfig.h.in
makeopts.in

index a1a2742469866a90ab4d5fcd85aaa44feeea1b94..a595d640bc12b4a92556993a21f872f75f2e90de 100644 (file)
@@ -23,7 +23,6 @@ ICONV=@PBX_ICONV@
 IKSEMEL=@PBX_IKSEMEL@
 IMAP_TK=@PBX_IMAP_TK@
 IODBC=@PBX_IODBC@
-ISDNNET=@PBX_ISDNNET@
 JACK=@PBX_JACK@
 JANSSON=@PBX_JANSSON@
 URIPARSER=@PBX_URIPARSER@
@@ -34,7 +33,6 @@ LIBXML2=@PBX_LIBXML2@
 XMLSTARLET=@PBX_XMLSTARLET@
 BASH=@PBX_BASH@
 LUA=@PBX_LUA@
-MISDN=@PBX_MISDN@
 MYSQLCLIENT=@PBX_MYSQLCLIENT@
 NETSNMP=@PBX_NETSNMP@
 NEWT=@PBX_NEWT@
@@ -64,7 +62,6 @@ SQLITE=@PBX_SQLITE@
 SRTP=@PBX_SRTP@
 SS7=@PBX_SS7@
 OPENSSL=@PBX_OPENSSL@
-SUPPSERV=@PBX_SUPPSERV@
 SYSLOG=@PBX_SYSLOG@
 TONEZONE=@PBX_TONEZONE@
 UNBOUND=@PBX_UNBOUND@
index b641173fe85304fb7c7388b3eed6a3ccb1b7d51e..7ce84d129db4b758d44fac3c3aa99b076500d710 100644 (file)
@@ -29,7 +29,6 @@ iax2/parser.o: _ASTCFLAGS+=$(call get_menuselect_cflags,MALLOC_DEBUG)
 $(call MOD_ADD_C,chan_sip,$(wildcard sip/*.c))
 $(call MOD_ADD_C,chan_pjsip,$(wildcard pjsip/*.c))
 $(call MOD_ADD_C,chan_dahdi,$(wildcard dahdi/*.c) sig_analog.c sig_pri.c sig_ss7.c)
-$(call MOD_ADD_C,chan_misdn,misdn_config.c misdn/isdn_lib.c misdn/isdn_msg_parser.c)
 
 chan_dahdi.o: _ASTCFLAGS+=$(call get_menuselect_cflags,LOTS_OF_SPANS)
 chan_mgcp.o: _ASTCFLAGS+=$(AST_NO_FORMAT_TRUNCATION)
@@ -37,8 +36,4 @@ chan_unistim.o: _ASTCFLAGS+=$(AST_NO_FORMAT_TRUNCATION)
 chan_phone.o: _ASTCFLAGS+=$(AST_NO_FORMAT_TRUNCATION)
 chan_sip.o: _ASTCFLAGS+=$(AST_NO_FORMAT_TRUNCATION)
 
-chan_misdn.o: _ASTCFLAGS+=-Imisdn
-misdn_config.o: _ASTCFLAGS+=-Imisdn
-misdn/isdn_lib.o: _ASTCFLAGS+=-Wno-strict-aliasing
-
 $(call MOD_ADD_C,chan_oss,console_video.c vgrabbers.c console_board.c)
diff --git a/channels/chan_misdn.c b/channels/chan_misdn.c
deleted file mode 100644 (file)
index 546bb2b..0000000
+++ /dev/null
@@ -1,12840 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2004 - 2006, Christian Richter
- *
- * Christian Richter <crich@beronet.com>
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- *
- */
-
-/*!
- * \file
- *
- * \brief the chan_misdn channel driver for Asterisk
- *
- * \author Christian Richter <crich@beronet.com>
- *
- * MISDN http://www.misdn.org/
- *
- * \ingroup channel_drivers
- */
-
-/*! \li \ref chan_misdn.c uses the configuration file \ref misdn.conf
- * \addtogroup configuration_file
- */
-
-/*! \page misdn.conf misdn.conf
- * \verbinclude misdn.conf.sample
- */
-
-/*!
- * \note
- * To use the CCBS/CCNR supplementary service feature and other
- * supplementary services using FACILITY messages requires a
- * modified version of mISDN.
- *
- * \note
- * The latest modified mISDN v1.1.x based version is available at:
- * http://svn.digium.com/svn/thirdparty/mISDN/trunk
- * http://svn.digium.com/svn/thirdparty/mISDNuser/trunk
- *
- * \note
- * Taged versions of the modified mISDN code are available under:
- * http://svn.digium.com/svn/thirdparty/mISDN/tags
- * http://svn.digium.com/svn/thirdparty/mISDNuser/tags
- */
-
-/* Define to enable cli commands to generate canned CCBS messages. */
-// #define CCBS_TEST_MESSAGES  1
-
-/*
- * XXX The mISDN channel driver needs its native bridge code
- * converted to the new bridge technology scheme.  The
- * chan_dahdi native bridge code can be used as an example.  It
- * is unlikely that this will ever get done.  Support for this
- * channel driver is dwindling because the supported version of
- * mISDN does not support newer kernels.
- *
- * Without native bridge support, the following config file
- * parameters have no effect: bridging.
- *
- * The existing native bridge code is marked with the
- * mISDN_NATIVE_BRIDGING conditional.
- */
-
-/*** MODULEINFO
-       <depend>isdnnet</depend>
-       <depend>misdn</depend>
-       <depend>suppserv</depend>
-       <support_level>deprecated</support_level>
-       <replacement>chan_dahdi</replacement>
-       <deprecated_in>16</deprecated_in>
-       <removed_in>19</removed_in>
- ***/
-
-#include "asterisk.h"
-
-#include <pthread.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-#include <arpa/inet.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <signal.h>
-#include <sys/file.h>
-#include <semaphore.h>
-#include <ctype.h>
-#include <time.h>
-
-#include "asterisk/channel.h"
-#include "asterisk/config.h"
-#include "asterisk/module.h"
-#include "asterisk/pbx.h"
-#include "asterisk/io.h"
-#include "asterisk/frame.h"
-#include "asterisk/translate.h"
-#include "asterisk/cli.h"
-#include "asterisk/musiconhold.h"
-#include "asterisk/dsp.h"
-#include "asterisk/file.h"
-#include "asterisk/callerid.h"
-#include "asterisk/indications.h"
-#include "asterisk/app.h"
-#include "asterisk/features.h"
-#include "asterisk/term.h"
-#include "asterisk/sched.h"
-#include "asterisk/stringfields.h"
-#include "asterisk/abstract_jb.h"
-#include "asterisk/causes.h"
-#include "asterisk/format.h"
-#include "asterisk/format_cap.h"
-#include "asterisk/features_config.h"
-#include "asterisk/bridge.h"
-#include "asterisk/pickup.h"
-#include "asterisk/format_cache.h"
-
-#include "chan_misdn_config.h"
-#include "isdn_lib.h"
-
-static char global_tracefile[BUFFERSIZE + 1];
-
-static int g_config_initialized = 0;
-
-struct misdn_jb{
-       int size;
-       int upper_threshold;
-       char *samples, *ok;
-       int wp,rp;
-       int state_empty;
-       int state_full;
-       int state_buffer;
-       int bytes_wrote;
-       ast_mutex_t mutexjb;
-};
-
-/*! \brief allocates the jb-structure and initialize the elements */
-struct misdn_jb *misdn_jb_init(int size, int upper_threshold);
-
-/*! \brief frees the data and destroys the given jitterbuffer struct */
-void misdn_jb_destroy(struct misdn_jb *jb);
-
-/*! \brief fills the jitterbuffer with len data returns < 0 if there was an
-error (buffer overrun). */
-int misdn_jb_fill(struct misdn_jb *jb, const char *data, int len);
-
-/*! \brief gets len bytes out of the jitterbuffer if available, else only the
-available data is returned and the return value indicates the number
-of data. */
-int misdn_jb_empty(struct misdn_jb *jb, char *data, int len);
-
-static char *complete_ch(struct ast_cli_args *a);
-static char *complete_debug_port(struct ast_cli_args *a);
-static char *complete_show_config(struct ast_cli_args *a);
-
-/* BEGIN: chan_misdn.h */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-/*
- * This timeout duration is to clean up any call completion records that
- * are forgotten about by the switch.
- */
-#define MISDN_CC_RECORD_AGE_MAX                (6UL * 60 * 60) /* seconds */
-
-#define MISDN_CC_REQUEST_WAIT_MAX      5       /* seconds */
-
-/*!
- * \brief Caller that initialized call completion services
- *
- * \details
- * This data is the payload for a datastore that is put on the channel that
- * initializes call completion services.  This datastore is set to be inherited
- * by the outbound mISDN channel.  When one of these channels hangs up, the
- * channel pointer will be set to NULL.  That way, we can ensure that we do not
- * touch this channel after it gets destroyed.
- */
-struct misdn_cc_caller {
-       /*! \brief The channel that initialized call completion services */
-       struct ast_channel *chan;
-};
-
-struct misdn_cc_notify {
-       /*! \brief Dialplan: Notify extension priority */
-       int priority;
-
-       /*! \brief Dialplan: Notify extension context */
-       char context[AST_MAX_CONTEXT];
-
-       /*! \brief Dialplan: Notify extension number (User-A) */
-       char exten[AST_MAX_EXTENSION];
-};
-
-/*! \brief mISDN call completion record */
-struct misdn_cc_record {
-       /*! \brief Call completion record linked list */
-       AST_LIST_ENTRY(misdn_cc_record) list;
-
-       /*! \brief Time the record was created. */
-       time_t time_created;
-
-       /*! \brief MISDN_CC_RECORD_ID value */
-       long record_id;
-
-       /*!
-        * \brief Logical Layer 1 port associated with this
-        * call completion record
-        */
-       int port;
-
-       /*! \brief TRUE if point-to-point mode (CCBS-T/CCNR-T mode) */
-       int ptp;
-
-       /*! \brief Mode specific parameters */
-       union {
-               /*! \brief point-to-point specific parameters. */
-               struct {
-                       /*!
-                        * \brief Call-completion signaling link.
-                        * NULL if signaling link not established.
-                        */
-                       struct misdn_bchannel *bc;
-
-                       /*!
-                        * \brief TRUE if we requested the request retention option
-                        * to be enabled.
-                        */
-                       int requested_retention;
-
-                       /*!
-                        * \brief TRUE if the request retention option is enabled.
-                        */
-                       int retention_enabled;
-               } ptp;
-
-               /*! \brief point-to-multi-point specific parameters. */
-               struct {
-                       /*! \brief CallLinkageID (valid when port determined) */
-                       int linkage_id;
-
-                       /*! \breif CCBSReference (valid when activated is TRUE) */
-                       int reference_id;
-
-                       /*! \brief globalRecall(0),     specificRecall(1) */
-                       int recall_mode;
-               } ptmp;
-       } mode;
-
-       /*! \brief TRUE if call completion activated */
-       int activated;
-
-       /*! \brief Outstanding message ID (valid when outstanding_message) */
-       int invoke_id;
-
-       /*! \brief TRUE if waiting for a response from a message (invoke_id is valid) */
-       int outstanding_message;
-
-       /*! \brief TRUE if activation has been requested */
-       int activation_requested;
-
-       /*!
-        * \brief TRUE if User-A is free
-        * \note PTMP - Used to answer CCBSStatusRequest.
-        * PTP - Determines how to respond to CCBS_T_RemoteUserFree.
-        */
-       int party_a_free;
-
-       /*! \brief Error code received from last outstanding message. */
-       enum FacErrorCode error_code;
-
-       /*! \brief Reject code received from last outstanding message. */
-       enum FacRejectCode reject_code;
-
-       /*!
-        * \brief Saved struct misdn_bchannel call information when
-        * attempted to call User-B
-        */
-       struct {
-               /*! \brief User-A caller id information */
-               struct misdn_party_id caller;
-
-               /*! \brief User-B number information */
-               struct misdn_party_dialing dialed;
-
-               /*! \brief The BC, HLC (optional) and LLC (optional) contents from the SETUP message. */
-               struct Q931_Bc_Hlc_Llc setup_bc_hlc_llc;
-
-               /*! \brief SETUP message bearer capability field code value */
-               int capability;
-
-               /*! \brief TRUE if call made in digital HDLC mode */
-               int hdlc;
-       } redial;
-
-       /*! \brief Dialplan location to indicate User-B free and User-A is free */
-       struct misdn_cc_notify remote_user_free;
-
-       /*! \brief Dialplan location to indicate User-B free and User-A is busy */
-       struct misdn_cc_notify b_free;
-};
-
-/*! \brief mISDN call completion record database */
-static AST_LIST_HEAD_STATIC(misdn_cc_records_db, misdn_cc_record);
-/*! \brief Next call completion record ID to use */
-static __u16 misdn_cc_record_id;
-/*! \brief Next invoke ID to use */
-static __s16 misdn_invoke_id;
-
-static const char misdn_no_response_from_network[] = "No response from network";
-static const char misdn_cc_record_not_found[] = "Call completion record not found";
-
-/* mISDN channel variable names */
-#define MISDN_CC_RECORD_ID     "MISDN_CC_RECORD_ID"
-#define MISDN_CC_STATUS                "MISDN_CC_STATUS"
-#define MISDN_ERROR_MSG                "MISDN_ERROR_MSG"
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-static ast_mutex_t release_lock;
-
-enum misdn_chan_state {
-       MISDN_NOTHING = 0,         /*!< at beginning */
-       MISDN_WAITING4DIGS,        /*!< when waiting for info */
-       MISDN_EXTCANTMATCH,        /*!< when asterisk couldn't match our ext */
-       MISDN_INCOMING_SETUP,      /*!< for incoming setup */
-       MISDN_DIALING,             /*!< when pbx_start */
-       MISDN_PROGRESS,            /*!< we have progress */
-       MISDN_PROCEEDING,          /*!< we have progress */
-       MISDN_CALLING,             /*!< when misdn_call is called */
-       MISDN_CALLING_ACKNOWLEDGE, /*!< when we get SETUP_ACK */
-       MISDN_ALERTING,            /*!< when Alerting */
-       MISDN_BUSY,                /*!< when BUSY */
-       MISDN_CONNECTED,           /*!< when connected */
-       MISDN_DISCONNECTED,        /*!< when connected */
-       MISDN_CLEANING,            /*!< when hangup from * but we were connected before */
-};
-
-/*! Asterisk created the channel (outgoing call) */
-#define ORG_AST 1
-/*! mISDN created the channel (incoming call) */
-#define ORG_MISDN 2
-
-enum misdn_hold_state {
-       MISDN_HOLD_IDLE,                /*!< HOLD not active */
-       MISDN_HOLD_ACTIVE,              /*!< Call is held */
-       MISDN_HOLD_TRANSFER,    /*!< Held call is being transferred */
-       MISDN_HOLD_DISCONNECT,  /*!< Held call is being disconnected */
-};
-struct hold_info {
-       /*!
-        * \brief Call HOLD state.
-        */
-       enum misdn_hold_state state;
-       /*!
-        * \brief Logical port the channel call record is HELD on
-        * because the B channel is no longer associated.
-        */
-       int port;
-
-       /*!
-        * \brief Original B channel number the HELD call was using.
-        * \note Used only for debug display messages.
-        */
-       int channel;
-};
-
-#define chan_list_ref(obj, debug) ao2_t_ref((obj), +1, (debug))
-#define chan_list_unref(obj, debug) ao2_t_ref((obj), -1, (debug))
-
-/*!
- * \brief Channel call record structure
- */
-struct chan_list {
-       /*!
-        * \brief The "allowed_bearers" string read in from /etc/asterisk/misdn.conf
-        */
-       char allowed_bearers[BUFFERSIZE + 1];
-
-       /*!
-        * \brief State of the channel
-        */
-       enum misdn_chan_state state;
-
-       /*!
-        * \brief TRUE if a hangup needs to be queued
-        * \note This is a debug flag only used to catch calls to hangup_chan() that are already hungup.
-        */
-       int need_queue_hangup;
-
-       /*!
-        * \brief TRUE if a channel can be hung up by calling asterisk directly when done.
-        */
-       int need_hangup;
-
-       /*!
-        * \brief TRUE if we could send an AST_CONTROL_BUSY if needed.
-        */
-       int need_busy;
-
-       /*!
-        * \brief Who originally created this channel. ORG_AST or ORG_MISDN
-        */
-       int originator;
-
-       /*!
-        * \brief TRUE of we are not to respond immediately to a SETUP message.  Check the dialplan first.
-        * \note The "noautorespond_on_setup" boolean read in from /etc/asterisk/misdn.conf
-        */
-       int noautorespond_on_setup;
-
-       int norxtone;   /*!< Boolean assigned values but the value is not used. */
-
-       /*!
-        * \brief TRUE if we are not to generate tones (Playtones)
-        */
-       int notxtone;
-
-       /*!
-        * \brief TRUE if echo canceller is enabled.  Value is toggled.
-        */
-       int toggle_ec;
-
-       /*!
-        * \brief TRUE if you want to send Tone Indications to an incoming
-        * ISDN channel on a TE Port.
-        * \note The "incoming_early_audio" boolean read in from /etc/asterisk/misdn.conf
-        */
-       int incoming_early_audio;
-
-       /*!
-        * \brief TRUE if DTMF digits are to be passed inband only.
-        * \note It is settable by the misdn_set_opt() application.
-        */
-       int ignore_dtmf;
-
-       /*!
-        * \brief Pipe file descriptor handles array.
-        * Read from pipe[0], write to pipe[1]
-        */
-       int pipe[2];
-
-       /*!
-        * \brief Read buffer for inbound audio from pipe[0]
-        */
-       char ast_rd_buf[4096];
-
-       /*!
-        * \brief Inbound audio frame returned by misdn_read().
-        */
-       struct ast_frame frame;
-
-       /*!
-        * \brief Fax detection option. (0:no 1:yes 2:yes+nojump)
-        * \note The "faxdetect" option string read in from /etc/asterisk/misdn.conf
-        * \note It is settable by the misdn_set_opt() application.
-        */
-       int faxdetect;
-
-       /*!
-        * \brief Number of seconds to detect a Fax machine when detection enabled.
-        * \note 0 disables the timeout.
-        * \note The "faxdetect_timeout" value read in from /etc/asterisk/misdn.conf
-        */
-       int faxdetect_timeout;
-
-       /*!
-        * \brief Starting time of fax detection with timeout when nonzero.
-        */
-       struct timeval faxdetect_tv;
-
-       /*!
-        * \brief TRUE if a fax has been detected.
-        */
-       int faxhandled;
-
-       /*!
-        * \brief TRUE if we will use the Asterisk DSP to detect DTMF/Fax
-        * \note The "astdtmf" boolean read in from /etc/asterisk/misdn.conf
-        */
-       int ast_dsp;
-
-       /*!
-        * \brief Jitterbuffer length
-        * \note The "jitterbuffer" value read in from /etc/asterisk/misdn.conf
-        */
-       int jb_len;
-
-       /*!
-        * \brief Jitterbuffer upper threshold
-        * \note The "jitterbuffer_upper_threshold" value read in from /etc/asterisk/misdn.conf
-        */
-       int jb_upper_threshold;
-
-       /*!
-        * \brief Allocated jitterbuffer controller
-        * \note misdn_jb_init() creates the jitterbuffer.
-        * \note Must use misdn_jb_destroy() to clean up.
-        */
-       struct misdn_jb *jb;
-
-       /*!
-        * \brief Allocated DSP controller
-        * \note ast_dsp_new() creates the DSP controller.
-        * \note Must use ast_dsp_free() to clean up.
-        */
-       struct ast_dsp *dsp;
-
-       /*!
-        * \brief Associated Asterisk channel structure.
-        */
-       struct ast_channel * ast;
-
-       /*!
-        * \brief Associated B channel structure.
-        */
-       struct misdn_bchannel *bc;
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-       /*!
-        * \brief Peer channel for which call completion was initialized.
-        */
-       struct misdn_cc_caller *peer;
-
-       /*! \brief Associated call completion record ID (-1 if not associated) */
-       long record_id;
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-       /*!
-        * \brief HELD channel call information
-        */
-       struct hold_info hold;
-
-       /*!
-        * \brief From associated B channel: Layer 3 process ID
-        * \note Used to find the HELD channel call record when retrieving a call.
-        */
-       unsigned int l3id;
-
-       /*!
-        * \brief From associated B channel: B Channel mISDN driver layer ID from mISDN_get_layerid()
-        * \note Used only for debug display messages.
-        */
-       int addr;
-
-       /*!
-        * \brief Incoming call dialplan context identifier.
-        * \note The "context" string read in from /etc/asterisk/misdn.conf
-        */
-       char context[AST_MAX_CONTEXT];
-
-       /*!
-        * \brief The configured music-on-hold class to use for this call.
-        * \note The "musicclass" string read in from /etc/asterisk/misdn.conf
-        */
-       char mohinterpret[MAX_MUSICCLASS];
-
-       /*!
-        * \brief Number of outgoing audio frames dropped since last debug gripe message.
-        */
-       int dropped_frame_cnt;
-
-       /*!
-        * \brief TRUE if we must do the ringback tones.
-        * \note The "far_alerting" boolean read in from /etc/asterisk/misdn.conf
-        */
-       int far_alerting;
-
-       /*!
-        * \brief TRUE if NT should disconnect an overlap dialing call when a timeout occurs.
-        * \note The "nttimeout" boolean read in from /etc/asterisk/misdn.conf
-        */
-       int nttimeout;
-
-       /*!
-        * \brief Tone zone sound used for dialtone generation.
-        * \note Used as a boolean.  Non-NULL to prod generation if enabled.
-        */
-       struct ast_tone_zone_sound *ts;
-
-       /*!
-        * \brief Enables overlap dialing for the set amount of seconds.  (0 = Disabled)
-        * \note The "overlapdial" value read in from /etc/asterisk/misdn.conf
-        */
-       int overlap_dial;
-
-       /*!
-        * \brief Overlap dialing timeout Task ID.  -1 if not running.
-        */
-       int overlap_dial_task;
-
-       /*!
-        * \brief overlap_tv access lock.
-        */
-       ast_mutex_t overlap_tv_lock;
-
-       /*!
-        * \brief Overlap timer start time.  Timer restarted for every digit received.
-        */
-       struct timeval overlap_tv;
-
-       /*!
-        * \brief Next channel call record in the list.
-        */
-       struct chan_list *next;
-};
-
-
-int MAXTICS = 8;
-
-
-void export_ch(struct ast_channel *chan, struct misdn_bchannel *bc, struct chan_list *ch);
-void import_ch(struct ast_channel *chan, struct misdn_bchannel *bc, struct chan_list *ch);
-static struct ast_frame *process_ast_dsp(struct chan_list *tmp, struct ast_frame *frame);
-
-struct robin_list {
-       char *group;
-       int port;
-       int channel;
-       struct robin_list *next;
-       struct robin_list *prev;
-};
-static struct robin_list *robin = NULL;
-
-
-static void free_robin_list(void)
-{
-       struct robin_list *r;
-       struct robin_list *next;
-
-       for (r = robin, robin = NULL; r; r = next) {
-               next = r->next;
-               ast_free(r->group);
-               ast_free(r);
-       }
-}
-
-static struct robin_list *get_robin_position(char *group)
-{
-       struct robin_list *new;
-       struct robin_list *iter = robin;
-       for (; iter; iter = iter->next) {
-               if (!strcasecmp(iter->group, group)) {
-                       return iter;
-               }
-       }
-       new = ast_calloc(1, sizeof(*new));
-       if (!new) {
-               return NULL;
-       }
-       new->group = ast_strdup(group);
-       if (!new->group) {
-               ast_free(new);
-               return NULL;
-       }
-       new->channel = 1;
-       if (robin) {
-               new->next = robin;
-               robin->prev = new;
-       }
-       robin = new;
-       return robin;
-}
-
-
-/*! \brief the main schedule context for stuff like l1 watcher, overlap dial, ... */
-static struct ast_sched_context *misdn_tasks = NULL;
-static pthread_t misdn_tasks_thread;
-
-static int *misdn_ports;
-
-static void chan_misdn_log(int level, int port, char *tmpl, ...)
-       __attribute__((format(printf, 3, 4)));
-
-static struct ast_channel *misdn_new(struct chan_list *cl, int state,  char *exten, char *callerid, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, int port, int c);
-static void send_digit_to_chan(struct chan_list *cl, char digit);
-
-static int pbx_start_chan(struct chan_list *ch);
-
-#define MISDN_ASTERISK_TECH_PVT(ast) ast_channel_tech_pvt(ast)
-#define MISDN_ASTERISK_TECH_PVT_SET(ast, value) ast_channel_tech_pvt_set(ast, value)
-
-#include "asterisk/strings.h"
-
-/* #define MISDN_DEBUG 1 */
-
-static const char misdn_type[] = "mISDN";
-
-static int tracing = 0;
-
-static int *misdn_debug;
-static int *misdn_debug_only;
-static int max_ports;
-
-static int *misdn_in_calls;
-static int *misdn_out_calls;
-
-/*!
- * \brief Global channel call record list head.
- */
-static struct chan_list *cl_te=NULL;
-static ast_mutex_t cl_te_lock;
-
-static enum event_response_e
-cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data);
-
-static int send_cause2ast(struct ast_channel *ast, struct misdn_bchannel *bc, struct chan_list *ch);
-
-static void cl_queue_chan(struct chan_list *chan);
-
-static int dialtone_indicate(struct chan_list *cl);
-static void hanguptone_indicate(struct chan_list *cl);
-static int stop_indicate(struct chan_list *cl);
-
-static int start_bc_tones(struct chan_list *cl);
-static int stop_bc_tones(struct chan_list *cl);
-static void release_chan_early(struct chan_list *ch);
-static void release_chan(struct chan_list *ch, struct misdn_bchannel *bc);
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-static const char misdn_command_name[] = "misdn_command";
-static int misdn_command_exec(struct ast_channel *chan, const char *data);
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-static int misdn_check_l2l1(struct ast_channel *chan, const char *data);
-static int misdn_set_opt_exec(struct ast_channel *chan, const char *data);
-static int misdn_facility_exec(struct ast_channel *chan, const char *data);
-
-int chan_misdn_jb_empty(struct misdn_bchannel *bc, char *buf, int len);
-
-void debug_numtype(int port, int numtype, char *type);
-
-int add_out_calls(int port);
-int add_in_calls(int port);
-
-
-#ifdef MISDN_1_2
-static int update_pipeline_config(struct misdn_bchannel *bc);
-#else
-static int update_ec_config(struct misdn_bchannel *bc);
-#endif
-
-
-
-/*************** Helpers *****************/
-
-static int misdn_chan_is_valid(struct chan_list *ch)
-{
-       struct chan_list *list;
-
-       ast_mutex_lock(&cl_te_lock);
-       for (list = cl_te; list; list = list->next) {
-               if (list == ch) {
-                       ast_mutex_unlock(&cl_te_lock);
-                       return 1;
-               }
-       }
-       ast_mutex_unlock(&cl_te_lock);
-
-       return 0;
-}
-
-#if defined(mISDN_NATIVE_BRIDGING)
-/*! Returns a reference to the found chan_list. */
-static struct chan_list *get_chan_by_ast(struct ast_channel *ast)
-{
-       struct chan_list *tmp;
-
-       ast_mutex_lock(&cl_te_lock);
-       for (tmp = cl_te; tmp; tmp = tmp->next) {
-               if (tmp->ast == ast) {
-                       chan_list_ref(tmp, "Found chan_list by ast");
-                       ast_mutex_unlock(&cl_te_lock);
-                       return tmp;
-               }
-       }
-       ast_mutex_unlock(&cl_te_lock);
-
-       return NULL;
-}
-#endif /* defined(mISDN_NATIVE_BRIDGING) */
-
-/*! Returns a reference to the found chan_list. */
-static struct chan_list *get_chan_by_ast_name(const char *name)
-{
-       struct chan_list *tmp;
-
-       ast_mutex_lock(&cl_te_lock);
-       for (tmp = cl_te; tmp; tmp = tmp->next) {
-               if (tmp->ast && strcmp(ast_channel_name(tmp->ast), name) == 0) {
-                       chan_list_ref(tmp, "Found chan_list by ast name");
-                       ast_mutex_unlock(&cl_te_lock);
-                       return tmp;
-               }
-       }
-       ast_mutex_unlock(&cl_te_lock);
-
-       return NULL;
-}
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-/*!
- * \internal
- * \brief Destroy the misdn_cc_ds_info datastore payload
- *
- * \param[in] data the datastore payload, a reference to an misdn_cc_caller
- *
- * \details
- * Since the payload is a reference to an astobj2 object, we just decrement its
- * reference count.  Before doing so, we NULL out the channel pointer inside of
- * the misdn_cc_caller instance.  This function will be called in one of two
- * cases.  In both cases, we no longer need the channel pointer:
- *
- *  - The original channel that initialized call completion services, the same
- *    channel that is stored here, has been destroyed early.  This could happen
- *    if it transferred the mISDN channel, for example.
- *
- *  - The mISDN channel that had this datastore inherited on to it is now being
- *    destroyed.  If this is the case, then the call completion events have
- *    already occurred and the appropriate channel variables have already been
- *    set on the original channel that requested call completion services.
- *
- * \return Nothing
- */
-static void misdn_cc_ds_destroy(void *data)
-{
-       struct misdn_cc_caller *cc_caller = data;
-
-       ao2_lock(cc_caller);
-       cc_caller->chan = NULL;
-       ao2_unlock(cc_caller);
-
-       ao2_ref(cc_caller, -1);
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-/*!
- * \internal
- * \brief Duplicate the misdn_cc_ds_info datastore payload
- *
- * \param[in] data the datastore payload, a reference to an misdn_cc_caller
- *
- * \details
- * All we need to do is bump the reference count and return the same instance.
- *
- * \return A reference to an instance of a misdn_cc_caller
- */
-static void *misdn_cc_ds_duplicate(void *data)
-{
-       struct misdn_cc_caller *cc_caller = data;
-
-       ao2_ref(cc_caller, +1);
-
-       return cc_caller;
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-static const struct ast_datastore_info misdn_cc_ds_info = {
-       .type      = "misdn_cc",
-       .destroy   = misdn_cc_ds_destroy,
-       .duplicate = misdn_cc_ds_duplicate,
-};
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-/*!
- * \internal
- * \brief Set a channel var on the peer channel for call completion services
- *
- * \param[in] peer The peer that initialized call completion services
- * \param[in] var The variable name to set
- * \param[in] value The variable value to set
- *
- * This function may be called from outside of the channel thread.  It handles
- * the fact that the peer channel may be hung up and destroyed at any time.
- *
- * \return nothing
- */
-static void misdn_cc_set_peer_var(struct misdn_cc_caller *peer, const char *var,
-       const char *value)
-{
-       ao2_lock(peer);
-
-       /*! \todo XXX This nastiness can go away once ast_channel is ref counted! */
-       while (peer->chan && ast_channel_trylock(peer->chan)) {
-               ao2_unlock(peer);
-               sched_yield();
-               ao2_lock(peer);
-       }
-
-       if (peer->chan) {
-               pbx_builtin_setvar_helper(peer->chan, var, value);
-               ast_channel_unlock(peer->chan);
-       }
-
-       ao2_unlock(peer);
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-/*!
- * \internal
- * \brief Get a reference to the CC caller if it exists
- */
-static struct misdn_cc_caller *misdn_cc_caller_get(struct ast_channel *chan)
-{
-       struct ast_datastore *datastore;
-       struct misdn_cc_caller *cc_caller;
-
-       ast_channel_lock(chan);
-
-       if (!(datastore = ast_channel_datastore_find(chan, &misdn_cc_ds_info, NULL))) {
-               ast_channel_unlock(chan);
-               return NULL;
-       }
-
-       ao2_ref(datastore->data, +1);
-       cc_caller = datastore->data;
-
-       ast_channel_unlock(chan);
-
-       return cc_caller;
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-/*!
- * \internal
- * \brief Find the call completion record given the record id.
- *
- * \param record_id
- *
- * \retval pointer to found call completion record
- * \retval NULL if not found
- *
- * \note Assumes the misdn_cc_records_db lock is already obtained.
- */
-static struct misdn_cc_record *misdn_cc_find_by_id(long record_id)
-{
-       struct misdn_cc_record *current;
-
-       AST_LIST_TRAVERSE(&misdn_cc_records_db, current, list) {
-               if (current->record_id == record_id) {
-                       /* Found the record */
-                       break;
-               }
-       }
-
-       return current;
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-/*!
- * \internal
- * \brief Find the call completion record given the port and call linkage id.
- *
- * \param port Logical port number
- * \param linkage_id Call linkage ID number from switch.
- *
- * \retval pointer to found call completion record
- * \retval NULL if not found
- *
- * \note Assumes the misdn_cc_records_db lock is already obtained.
- */
-static struct misdn_cc_record *misdn_cc_find_by_linkage(int port, int linkage_id)
-{
-       struct misdn_cc_record *current;
-
-       AST_LIST_TRAVERSE(&misdn_cc_records_db, current, list) {
-               if (current->port == port
-                       && !current->ptp
-                       && current->mode.ptmp.linkage_id == linkage_id) {
-                       /* Found the record */
-                       break;
-               }
-       }
-
-       return current;
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-/*!
- * \internal
- * \brief Find the call completion record given the port and outstanding invocation id.
- *
- * \param port Logical port number
- * \param invoke_id Outstanding message invocation ID number.
- *
- * \retval pointer to found call completion record
- * \retval NULL if not found
- *
- * \note Assumes the misdn_cc_records_db lock is already obtained.
- */
-static struct misdn_cc_record *misdn_cc_find_by_invoke(int port, int invoke_id)
-{
-       struct misdn_cc_record *current;
-
-       AST_LIST_TRAVERSE(&misdn_cc_records_db, current, list) {
-               if (current->outstanding_message
-                       && current->invoke_id == invoke_id
-                       && current->port == port) {
-                       /* Found the record */
-                       break;
-               }
-       }
-
-       return current;
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-/*!
- * \internal
- * \brief Find the call completion record given the port and CCBS reference id.
- *
- * \param port Logical port number
- * \param reference_id CCBS reference ID number from switch.
- *
- * \retval pointer to found call completion record
- * \retval NULL if not found
- *
- * \note Assumes the misdn_cc_records_db lock is already obtained.
- */
-static struct misdn_cc_record *misdn_cc_find_by_reference(int port, int reference_id)
-{
-       struct misdn_cc_record *current;
-
-       AST_LIST_TRAVERSE(&misdn_cc_records_db, current, list) {
-               if (current->activated
-                       && current->port == port
-                       && !current->ptp
-                       && current->mode.ptmp.reference_id == reference_id) {
-                       /* Found the record */
-                       break;
-               }
-       }
-
-       return current;
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-/*!
- * \internal
- * \brief Find the call completion record given the B channel pointer
- *
- * \param bc B channel control structure pointer.
- *
- * \retval pointer to found call completion record
- * \retval NULL if not found
- *
- * \note Assumes the misdn_cc_records_db lock is already obtained.
- */
-static struct misdn_cc_record *misdn_cc_find_by_bc(const struct misdn_bchannel *bc)
-{
-       struct misdn_cc_record *current;
-
-       if (bc) {
-               AST_LIST_TRAVERSE(&misdn_cc_records_db, current, list) {
-                       if (current->ptp
-                               && current->mode.ptp.bc == bc) {
-                               /* Found the record */
-                               break;
-                       }
-               }
-       } else {
-               current = NULL;
-       }
-
-       return current;
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-/*!
- * \internal
- * \brief Delete the given call completion record
- *
- * \param doomed Call completion record to destroy
- *
- * \return Nothing
- *
- * \note Assumes the misdn_cc_records_db lock is already obtained.
- */
-static void misdn_cc_delete(struct misdn_cc_record *doomed)
-{
-       struct misdn_cc_record *current;
-
-       AST_LIST_TRAVERSE_SAFE_BEGIN(&misdn_cc_records_db, current, list) {
-               if (current == doomed) {
-                       AST_LIST_REMOVE_CURRENT(list);
-                       ast_free(current);
-                       return;
-               }
-       }
-       AST_LIST_TRAVERSE_SAFE_END;
-
-       /* The doomed node is not in the call completion database */
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-/*!
- * \internal
- * \brief Delete all old call completion records
- *
- * \return Nothing
- *
- * \note Assumes the misdn_cc_records_db lock is already obtained.
- */
-static void misdn_cc_remove_old(void)
-{
-       struct misdn_cc_record *current;
-       time_t now;
-
-       now = time(NULL);
-       AST_LIST_TRAVERSE_SAFE_BEGIN(&misdn_cc_records_db, current, list) {
-               if (MISDN_CC_RECORD_AGE_MAX < now - current->time_created) {
-                       if (current->ptp && current->mode.ptp.bc) {
-                               /* Close the old call-completion signaling link */
-                               current->mode.ptp.bc->fac_out.Function = Fac_None;
-                               current->mode.ptp.bc->out_cause = AST_CAUSE_NORMAL_CLEARING;
-                               misdn_lib_send_event(current->mode.ptp.bc, EVENT_RELEASE_COMPLETE);
-                       }
-
-                       /* Remove the old call completion record */
-                       AST_LIST_REMOVE_CURRENT(list);
-                       ast_free(current);
-               }
-       }
-       AST_LIST_TRAVERSE_SAFE_END;
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-/*!
- * \internal
- * \brief Allocate the next record id.
- *
- * \retval New record id on success.
- * \retval -1 on error.
- *
- * \note Assumes the misdn_cc_records_db lock is already obtained.
- */
-static long misdn_cc_record_id_new(void)
-{
-       long record_id;
-       long first_id;
-
-       record_id = ++misdn_cc_record_id;
-       first_id = record_id;
-       while (misdn_cc_find_by_id(record_id)) {
-               record_id = ++misdn_cc_record_id;
-               if (record_id == first_id) {
-                       /*
-                        * We have a resource leak.
-                        * We should never need to allocate 64k records.
-                        */
-                       chan_misdn_log(0, 0, " --> ERROR Too many call completion records!\n");
-                       record_id = -1;
-                       break;
-               }
-       }
-
-       return record_id;
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-/*!
- * \internal
- * \brief Create a new call completion record
- *
- * \retval pointer to new call completion record
- * \retval NULL if failed
- *
- * \note Assumes the misdn_cc_records_db lock is already obtained.
- */
-static struct misdn_cc_record *misdn_cc_new(void)
-{
-       struct misdn_cc_record *cc_record;
-       long record_id;
-
-       misdn_cc_remove_old();
-
-       cc_record = ast_calloc(1, sizeof(*cc_record));
-       if (cc_record) {
-               record_id = misdn_cc_record_id_new();
-               if (record_id < 0) {
-                       ast_free(cc_record);
-                       return NULL;
-               }
-
-               /* Initialize the new record */
-               cc_record->record_id = record_id;
-               cc_record->port = -1;/* Invalid port so it will never be found this way */
-               cc_record->invoke_id = ++misdn_invoke_id;
-               cc_record->party_a_free = 1;/* Default User-A as free */
-               cc_record->error_code = FacError_None;
-               cc_record->reject_code = FacReject_None;
-               cc_record->time_created = time(NULL);
-
-               /* Insert the new record into the database */
-               AST_LIST_INSERT_HEAD(&misdn_cc_records_db, cc_record, list);
-       }
-       return cc_record;
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-/*!
- * \internal
- * \brief Destroy the call completion record database
- *
- * \return Nothing
- */
-static void misdn_cc_destroy(void)
-{
-       struct misdn_cc_record *current;
-
-       while ((current = AST_LIST_REMOVE_HEAD(&misdn_cc_records_db, list))) {
-               /* Do a misdn_cc_delete(current) inline */
-               ast_free(current);
-       }
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-/*!
- * \internal
- * \brief Initialize the call completion record database
- *
- * \return Nothing
- */
-static void misdn_cc_init(void)
-{
-       misdn_cc_record_id = 0;
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-/*!
- * \internal
- * \brief Check the status of an outstanding invocation request.
- *
- * \param data Points to an integer containing the call completion record id.
- *
- * \retval 0 if got a response.
- * \retval -1 if no response yet.
- */
-static int misdn_cc_response_check(void *data)
-{
-       int not_responded;
-       struct misdn_cc_record *cc_record;
-
-       AST_LIST_LOCK(&misdn_cc_records_db);
-       cc_record = misdn_cc_find_by_id(*(long *) data);
-       if (cc_record) {
-               if (cc_record->outstanding_message) {
-                       not_responded = -1;
-               } else {
-                       not_responded = 0;
-               }
-       } else {
-               /* No record so there is no response to check. */
-               not_responded = 0;
-       }
-       AST_LIST_UNLOCK(&misdn_cc_records_db);
-
-       return not_responded;
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-/*!
- * \internal
- * \brief Wait for a response from the switch for an outstanding
- * invocation request.
- *
- * \param chan Asterisk channel to operate upon.
- * \param wait_seconds Number of seconds to wait
- * \param record_id Call completion record ID.
- *
- * \return Nothing
- */
-static void misdn_cc_response_wait(struct ast_channel *chan, int wait_seconds, long record_id)
-{
-       unsigned count;
-
-       for (count = 2 * MISDN_CC_REQUEST_WAIT_MAX; count--;) {
-               /* Sleep in 500 ms increments */
-               if (ast_safe_sleep_conditional(chan, 500, misdn_cc_response_check, &record_id) != 0) {
-                       /* We got hung up or our response came in. */
-                       break;
-               }
-       }
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-/*!
- * \internal
- * \brief Convert the mISDN reject code to a string
- *
- * \param code mISDN reject code.
- *
- * \return The mISDN reject code as a string
- */
-static const char *misdn_to_str_reject_code(enum FacRejectCode code)
-{
-       static const struct {
-               enum FacRejectCode code;
-               char *name;
-       } arr[] = {
-/* *INDENT-OFF* */
-               { FacReject_None,                           "No reject occurred" },
-               { FacReject_Unknown,                        "Unknown reject code" },
-
-               { FacReject_Gen_UnrecognizedComponent,      "General: Unrecognized Component" },
-               { FacReject_Gen_MistypedComponent,          "General: Mistyped Component" },
-               { FacReject_Gen_BadlyStructuredComponent,   "General: Badly Structured Component" },
-
-               { FacReject_Inv_DuplicateInvocation,        "Invoke: Duplicate Invocation" },
-               { FacReject_Inv_UnrecognizedOperation,      "Invoke: Unrecognized Operation" },
-               { FacReject_Inv_MistypedArgument,           "Invoke: Mistyped Argument" },
-               { FacReject_Inv_ResourceLimitation,         "Invoke: Resource Limitation" },
-               { FacReject_Inv_InitiatorReleasing,         "Invoke: Initiator Releasing" },
-               { FacReject_Inv_UnrecognizedLinkedID,       "Invoke: Unrecognized Linked ID" },
-               { FacReject_Inv_LinkedResponseUnexpected,   "Invoke: Linked Response Unexpected" },
-               { FacReject_Inv_UnexpectedChildOperation,   "Invoke: Unexpected Child Operation" },
-
-               { FacReject_Res_UnrecognizedInvocation,     "Result: Unrecognized Invocation" },
-               { FacReject_Res_ResultResponseUnexpected,   "Result: Result Response Unexpected" },
-               { FacReject_Res_MistypedResult,             "Result: Mistyped Result" },
-
-               { FacReject_Err_UnrecognizedInvocation,     "Error: Unrecognized Invocation" },
-               { FacReject_Err_ErrorResponseUnexpected,    "Error: Error Response Unexpected" },
-               { FacReject_Err_UnrecognizedError,          "Error: Unrecognized Error" },
-               { FacReject_Err_UnexpectedError,            "Error: Unexpected Error" },
-               { FacReject_Err_MistypedParameter,          "Error: Mistyped Parameter" },
-/* *INDENT-ON* */
-       };
-
-       unsigned index;
-
-       for (index = 0; index < ARRAY_LEN(arr); ++index) {
-               if (arr[index].code == code) {
-                       return arr[index].name;
-               }
-       }
-
-       return "unknown";
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-/*!
- * \internal
- * \brief Convert the mISDN error code to a string
- *
- * \param code mISDN error code.
- *
- * \return The mISDN error code as a string
- */
-static const char *misdn_to_str_error_code(enum FacErrorCode code)
-{
-       static const struct {
-               enum FacErrorCode code;
-               char *name;
-       } arr[] = {
-/* *INDENT-OFF* */
-               { FacError_None,                            "No error occurred" },
-               { FacError_Unknown,                         "Unknown OID error code" },
-
-               { FacError_Gen_NotSubscribed,               "General: Not Subscribed" },
-               { FacError_Gen_NotAvailable,                "General: Not Available" },
-               { FacError_Gen_NotImplemented,              "General: Not Implemented" },
-               { FacError_Gen_InvalidServedUserNr,         "General: Invalid Served User Number" },
-               { FacError_Gen_InvalidCallState,            "General: Invalid Call State" },
-               { FacError_Gen_BasicServiceNotProvided,     "General: Basic Service Not Provided" },
-               { FacError_Gen_NotIncomingCall,             "General: Not Incoming Call" },
-               { FacError_Gen_SupplementaryServiceInteractionNotAllowed,"General: Supplementary Service Interaction Not Allowed" },
-               { FacError_Gen_ResourceUnavailable,         "General: Resource Unavailable" },
-
-               { FacError_Div_InvalidDivertedToNr,         "Diversion: Invalid Diverted To Number" },
-               { FacError_Div_SpecialServiceNr,            "Diversion: Special Service Number" },
-               { FacError_Div_DiversionToServedUserNr,     "Diversion: Diversion To Served User Number" },
-               { FacError_Div_IncomingCallAccepted,        "Diversion: Incoming Call Accepted" },
-               { FacError_Div_NumberOfDiversionsExceeded,  "Diversion: Number Of Diversions Exceeded" },
-               { FacError_Div_NotActivated,                "Diversion: Not Activated" },
-               { FacError_Div_RequestAlreadyAccepted,      "Diversion: Request Already Accepted" },
-
-               { FacError_AOC_NoChargingInfoAvailable,     "AOC: No Charging Info Available" },
-
-               { FacError_CCBS_InvalidCallLinkageID,       "CCBS: Invalid Call Linkage ID" },
-               { FacError_CCBS_InvalidCCBSReference,       "CCBS: Invalid CCBS Reference" },
-               { FacError_CCBS_LongTermDenial,             "CCBS: Long Term Denial" },
-               { FacError_CCBS_ShortTermDenial,            "CCBS: Short Term Denial" },
-               { FacError_CCBS_IsAlreadyActivated,         "CCBS: Is Already Activated" },
-               { FacError_CCBS_AlreadyAccepted,            "CCBS: Already Accepted" },
-               { FacError_CCBS_OutgoingCCBSQueueFull,      "CCBS: Outgoing CCBS Queue Full" },
-               { FacError_CCBS_CallFailureReasonNotBusy,   "CCBS: Call Failure Reason Not Busy" },
-               { FacError_CCBS_NotReadyForCall,            "CCBS: Not Ready For Call" },
-
-               { FacError_CCBS_T_LongTermDenial,           "CCBS-T: Long Term Denial" },
-               { FacError_CCBS_T_ShortTermDenial,          "CCBS-T: Short Term Denial" },
-
-               { FacError_ECT_LinkIdNotAssignedByNetwork,  "ECT: Link ID Not Assigned By Network" },
-/* *INDENT-ON* */
-       };
-
-       unsigned index;
-
-       for (index = 0; index < ARRAY_LEN(arr); ++index) {
-               if (arr[index].code == code) {
-                       return arr[index].name;
-               }
-       }
-
-       return "unknown";
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-/*!
- * \internal
- * \brief Convert mISDN redirecting reason to diversion reason.
- *
- * \param reason mISDN redirecting reason code.
- *
- * \return Supported diversion reason code.
- */
-static unsigned misdn_to_diversion_reason(enum mISDN_REDIRECTING_REASON reason)
-{
-       unsigned diversion_reason;
-
-       switch (reason) {
-       case mISDN_REDIRECTING_REASON_CALL_FWD:
-               diversion_reason = 1;/* cfu */
-               break;
-       case mISDN_REDIRECTING_REASON_CALL_FWD_BUSY:
-               diversion_reason = 2;/* cfb */
-               break;
-       case mISDN_REDIRECTING_REASON_NO_REPLY:
-               diversion_reason = 3;/* cfnr */
-               break;
-       default:
-               diversion_reason = 0;/* unknown */
-               break;
-       }
-
-       return diversion_reason;
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-/*!
- * \internal
- * \brief Convert diversion reason to mISDN redirecting reason
- *
- * \param diversion_reason Diversion reason to convert
- *
- * \return Supported redirecting reason code.
- */
-static enum mISDN_REDIRECTING_REASON diversion_reason_to_misdn(unsigned diversion_reason)
-{
-       enum mISDN_REDIRECTING_REASON reason;
-
-       switch (diversion_reason) {
-       case 1:/* cfu */
-               reason = mISDN_REDIRECTING_REASON_CALL_FWD;
-               break;
-       case 2:/* cfb */
-               reason = mISDN_REDIRECTING_REASON_CALL_FWD_BUSY;
-               break;
-       case 3:/* cfnr */
-               reason = mISDN_REDIRECTING_REASON_NO_REPLY;
-               break;
-       default:
-               reason = mISDN_REDIRECTING_REASON_UNKNOWN;
-               break;
-       }
-
-       return reason;
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-/*!
- * \internal
- * \brief Convert the mISDN presentation to PresentedNumberUnscreened type
- *
- * \param presentation mISDN presentation to convert
- * \param number_present TRUE if the number is present
- *
- * \return PresentedNumberUnscreened type
- */
-static unsigned misdn_to_PresentedNumberUnscreened_type(int presentation, int number_present)
-{
-       unsigned type;
-
-       switch (presentation) {
-       case 0:/* allowed */
-               if (number_present) {
-                       type = 0;/* presentationAllowedNumber */
-               } else {
-                       type = 2;/* numberNotAvailableDueToInterworking */
-               }
-               break;
-       case 1:/* restricted */
-               if (number_present) {
-                       type = 3;/* presentationRestrictedNumber */
-               } else {
-                       type = 1;/* presentationRestricted */
-               }
-               break;
-       default:
-               type = 2;/* numberNotAvailableDueToInterworking */
-               break;
-       }
-
-       return type;
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-/*!
- * \internal
- * \brief Convert the PresentedNumberUnscreened type to mISDN presentation
- *
- * \param type PresentedNumberUnscreened type
- *
- * \return mISDN presentation
- */
-static int PresentedNumberUnscreened_to_misdn_pres(unsigned type)
-{
-       int presentation;
-
-       switch (type) {
-       default:
-       case 0:/* presentationAllowedNumber */
-               presentation = 0;/* allowed */
-               break;
-
-       case 1:/* presentationRestricted */
-       case 3:/* presentationRestrictedNumber */
-               presentation = 1;/* restricted */
-               break;
-
-       case 2:/* numberNotAvailableDueToInterworking */
-               presentation = 2;/* unavailable */
-               break;
-       }
-
-       return presentation;
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-/*!
- * \internal
- * \brief Convert the mISDN numbering plan to PartyNumber numbering plan
- *
- * \param number_plan mISDN numbering plan
- *
- * \return PartyNumber numbering plan
- */
-static unsigned misdn_to_PartyNumber_plan(enum mISDN_NUMBER_PLAN number_plan)
-{
-       unsigned party_plan;
-
-       switch (number_plan) {
-       default:
-       case NUMPLAN_UNKNOWN:
-               party_plan = 0;/* unknown */
-               break;
-
-       case NUMPLAN_ISDN:
-               party_plan = 1;/* public */
-               break;
-
-       case NUMPLAN_DATA:
-               party_plan = 3;/* data */
-               break;
-
-       case NUMPLAN_TELEX:
-               party_plan = 4;/* telex */
-               break;
-
-       case NUMPLAN_NATIONAL:
-               party_plan = 8;/* nationalStandard */
-               break;
-
-       case NUMPLAN_PRIVATE:
-               party_plan = 5;/* private */
-               break;
-       }
-
-       return party_plan;
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-/*!
- * \internal
- * \brief Convert PartyNumber numbering plan to mISDN numbering plan
- *
- * \param party_plan PartyNumber numbering plan
- *
- * \return mISDN numbering plan
- */
-static enum mISDN_NUMBER_PLAN PartyNumber_to_misdn_plan(unsigned party_plan)
-{
-       enum mISDN_NUMBER_PLAN number_plan;
-
-       switch (party_plan) {
-       default:
-       case 0:/* unknown */
-               number_plan = NUMPLAN_UNKNOWN;
-               break;
-       case 1:/* public */
-               number_plan = NUMPLAN_ISDN;
-               break;
-       case 3:/* data */
-               number_plan = NUMPLAN_DATA;
-               break;
-       case 4:/* telex */
-               number_plan = NUMPLAN_TELEX;
-               break;
-       case 8:/* nationalStandard */
-               number_plan = NUMPLAN_NATIONAL;
-               break;
-       case 5:/* private */
-               number_plan = NUMPLAN_PRIVATE;
-               break;
-       }
-
-       return number_plan;
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-/*!
- * \internal
- * \brief Convert mISDN type-of-number to PartyNumber public type-of-number
- *
- * \param ton mISDN type-of-number
- *
- * \return PartyNumber public type-of-number
- */
-static unsigned misdn_to_PartyNumber_ton_public(enum mISDN_NUMBER_TYPE ton)
-{
-       unsigned party_ton;
-
-       switch (ton) {
-       default:
-       case NUMTYPE_UNKNOWN:
-               party_ton = 0;/* unknown */
-               break;
-
-       case NUMTYPE_INTERNATIONAL:
-               party_ton = 1;/* internationalNumber */
-               break;
-
-       case NUMTYPE_NATIONAL:
-               party_ton = 2;/* nationalNumber */
-               break;
-
-       case NUMTYPE_NETWORK_SPECIFIC:
-               party_ton = 3;/* networkSpecificNumber */
-               break;
-
-       case NUMTYPE_SUBSCRIBER:
-               party_ton = 4;/* subscriberNumber */
-               break;
-
-       case NUMTYPE_ABBREVIATED:
-               party_ton = 6;/* abbreviatedNumber */
-               break;
-       }
-
-       return party_ton;
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-/*!
- * \internal
- * \brief Convert the PartyNumber public type-of-number to mISDN type-of-number
- *
- * \param party_ton PartyNumber public type-of-number
- *
- * \return mISDN type-of-number
- */
-static enum mISDN_NUMBER_TYPE PartyNumber_to_misdn_ton_public(unsigned party_ton)
-{
-       enum mISDN_NUMBER_TYPE ton;
-
-       switch (party_ton) {
-       default:
-       case 0:/* unknown */
-               ton = NUMTYPE_UNKNOWN;
-               break;
-
-       case 1:/* internationalNumber */
-               ton = NUMTYPE_INTERNATIONAL;
-               break;
-
-       case 2:/* nationalNumber */
-               ton = NUMTYPE_NATIONAL;
-               break;
-
-       case 3:/* networkSpecificNumber */
-               ton = NUMTYPE_NETWORK_SPECIFIC;
-               break;
-
-       case 4:/* subscriberNumber */
-               ton = NUMTYPE_SUBSCRIBER;
-               break;
-
-       case 6:/* abbreviatedNumber */
-               ton = NUMTYPE_ABBREVIATED;
-               break;
-       }
-
-       return ton;
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-/*!
- * \internal
- * \brief Convert mISDN type-of-number to PartyNumber private type-of-number
- *
- * \param ton mISDN type-of-number
- *
- * \return PartyNumber private type-of-number
- */
-static unsigned misdn_to_PartyNumber_ton_private(enum mISDN_NUMBER_TYPE ton)
-{
-       unsigned party_ton;
-
-       switch (ton) {
-       default:
-       case NUMTYPE_UNKNOWN:
-               party_ton = 0;/* unknown */
-               break;
-
-       case NUMTYPE_INTERNATIONAL:
-               party_ton = 1;/* level2RegionalNumber */
-               break;
-
-       case NUMTYPE_NATIONAL:
-               party_ton = 2;/* level1RegionalNumber */
-               break;
-
-       case NUMTYPE_NETWORK_SPECIFIC:
-               party_ton = 3;/* pTNSpecificNumber */
-               break;
-
-       case NUMTYPE_SUBSCRIBER:
-               party_ton = 4;/* localNumber */
-               break;
-
-       case NUMTYPE_ABBREVIATED:
-               party_ton = 6;/* abbreviatedNumber */
-               break;
-       }
-
-       return party_ton;
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-/*!
- * \internal
- * \brief Convert the PartyNumber private type-of-number to mISDN type-of-number
- *
- * \param party_ton PartyNumber private type-of-number
- *
- * \return mISDN type-of-number
- */
-static enum mISDN_NUMBER_TYPE PartyNumber_to_misdn_ton_private(unsigned party_ton)
-{
-       enum mISDN_NUMBER_TYPE ton;
-
-       switch (party_ton) {
-       default:
-       case 0:/* unknown */
-               ton = NUMTYPE_UNKNOWN;
-               break;
-
-       case 1:/* level2RegionalNumber */
-               ton = NUMTYPE_INTERNATIONAL;
-               break;
-
-       case 2:/* level1RegionalNumber */
-               ton = NUMTYPE_NATIONAL;
-               break;
-
-       case 3:/* pTNSpecificNumber */
-               ton = NUMTYPE_NETWORK_SPECIFIC;
-               break;
-
-       case 4:/* localNumber */
-               ton = NUMTYPE_SUBSCRIBER;
-               break;
-
-       case 6:/* abbreviatedNumber */
-               ton = NUMTYPE_ABBREVIATED;
-               break;
-       }
-
-       return ton;
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-/*!
- * \internal
- * \brief Convert the mISDN type of number code to a string
- *
- * \param number_type mISDN type of number code.
- *
- * \return The mISDN type of number code as a string
- */
-static const char *misdn_to_str_ton(enum mISDN_NUMBER_TYPE number_type)
-{
-       const char *str;
-
-       switch (number_type) {
-       default:
-       case NUMTYPE_UNKNOWN:
-               str = "Unknown";
-               break;
-
-       case NUMTYPE_INTERNATIONAL:
-               str = "International";
-               break;
-
-       case NUMTYPE_NATIONAL:
-               str = "National";
-               break;
-
-       case NUMTYPE_NETWORK_SPECIFIC:
-               str = "Network Specific";
-               break;
-
-       case NUMTYPE_SUBSCRIBER:
-               str = "Subscriber";
-               break;
-
-       case NUMTYPE_ABBREVIATED:
-               str = "Abbreviated";
-               break;
-       }
-
-       return str;
-}
-
-/*!
- * \internal
- * \brief Convert the mISDN type of number code to Asterisk type of number code
- *
- * \param number_type mISDN type of number code.
- *
- * \return Asterisk type of number code
- */
-static int misdn_to_ast_ton(enum mISDN_NUMBER_TYPE number_type)
-{
-       int ast_number_type;
-
-       switch (number_type) {
-       default:
-       case NUMTYPE_UNKNOWN:
-               ast_number_type = NUMTYPE_UNKNOWN << 4;
-               break;
-
-       case NUMTYPE_INTERNATIONAL:
-               ast_number_type = NUMTYPE_INTERNATIONAL << 4;
-               break;
-
-       case NUMTYPE_NATIONAL:
-               ast_number_type = NUMTYPE_NATIONAL << 4;
-               break;
-
-       case NUMTYPE_NETWORK_SPECIFIC:
-               ast_number_type = NUMTYPE_NETWORK_SPECIFIC << 4;
-               break;
-
-       case NUMTYPE_SUBSCRIBER:
-               ast_number_type = NUMTYPE_SUBSCRIBER << 4;
-               break;
-
-       case NUMTYPE_ABBREVIATED:
-               ast_number_type = NUMTYPE_ABBREVIATED << 4;
-               break;
-       }
-
-       return ast_number_type;
-}
-
-/*!
- * \internal
- * \brief Convert the Asterisk type of number code to mISDN type of number code
- *
- * \param ast_number_type Asterisk type of number code.
- *
- * \return mISDN type of number code
- */
-static enum mISDN_NUMBER_TYPE ast_to_misdn_ton(unsigned ast_number_type)
-{
-       enum mISDN_NUMBER_TYPE number_type;
-
-       switch ((ast_number_type >> 4) & 0x07) {
-       default:
-       case NUMTYPE_UNKNOWN:
-               number_type = NUMTYPE_UNKNOWN;
-               break;
-
-       case NUMTYPE_INTERNATIONAL:
-               number_type = NUMTYPE_INTERNATIONAL;
-               break;
-
-       case NUMTYPE_NATIONAL:
-               number_type = NUMTYPE_NATIONAL;
-               break;
-
-       case NUMTYPE_NETWORK_SPECIFIC:
-               number_type = NUMTYPE_NETWORK_SPECIFIC;
-               break;
-
-       case NUMTYPE_SUBSCRIBER:
-               number_type = NUMTYPE_SUBSCRIBER;
-               break;
-
-       case NUMTYPE_ABBREVIATED:
-               number_type = NUMTYPE_ABBREVIATED;
-               break;
-       }
-
-       return number_type;
-}
-
-/*!
- * \internal
- * \brief Convert the mISDN numbering plan code to a string
- *
- * \param number_plan mISDN numbering plan code.
- *
- * \return The mISDN numbering plan code as a string
- */
-static const char *misdn_to_str_plan(enum mISDN_NUMBER_PLAN number_plan)
-{
-       const char *str;
-
-       switch (number_plan) {
-       default:
-       case NUMPLAN_UNKNOWN:
-               str = "Unknown";
-               break;
-
-       case NUMPLAN_ISDN:
-               str = "ISDN";
-               break;
-
-       case NUMPLAN_DATA:
-               str = "Data";
-               break;
-
-       case NUMPLAN_TELEX:
-               str = "Telex";
-               break;
-
-       case NUMPLAN_NATIONAL:
-               str = "National";
-               break;
-
-       case NUMPLAN_PRIVATE:
-               str = "Private";
-               break;
-       }
-
-       return str;
-}
-
-/*!
- * \internal
- * \brief Convert the mISDN numbering plan code to Asterisk numbering plan code
- *
- * \param number_plan mISDN numbering plan code.
- *
- * \return Asterisk numbering plan code
- */
-static int misdn_to_ast_plan(enum mISDN_NUMBER_PLAN number_plan)
-{
-       int ast_number_plan;
-
-       switch (number_plan) {
-       default:
-       case NUMPLAN_UNKNOWN:
-               ast_number_plan = NUMPLAN_UNKNOWN;
-               break;
-
-       case NUMPLAN_ISDN:
-               ast_number_plan = NUMPLAN_ISDN;
-               break;
-
-       case NUMPLAN_DATA:
-               ast_number_plan = NUMPLAN_DATA;
-               break;
-
-       case NUMPLAN_TELEX:
-               ast_number_plan = NUMPLAN_TELEX;
-               break;
-
-       case NUMPLAN_NATIONAL:
-               ast_number_plan = NUMPLAN_NATIONAL;
-               break;
-
-       case NUMPLAN_PRIVATE:
-               ast_number_plan = NUMPLAN_PRIVATE;
-               break;
-       }
-
-       return ast_number_plan;
-}
-
-/*!
- * \internal
- * \brief Convert the Asterisk numbering plan code to mISDN numbering plan code
- *
- * \param ast_number_plan Asterisk numbering plan code.
- *
- * \return mISDN numbering plan code
- */
-static enum mISDN_NUMBER_PLAN ast_to_misdn_plan(unsigned ast_number_plan)
-{
-       enum mISDN_NUMBER_PLAN number_plan;
-
-       switch (ast_number_plan & 0x0F) {
-       default:
-       case NUMPLAN_UNKNOWN:
-               number_plan = NUMPLAN_UNKNOWN;
-               break;
-
-       case NUMPLAN_ISDN:
-               number_plan = NUMPLAN_ISDN;
-               break;
-
-       case NUMPLAN_DATA:
-               number_plan = NUMPLAN_DATA;
-               break;
-
-       case NUMPLAN_TELEX:
-               number_plan = NUMPLAN_TELEX;
-               break;
-
-       case NUMPLAN_NATIONAL:
-               number_plan = NUMPLAN_NATIONAL;
-               break;
-
-       case NUMPLAN_PRIVATE:
-               number_plan = NUMPLAN_PRIVATE;
-               break;
-       }
-
-       return number_plan;
-}
-
-/*!
- * \internal
- * \brief Convert the mISDN presentation code to a string
- *
- * \param presentation mISDN number presentation restriction code.
- *
- * \return The mISDN presentation code as a string
- */
-static const char *misdn_to_str_pres(int presentation)
-{
-       const char *str;
-
-       switch (presentation) {
-       case 0:
-               str = "Allowed";
-               break;
-
-       case 1:
-               str = "Restricted";
-               break;
-
-       case 2:
-               str = "Unavailable";
-               break;
-
-       default:
-               str = "Unknown";
-               break;
-       }
-
-       return str;
-}
-
-/*!
- * \internal
- * \brief Convert the mISDN presentation code to Asterisk presentation code
- *
- * \param presentation mISDN number presentation restriction code.
- *
- * \return Asterisk presentation code
- */
-static int misdn_to_ast_pres(int presentation)
-{
-       switch (presentation) {
-       default:
-       case 0:
-               presentation = AST_PRES_ALLOWED;
-               break;
-
-       case 1:
-               presentation = AST_PRES_RESTRICTED;
-               break;
-
-       case 2:
-               presentation = AST_PRES_UNAVAILABLE;
-               break;
-       }
-
-       return presentation;
-}
-
-/*!
- * \internal
- * \brief Convert the Asterisk presentation code to mISDN presentation code
- *
- * \param presentation Asterisk number presentation restriction code.
- *
- * \return mISDN presentation code
- */
-static int ast_to_misdn_pres(int presentation)
-{
-       switch (presentation & AST_PRES_RESTRICTION) {
-       default:
-       case AST_PRES_ALLOWED:
-               presentation = 0;
-               break;
-
-       case AST_PRES_RESTRICTED:
-               presentation = 1;
-               break;
-
-       case AST_PRES_UNAVAILABLE:
-               presentation = 2;
-               break;
-       }
-
-       return presentation;
-}
-
-/*!
- * \internal
- * \brief Convert the mISDN screening code to a string
- *
- * \param screening mISDN number screening code.
- *
- * \return The mISDN screening code as a string
- */
-static const char *misdn_to_str_screen(int screening)
-{
-       const char *str;
-
-       switch (screening) {
-       case 0:
-               str = "Unscreened";
-               break;
-
-       case 1:
-               str = "Passed Screen";
-               break;
-
-       case 2:
-               str = "Failed Screen";
-               break;
-
-       case 3:
-               str = "Network Number";
-               break;
-
-       default:
-               str = "Unknown";
-               break;
-       }
-
-       return str;
-}
-
-/*!
- * \internal
- * \brief Convert the mISDN screening code to Asterisk screening code
- *
- * \param screening mISDN number screening code.
- *
- * \return Asterisk screening code
- */
-static int misdn_to_ast_screen(int screening)
-{
-       switch (screening) {
-       default:
-       case 0:
-               screening = AST_PRES_USER_NUMBER_UNSCREENED;
-               break;
-
-       case 1:
-               screening = AST_PRES_USER_NUMBER_PASSED_SCREEN;
-               break;
-
-       case 2:
-               screening = AST_PRES_USER_NUMBER_FAILED_SCREEN;
-               break;
-
-       case 3:
-               screening = AST_PRES_NETWORK_NUMBER;
-               break;
-       }
-
-       return screening;
-}
-
-/*!
- * \internal
- * \brief Convert the Asterisk screening code to mISDN screening code
- *
- * \param screening Asterisk number screening code.
- *
- * \return mISDN screening code
- */
-static int ast_to_misdn_screen(int screening)
-{
-       switch (screening & AST_PRES_NUMBER_TYPE) {
-       default:
-       case AST_PRES_USER_NUMBER_UNSCREENED:
-               screening = 0;
-               break;
-
-       case AST_PRES_USER_NUMBER_PASSED_SCREEN:
-               screening = 1;
-               break;
-
-       case AST_PRES_USER_NUMBER_FAILED_SCREEN:
-               screening = 2;
-               break;
-
-       case AST_PRES_NETWORK_NUMBER:
-               screening = 3;
-               break;
-       }
-
-       return screening;
-}
-
-/*!
- * \internal
- * \brief Convert Asterisk redirecting reason to mISDN redirecting reason code.
- *
- * \param ast Asterisk redirecting reason code.
- *
- * \return mISDN reason code
- */
-static enum mISDN_REDIRECTING_REASON ast_to_misdn_reason(const enum AST_REDIRECTING_REASON ast)
-{
-       unsigned index;
-
-       static const struct misdn_reasons {
-               enum AST_REDIRECTING_REASON ast;
-               enum mISDN_REDIRECTING_REASON q931;
-       } misdn_reason_table[] = {
-       /* *INDENT-OFF* */
-               { AST_REDIRECTING_REASON_UNKNOWN,        mISDN_REDIRECTING_REASON_UNKNOWN },
-               { AST_REDIRECTING_REASON_USER_BUSY,      mISDN_REDIRECTING_REASON_CALL_FWD_BUSY },
-               { AST_REDIRECTING_REASON_NO_ANSWER,      mISDN_REDIRECTING_REASON_NO_REPLY },
-               { AST_REDIRECTING_REASON_UNAVAILABLE,    mISDN_REDIRECTING_REASON_NO_REPLY },
-               { AST_REDIRECTING_REASON_UNCONDITIONAL,  mISDN_REDIRECTING_REASON_CALL_FWD },
-               { AST_REDIRECTING_REASON_TIME_OF_DAY,    mISDN_REDIRECTING_REASON_UNKNOWN },
-               { AST_REDIRECTING_REASON_DO_NOT_DISTURB, mISDN_REDIRECTING_REASON_UNKNOWN },
-               { AST_REDIRECTING_REASON_DEFLECTION,     mISDN_REDIRECTING_REASON_DEFLECTION },
-               { AST_REDIRECTING_REASON_FOLLOW_ME,      mISDN_REDIRECTING_REASON_UNKNOWN },
-               { AST_REDIRECTING_REASON_OUT_OF_ORDER,   mISDN_REDIRECTING_REASON_OUT_OF_ORDER },
-               { AST_REDIRECTING_REASON_AWAY,           mISDN_REDIRECTING_REASON_UNKNOWN },
-               { AST_REDIRECTING_REASON_CALL_FWD_DTE,   mISDN_REDIRECTING_REASON_CALL_FWD_DTE }
-       /* *INDENT-ON* */
-       };
-
-       for (index = 0; index < ARRAY_LEN(misdn_reason_table); ++index) {
-               if (misdn_reason_table[index].ast == ast) {
-                       return misdn_reason_table[index].q931;
-               }
-       }
-       return mISDN_REDIRECTING_REASON_UNKNOWN;
-}
-
-/*!
- * \internal
- * \brief Convert the mISDN redirecting reason to Asterisk redirecting reason code
- *
- * \param q931 mISDN redirecting reason code.
- *
- * \return Asterisk redirecting reason code
- */
-static enum AST_REDIRECTING_REASON misdn_to_ast_reason(const enum mISDN_REDIRECTING_REASON q931)
-{
-       enum AST_REDIRECTING_REASON ast;
-
-       switch (q931) {
-       default:
-       case mISDN_REDIRECTING_REASON_UNKNOWN:
-               ast = AST_REDIRECTING_REASON_UNKNOWN;
-               break;
-
-       case mISDN_REDIRECTING_REASON_CALL_FWD_BUSY:
-               ast = AST_REDIRECTING_REASON_USER_BUSY;
-               break;
-
-       case mISDN_REDIRECTING_REASON_NO_REPLY:
-               ast = AST_REDIRECTING_REASON_NO_ANSWER;
-               break;
-
-       case mISDN_REDIRECTING_REASON_DEFLECTION:
-               ast = AST_REDIRECTING_REASON_DEFLECTION;
-               break;
-
-       case mISDN_REDIRECTING_REASON_OUT_OF_ORDER:
-               ast = AST_REDIRECTING_REASON_OUT_OF_ORDER;
-               break;
-
-       case mISDN_REDIRECTING_REASON_CALL_FWD_DTE:
-               ast = AST_REDIRECTING_REASON_CALL_FWD_DTE;
-               break;
-
-       case mISDN_REDIRECTING_REASON_CALL_FWD:
-               ast = AST_REDIRECTING_REASON_UNCONDITIONAL;
-               break;
-       }
-
-       return ast;
-}
-
-
-
-struct allowed_bearers {
-       char *name;         /*!< Bearer capability name string used in /etc/misdn.conf allowed_bearers */
-       char *display;      /*!< Bearer capability displayable name */
-       int cap;            /*!< SETUP message bearer capability field code value */
-       int deprecated;     /*!< TRUE if this entry is deprecated. (Misspelled or bad name to use) */
-};
-
-/* *INDENT-OFF* */
-static const struct allowed_bearers allowed_bearers_array[] = {
-       /* Name,                      Displayable Name       Bearer Capability,                    Deprecated */
-       { "speech",                  "Speech",               INFO_CAPABILITY_SPEECH,               0 },
-       { "3_1khz",                  "3.1KHz Audio",         INFO_CAPABILITY_AUDIO_3_1K,           0 },
-       { "digital_unrestricted",    "Unrestricted Digital", INFO_CAPABILITY_DIGITAL_UNRESTRICTED, 0 },
-       { "digital_restricted",      "Restricted Digital",   INFO_CAPABILITY_DIGITAL_RESTRICTED,   0 },
-       { "digital_restriced",       "Restricted Digital",   INFO_CAPABILITY_DIGITAL_RESTRICTED,   1 }, /* Allow misspelling for backwards compatibility */
-       { "video",                   "Video",                INFO_CAPABILITY_VIDEO,                0 }
-};
-/* *INDENT-ON* */
-
-static const char *bearer2str(int cap)
-{
-       unsigned index;
-
-       for (index = 0; index < ARRAY_LEN(allowed_bearers_array); ++index) {
-               if (allowed_bearers_array[index].cap == cap) {
-                       return allowed_bearers_array[index].display;
-               }
-       }
-
-       return "Unknown Bearer";
-}
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-/*!
- * \internal
- * \brief Fill in facility PartyNumber information
- *
- * \param party PartyNumber structure to fill in.
- * \param id Information to put in PartyNumber structure.
- *
- * \return Nothing
- */
-static void misdn_PartyNumber_fill(struct FacPartyNumber *party, const struct misdn_party_id *id)
-{
-       ast_copy_string((char *) party->Number, id->number, sizeof(party->Number));
-       party->LengthOfNumber = strlen((char *) party->Number);
-       party->Type = misdn_to_PartyNumber_plan(id->number_plan);
-       switch (party->Type) {
-       case 1:/* public */
-               party->TypeOfNumber = misdn_to_PartyNumber_ton_public(id->number_type);
-               break;
-       case 5:/* private */
-               party->TypeOfNumber = misdn_to_PartyNumber_ton_private(id->number_type);
-               break;
-       default:
-               party->TypeOfNumber = 0;/* Don't care */
-               break;
-       }
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-/*!
- * \internal
- * \brief Extract the information from PartyNumber
- *
- * \param id Where to put extracted PartyNumber information
- * \param party PartyNumber information to extract
- *
- * \return Nothing
- */
-static void misdn_PartyNumber_extract(struct misdn_party_id *id, const struct FacPartyNumber *party)
-{
-       if (party->LengthOfNumber) {
-               ast_copy_string(id->number, (char *) party->Number, sizeof(id->number));
-               id->number_plan = PartyNumber_to_misdn_plan(party->Type);
-               switch (party->Type) {
-               case 1:/* public */
-                       id->number_type = PartyNumber_to_misdn_ton_public(party->TypeOfNumber);
-                       break;
-               case 5:/* private */
-                       id->number_type = PartyNumber_to_misdn_ton_private(party->TypeOfNumber);
-                       break;
-               default:
-                       id->number_type = NUMTYPE_UNKNOWN;
-                       break;
-               }
-       } else {
-               /* Number not present */
-               id->number_type = NUMTYPE_UNKNOWN;
-               id->number_plan = NUMPLAN_ISDN;
-               id->number[0] = 0;
-       }
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-/*!
- * \internal
- * \brief Fill in facility Address information
- *
- * \param Address Address structure to fill in.
- * \param id Information to put in Address structure.
- *
- * \return Nothing
- */
-static void misdn_Address_fill(struct FacAddress *Address, const struct misdn_party_id *id)
-{
-       misdn_PartyNumber_fill(&Address->Party, id);
-
-       /* Subaddresses are not supported yet */
-       Address->Subaddress.Length = 0;
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-/*!
- * \internal
- * \brief Fill in facility PresentedNumberUnscreened information
- *
- * \param presented PresentedNumberUnscreened structure to fill in.
- * \param id Information to put in PresentedNumberUnscreened structure.
- *
- * \return Nothing
- */
-static void misdn_PresentedNumberUnscreened_fill(struct FacPresentedNumberUnscreened *presented, const struct misdn_party_id *id)
-{
-       presented->Type = misdn_to_PresentedNumberUnscreened_type(id->presentation, id->number[0] ? 1 : 0);
-       misdn_PartyNumber_fill(&presented->Unscreened, id);
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-/*!
- * \internal
- * \brief Extract the information from PartyNumber
- *
- * \param id Where to put extracted PresentedNumberUnscreened information
- * \param presented PresentedNumberUnscreened information to extract
- *
- * \return Nothing
- */
-static void misdn_PresentedNumberUnscreened_extract(struct misdn_party_id *id, const struct FacPresentedNumberUnscreened *presented)
-{
-       id->presentation = PresentedNumberUnscreened_to_misdn_pres(presented->Type);
-       id->screening = 0;/* unscreened */
-       switch (presented->Type) {
-       case 0:/* presentationAllowedNumber */
-       case 3:/* presentationRestrictedNumber */
-               misdn_PartyNumber_extract(id, &presented->Unscreened);
-               break;
-       case 1:/* presentationRestricted */
-       case 2:/* numberNotAvailableDueToInterworking */
-       default:
-               /* Number not present (And uninitialized so do not even look at it!) */
-               id->number_type = NUMTYPE_UNKNOWN;
-               id->number_plan = NUMPLAN_ISDN;
-               id->number[0] = 0;
-               break;
-       }
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-static const char Level_Spacing[] = "          ";/* Work for up to 10 levels */
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-static void print_facility_PartyNumber(unsigned Level, const struct FacPartyNumber *Party, const struct misdn_bchannel *bc)
-{
-       if (Party->LengthOfNumber) {
-               const char *Spacing;
-
-               Spacing = &Level_Spacing[sizeof(Level_Spacing) - 1 - Level];
-               chan_misdn_log(1, bc->port, " -->%s PartyNumber: Type:%d\n",
-                       Spacing, Party->Type);
-               switch (Party->Type) {
-               case 0: /* Unknown PartyNumber */
-                       chan_misdn_log(1, bc->port, " -->%s  Unknown: %s\n",
-                               Spacing, Party->Number);
-                       break;
-               case 1: /* Public PartyNumber */
-                       chan_misdn_log(1, bc->port, " -->%s  Public TON:%d %s\n",
-                               Spacing, Party->TypeOfNumber, Party->Number);
-                       break;
-               case 2: /* NSAP encoded PartyNumber */
-                       chan_misdn_log(1, bc->port, " -->%s  NSAP: %s\n",
-                               Spacing, Party->Number);
-                       break;
-               case 3: /* Data PartyNumber (Not used) */
-                       chan_misdn_log(1, bc->port, " -->%s  Data: %s\n",
-                               Spacing, Party->Number);
-                       break;
-               case 4: /* Telex PartyNumber (Not used) */
-                       chan_misdn_log(1, bc->port, " -->%s  Telex: %s\n",
-                               Spacing, Party->Number);
-                       break;
-               case 5: /* Private PartyNumber */
-                       chan_misdn_log(1, bc->port, " -->%s  Private TON:%d %s\n",
-                               Spacing, Party->TypeOfNumber, Party->Number);
-                       break;
-               case 8: /* National Standard PartyNumber (Not used) */
-                       chan_misdn_log(1, bc->port, " -->%s  National: %s\n",
-                               Spacing, Party->Number);
-                       break;
-               default:
-                       break;
-               }
-       }
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-static void print_facility_Subaddress(unsigned Level, const struct FacPartySubaddress *Subaddress, const struct misdn_bchannel *bc)
-{
-       if (Subaddress->Length) {
-               const char *Spacing;
-
-               Spacing = &Level_Spacing[sizeof(Level_Spacing) - 1 - Level];
-               chan_misdn_log(1, bc->port, " -->%s Subaddress: Type:%d\n",
-                       Spacing, Subaddress->Type);
-               switch (Subaddress->Type) {
-               case 0: /* UserSpecified */
-                       if (Subaddress->u.UserSpecified.OddCountPresent) {
-                               chan_misdn_log(1, bc->port, " -->%s  User BCD OddCount:%d NumOctets:%d\n",
-                                       Spacing, Subaddress->u.UserSpecified.OddCount, Subaddress->Length);
-                       } else {
-                               chan_misdn_log(1, bc->port, " -->%s  User: %s\n",
-                                       Spacing, Subaddress->u.UserSpecified.Information);
-                       }
-                       break;
-               case 1: /* NSAP */
-                       chan_misdn_log(1, bc->port, " -->%s  NSAP: %s\n",
-                               Spacing, Subaddress->u.Nsap);
-                       break;
-               default:
-                       break;
-               }
-       }
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-static void print_facility_Address(unsigned Level, const struct FacAddress *Address, const struct misdn_bchannel *bc)
-{
-       print_facility_PartyNumber(Level, &Address->Party, bc);
-       print_facility_Subaddress(Level, &Address->Subaddress, bc);
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-static void print_facility_PresentedNumberUnscreened(unsigned Level, const struct FacPresentedNumberUnscreened *Presented, const struct misdn_bchannel *bc)
-{
-       const char *Spacing;
-
-       Spacing = &Level_Spacing[sizeof(Level_Spacing) - 1 - Level];
-       chan_misdn_log(1, bc->port, " -->%s Unscreened Type:%d\n", Spacing, Presented->Type);
-       switch (Presented->Type) {
-       case 0: /* presentationAllowedNumber */
-               chan_misdn_log(1, bc->port, " -->%s  Allowed:\n", Spacing);
-               print_facility_PartyNumber(Level + 2, &Presented->Unscreened, bc);
-               break;
-       case 1: /* presentationRestricted */
-               chan_misdn_log(1, bc->port, " -->%s  Restricted\n", Spacing);
-               break;
-       case 2: /* numberNotAvailableDueToInterworking */
-               chan_misdn_log(1, bc->port, " -->%s  Not Available\n", Spacing);
-               break;
-       case 3: /* presentationRestrictedNumber */
-               chan_misdn_log(1, bc->port, " -->%s  Restricted:\n", Spacing);
-               print_facility_PartyNumber(Level + 2, &Presented->Unscreened, bc);
-               break;
-       default:
-               break;
-       }
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-static void print_facility_AddressScreened(unsigned Level, const struct FacAddressScreened *Address, const struct misdn_bchannel *bc)
-{
-       const char *Spacing;
-
-       Spacing = &Level_Spacing[sizeof(Level_Spacing) - 1 - Level];
-       chan_misdn_log(1, bc->port, " -->%s ScreeningIndicator:%d\n", Spacing, Address->ScreeningIndicator);
-       print_facility_PartyNumber(Level, &Address->Party, bc);
-       print_facility_Subaddress(Level, &Address->Subaddress, bc);
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-static void print_facility_PresentedAddressScreened(unsigned Level, const struct FacPresentedAddressScreened *Presented, const struct misdn_bchannel *bc)
-{
-       const char *Spacing;
-
-       Spacing = &Level_Spacing[sizeof(Level_Spacing) - 1 - Level];
-       chan_misdn_log(1, bc->port, " -->%s Screened Type:%d\n", Spacing, Presented->Type);
-       switch (Presented->Type) {
-       case 0: /* presentationAllowedAddress */
-               chan_misdn_log(1, bc->port, " -->%s  Allowed:\n", Spacing);
-               print_facility_AddressScreened(Level + 2, &Presented->Address, bc);
-               break;
-       case 1: /* presentationRestricted */
-               chan_misdn_log(1, bc->port, " -->%s  Restricted\n", Spacing);
-               break;
-       case 2: /* numberNotAvailableDueToInterworking */
-               chan_misdn_log(1, bc->port, " -->%s  Not Available\n", Spacing);
-               break;
-       case 3: /* presentationRestrictedAddress */
-               chan_misdn_log(1, bc->port, " -->%s  Restricted:\n", Spacing);
-               print_facility_AddressScreened(Level + 2, &Presented->Address, bc);
-               break;
-       default:
-               break;
-       }
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-static void print_facility_Q931_Bc_Hlc_Llc(unsigned Level, const struct Q931_Bc_Hlc_Llc *Q931ie, const struct misdn_bchannel *bc)
-{
-       const char *Spacing;
-
-       Spacing = &Level_Spacing[sizeof(Level_Spacing) - 1 - Level];
-       chan_misdn_log(1, bc->port, " -->%s Q931ie:\n", Spacing);
-       if (Q931ie->Bc.Length) {
-               chan_misdn_log(1, bc->port, " -->%s  Bc Len:%d\n", Spacing, Q931ie->Bc.Length);
-       }
-       if (Q931ie->Hlc.Length) {
-               chan_misdn_log(1, bc->port, " -->%s  Hlc Len:%d\n", Spacing, Q931ie->Hlc.Length);
-       }
-       if (Q931ie->Llc.Length) {
-               chan_misdn_log(1, bc->port, " -->%s  Llc Len:%d\n", Spacing, Q931ie->Llc.Length);
-       }
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-static void print_facility_Q931_Bc_Hlc_Llc_Uu(unsigned Level, const struct Q931_Bc_Hlc_Llc_Uu *Q931ie, const struct misdn_bchannel *bc)
-{
-       const char *Spacing;
-
-       Spacing = &Level_Spacing[sizeof(Level_Spacing) - 1 - Level];
-       chan_misdn_log(1, bc->port, " -->%s Q931ie:\n", Spacing);
-       if (Q931ie->Bc.Length) {
-               chan_misdn_log(1, bc->port, " -->%s  Bc Len:%d\n", Spacing, Q931ie->Bc.Length);
-       }
-       if (Q931ie->Hlc.Length) {
-               chan_misdn_log(1, bc->port, " -->%s  Hlc Len:%d\n", Spacing, Q931ie->Hlc.Length);
-       }
-       if (Q931ie->Llc.Length) {
-               chan_misdn_log(1, bc->port, " -->%s  Llc Len:%d\n", Spacing, Q931ie->Llc.Length);
-       }
-       if (Q931ie->UserInfo.Length) {
-               chan_misdn_log(1, bc->port, " -->%s  UserInfo Len:%d\n", Spacing, Q931ie->UserInfo.Length);
-       }
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-static void print_facility_CallInformation(unsigned Level, const struct FacCallInformation *CallInfo, const struct misdn_bchannel *bc)
-{
-       const char *Spacing;
-
-       Spacing = &Level_Spacing[sizeof(Level_Spacing) - 1 - Level];
-       chan_misdn_log(1, bc->port, " -->%s CCBSReference:%d\n",
-               Spacing, CallInfo->CCBSReference);
-       chan_misdn_log(1, bc->port, " -->%s AddressOfB:\n", Spacing);
-       print_facility_Address(Level + 1, &CallInfo->AddressOfB, bc);
-       print_facility_Q931_Bc_Hlc_Llc(Level, &CallInfo->Q931ie, bc);
-       if (CallInfo->SubaddressOfA.Length) {
-               chan_misdn_log(1, bc->port, " -->%s SubaddressOfA:\n", Spacing);
-               print_facility_Subaddress(Level + 1, &CallInfo->SubaddressOfA, bc);
-       }
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-static void print_facility_ServedUserNr(unsigned Level, const struct FacPartyNumber *Party, const struct misdn_bchannel *bc)
-{
-       const char *Spacing;
-
-       Spacing = &Level_Spacing[sizeof(Level_Spacing) - 1 - Level];
-       if (Party->LengthOfNumber) {
-               print_facility_PartyNumber(Level, Party, bc);
-       } else {
-               chan_misdn_log(1, bc->port, " -->%s All Numbers\n", Spacing);
-       }
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-static void print_facility_IntResult(unsigned Level, const struct FacForwardingRecord *ForwardingRecord, const struct misdn_bchannel *bc)
-{
-       const char *Spacing;
-
-       Spacing = &Level_Spacing[sizeof(Level_Spacing) - 1 - Level];
-       chan_misdn_log(1, bc->port, " -->%s Procedure:%d BasicService:%d\n",
-               Spacing,
-               ForwardingRecord->Procedure,
-               ForwardingRecord->BasicService);
-       chan_misdn_log(1, bc->port, " -->%s ForwardedTo:\n", Spacing);
-       print_facility_Address(Level + 1, &ForwardingRecord->ForwardedTo, bc);
-       chan_misdn_log(1, bc->port, " -->%s ServedUserNr:\n", Spacing);
-       print_facility_ServedUserNr(Level + 1, &ForwardingRecord->ServedUser, bc);
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-static void print_facility(const struct FacParm *fac, const struct misdn_bchannel *bc)
-{
-#if defined(AST_MISDN_ENHANCEMENTS)
-       unsigned Index;
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-       switch (fac->Function) {
-#if defined(AST_MISDN_ENHANCEMENTS)
-       case Fac_ActivationDiversion:
-               chan_misdn_log(1, bc->port, " --> ActivationDiversion: InvokeID:%d\n",
-                       fac->u.ActivationDiversion.InvokeID);
-               switch (fac->u.ActivationDiversion.ComponentType) {
-               case FacComponent_Invoke:
-                       chan_misdn_log(1, bc->port, " -->  Invoke: Procedure:%d BasicService:%d\n",
-                               fac->u.ActivationDiversion.Component.Invoke.Procedure,
-                               fac->u.ActivationDiversion.Component.Invoke.BasicService);
-                       chan_misdn_log(1, bc->port, " -->   ForwardedTo:\n");
-                       print_facility_Address(3, &fac->u.ActivationDiversion.Component.Invoke.ForwardedTo, bc);
-                       chan_misdn_log(1, bc->port, " -->   ServedUserNr:\n");
-                       print_facility_ServedUserNr(3, &fac->u.ActivationDiversion.Component.Invoke.ServedUser, bc);
-                       break;
-               case FacComponent_Result:
-                       chan_misdn_log(1, bc->port, " -->  Result\n");
-                       break;
-               default:
-                       break;
-               }
-               break;
-       case Fac_DeactivationDiversion:
-               chan_misdn_log(1, bc->port, " --> DeactivationDiversion: InvokeID:%d\n",
-                       fac->u.DeactivationDiversion.InvokeID);
-               switch (fac->u.DeactivationDiversion.ComponentType) {
-               case FacComponent_Invoke:
-                       chan_misdn_log(1, bc->port, " -->  Invoke: Procedure:%d BasicService:%d\n",
-                               fac->u.DeactivationDiversion.Component.Invoke.Procedure,
-                               fac->u.DeactivationDiversion.Component.Invoke.BasicService);
-                       chan_misdn_log(1, bc->port, " -->   ServedUserNr:\n");
-                       print_facility_ServedUserNr(3, &fac->u.DeactivationDiversion.Component.Invoke.ServedUser, bc);
-                       break;
-               case FacComponent_Result:
-                       chan_misdn_log(1, bc->port, " -->  Result\n");
-                       break;
-               default:
-                       break;
-               }
-               break;
-       case Fac_ActivationStatusNotificationDiv:
-               chan_misdn_log(1, bc->port, " --> ActivationStatusNotificationDiv: InvokeID:%d Procedure:%d BasicService:%d\n",
-                       fac->u.ActivationStatusNotificationDiv.InvokeID,
-                       fac->u.ActivationStatusNotificationDiv.Procedure,
-                       fac->u.ActivationStatusNotificationDiv.BasicService);
-               chan_misdn_log(1, bc->port, " -->  ForwardedTo:\n");
-               print_facility_Address(2, &fac->u.ActivationStatusNotificationDiv.ForwardedTo, bc);
-               chan_misdn_log(1, bc->port, " -->  ServedUserNr:\n");
-               print_facility_ServedUserNr(2, &fac->u.ActivationStatusNotificationDiv.ServedUser, bc);
-               break;
-       case Fac_DeactivationStatusNotificationDiv:
-               chan_misdn_log(1, bc->port, " --> DeactivationStatusNotificationDiv: InvokeID:%d Procedure:%d BasicService:%d\n",
-                       fac->u.DeactivationStatusNotificationDiv.InvokeID,
-                       fac->u.DeactivationStatusNotificationDiv.Procedure,
-                       fac->u.DeactivationStatusNotificationDiv.BasicService);
-               chan_misdn_log(1, bc->port, " -->  ServedUserNr:\n");
-               print_facility_ServedUserNr(2, &fac->u.DeactivationStatusNotificationDiv.ServedUser, bc);
-               break;
-       case Fac_InterrogationDiversion:
-               chan_misdn_log(1, bc->port, " --> InterrogationDiversion: InvokeID:%d\n",
-                       fac->u.InterrogationDiversion.InvokeID);
-               switch (fac->u.InterrogationDiversion.ComponentType) {
-               case FacComponent_Invoke:
-                       chan_misdn_log(1, bc->port, " -->  Invoke: Procedure:%d BasicService:%d\n",
-                               fac->u.InterrogationDiversion.Component.Invoke.Procedure,
-                               fac->u.InterrogationDiversion.Component.Invoke.BasicService);
-                       chan_misdn_log(1, bc->port, " -->   ServedUserNr:\n");
-                       print_facility_ServedUserNr(3, &fac->u.InterrogationDiversion.Component.Invoke.ServedUser, bc);
-                       break;
-               case FacComponent_Result:
-                       chan_misdn_log(1, bc->port, " -->  Result:\n");
-                       if (fac->u.InterrogationDiversion.Component.Result.NumRecords) {
-                               for (Index = 0; Index < fac->u.InterrogationDiversion.Component.Result.NumRecords; ++Index) {
-                                       chan_misdn_log(1, bc->port, " -->   IntResult[%d]:\n", Index);
-                                       print_facility_IntResult(3, &fac->u.InterrogationDiversion.Component.Result.List[Index], bc);
-                               }
-                       }
-                       break;
-               default:
-                       break;
-               }
-               break;
-       case Fac_DiversionInformation:
-               chan_misdn_log(1, bc->port, " --> DiversionInformation: InvokeID:%d Reason:%d BasicService:%d\n",
-                       fac->u.DiversionInformation.InvokeID,
-                       fac->u.DiversionInformation.DiversionReason,
-                       fac->u.DiversionInformation.BasicService);
-               if (fac->u.DiversionInformation.ServedUserSubaddress.Length) {
-                       chan_misdn_log(1, bc->port, " -->  ServedUserSubaddress:\n");
-                       print_facility_Subaddress(2, &fac->u.DiversionInformation.ServedUserSubaddress, bc);
-               }
-               if (fac->u.DiversionInformation.CallingAddressPresent) {
-                       chan_misdn_log(1, bc->port, " -->  CallingAddress:\n");
-                       print_facility_PresentedAddressScreened(2, &fac->u.DiversionInformation.CallingAddress, bc);
-               }
-               if (fac->u.DiversionInformation.OriginalCalledPresent) {
-                       chan_misdn_log(1, bc->port, " -->  OriginalCalledNr:\n");
-                       print_facility_PresentedNumberUnscreened(2, &fac->u.DiversionInformation.OriginalCalled, bc);
-               }
-               if (fac->u.DiversionInformation.LastDivertingPresent) {
-                       chan_misdn_log(1, bc->port, " -->  LastDivertingNr:\n");
-                       print_facility_PresentedNumberUnscreened(2, &fac->u.DiversionInformation.LastDiverting, bc);
-               }
-               if (fac->u.DiversionInformation.LastDivertingReasonPresent) {
-                       chan_misdn_log(1, bc->port, " -->  LastDivertingReason:%d\n", fac->u.DiversionInformation.LastDivertingReason);
-               }
-               if (fac->u.DiversionInformation.UserInfo.Length) {
-                       chan_misdn_log(1, bc->port, " -->  UserInfo Length:%d\n", fac->u.DiversionInformation.UserInfo.Length);
-               }
-               break;
-       case Fac_CallDeflection:
-               chan_misdn_log(1, bc->port, " --> CallDeflection: InvokeID:%d\n",
-                       fac->u.CallDeflection.InvokeID);
-               switch (fac->u.CallDeflection.ComponentType) {
-               case FacComponent_Invoke:
-                       chan_misdn_log(1, bc->port, " -->  Invoke:\n");
-                       if (fac->u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUserPresent) {
-                               chan_misdn_log(1, bc->port, " -->   PresentationAllowed:%d\n",
-                                       fac->u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUser);
-                       }
-                       chan_misdn_log(1, bc->port, " -->   DeflectionAddress:\n");
-                       print_facility_Address(3, &fac->u.CallDeflection.Component.Invoke.Deflection, bc);
-                       break;
-               case FacComponent_Result:
-                       chan_misdn_log(1, bc->port, " -->  Result\n");
-                       break;
-               default:
-                       break;
-               }
-               break;
-       case Fac_CallRerouteing:
-               chan_misdn_log(1, bc->port, " --> CallRerouteing: InvokeID:%d\n",
-                       fac->u.CallRerouteing.InvokeID);
-               switch (fac->u.CallRerouteing.ComponentType) {
-               case FacComponent_Invoke:
-                       chan_misdn_log(1, bc->port, " -->  Invoke: Reason:%d Counter:%d\n",
-                               fac->u.CallRerouteing.Component.Invoke.ReroutingReason,
-                               fac->u.CallRerouteing.Component.Invoke.ReroutingCounter);
-                       chan_misdn_log(1, bc->port, " -->   CalledAddress:\n");
-                       print_facility_Address(3, &fac->u.CallRerouteing.Component.Invoke.CalledAddress, bc);
-                       print_facility_Q931_Bc_Hlc_Llc_Uu(2, &fac->u.CallRerouteing.Component.Invoke.Q931ie, bc);
-                       chan_misdn_log(1, bc->port, " -->   LastReroutingNr:\n");
-                       print_facility_PresentedNumberUnscreened(3, &fac->u.CallRerouteing.Component.Invoke.LastRerouting, bc);
-                       chan_misdn_log(1, bc->port, " -->   SubscriptionOption:%d\n",
-                               fac->u.CallRerouteing.Component.Invoke.SubscriptionOption);
-                       if (fac->u.CallRerouteing.Component.Invoke.CallingPartySubaddress.Length) {
-                               chan_misdn_log(1, bc->port, " -->   CallingParty:\n");
-                               print_facility_Subaddress(3, &fac->u.CallRerouteing.Component.Invoke.CallingPartySubaddress, bc);
-                       }
-                       break;
-               case FacComponent_Result:
-                       chan_misdn_log(1, bc->port, " -->  Result\n");
-                       break;
-               default:
-                       break;
-               }
-               break;
-       case Fac_InterrogateServedUserNumbers:
-               chan_misdn_log(1, bc->port, " --> InterrogateServedUserNumbers: InvokeID:%d\n",
-                       fac->u.InterrogateServedUserNumbers.InvokeID);
-               switch (fac->u.InterrogateServedUserNumbers.ComponentType) {
-               case FacComponent_Invoke:
-                       chan_misdn_log(1, bc->port, " -->  Invoke\n");
-                       break;
-               case FacComponent_Result:
-                       chan_misdn_log(1, bc->port, " -->  Result:\n");
-                       if (fac->u.InterrogateServedUserNumbers.Component.Result.NumRecords) {
-                               for (Index = 0; Index < fac->u.InterrogateServedUserNumbers.Component.Result.NumRecords; ++Index) {
-                                       chan_misdn_log(1, bc->port, " -->   ServedUserNr[%d]:\n", Index);
-                                       print_facility_PartyNumber(3, &fac->u.InterrogateServedUserNumbers.Component.Result.List[Index], bc);
-                               }
-                       }
-                       break;
-               default:
-                       break;
-               }
-               break;
-       case Fac_DivertingLegInformation1:
-               chan_misdn_log(1, bc->port, " --> DivertingLegInformation1: InvokeID:%d Reason:%d SubscriptionOption:%d\n",
-                       fac->u.DivertingLegInformation1.InvokeID,
-                       fac->u.DivertingLegInformation1.DiversionReason,
-                       fac->u.DivertingLegInformation1.SubscriptionOption);
-               if (fac->u.DivertingLegInformation1.DivertedToPresent) {
-                       chan_misdn_log(1, bc->port, " -->  DivertedToNr:\n");
-                       print_facility_PresentedNumberUnscreened(2, &fac->u.DivertingLegInformation1.DivertedTo, bc);
-               }
-               break;
-       case Fac_DivertingLegInformation2:
-               chan_misdn_log(1, bc->port, " --> DivertingLegInformation2: InvokeID:%d Reason:%d Count:%d\n",
-                       fac->u.DivertingLegInformation2.InvokeID,
-                       fac->u.DivertingLegInformation2.DiversionReason,
-                       fac->u.DivertingLegInformation2.DiversionCounter);
-               if (fac->u.DivertingLegInformation2.DivertingPresent) {
-                       chan_misdn_log(1, bc->port, " -->  DivertingNr:\n");
-                       print_facility_PresentedNumberUnscreened(2, &fac->u.DivertingLegInformation2.Diverting, bc);
-               }
-               if (fac->u.DivertingLegInformation2.OriginalCalledPresent) {
-                       chan_misdn_log(1, bc->port, " -->  OriginalCalledNr:\n");
-                       print_facility_PresentedNumberUnscreened(2, &fac->u.DivertingLegInformation2.OriginalCalled, bc);
-               }
-               break;
-       case Fac_DivertingLegInformation3:
-               chan_misdn_log(1, bc->port, " --> DivertingLegInformation3: InvokeID:%d PresentationAllowed:%d\n",
-                       fac->u.DivertingLegInformation3.InvokeID,
-                       fac->u.DivertingLegInformation3.PresentationAllowedIndicator);
-               break;
-
-#else  /* !defined(AST_MISDN_ENHANCEMENTS) */
-
-       case Fac_CD:
-               chan_misdn_log(1, bc->port, " --> calldeflect to: %s, presentable: %s\n", fac->u.CDeflection.DeflectedToNumber,
-                       fac->u.CDeflection.PresentationAllowed ? "yes" : "no");
-               break;
-#endif /* !defined(AST_MISDN_ENHANCEMENTS) */
-       case Fac_AOCDCurrency:
-               if (fac->u.AOCDcur.chargeNotAvailable) {
-                       chan_misdn_log(1, bc->port, " --> AOCD currency: charge not available\n");
-               } else if (fac->u.AOCDcur.freeOfCharge) {
-                       chan_misdn_log(1, bc->port, " --> AOCD currency: free of charge\n");
-               } else if (fac->u.AOCDchu.billingId >= 0) {
-                       chan_misdn_log(1, bc->port, " --> AOCD currency: currency:%s amount:%d multiplier:%d typeOfChargingInfo:%s billingId:%d\n",
-                               fac->u.AOCDcur.currency, fac->u.AOCDcur.currencyAmount, fac->u.AOCDcur.multiplier,
-                               (fac->u.AOCDcur.typeOfChargingInfo == 0) ? "subTotal" : "total", fac->u.AOCDcur.billingId);
-               } else {
-                       chan_misdn_log(1, bc->port, " --> AOCD currency: currency:%s amount:%d multiplier:%d typeOfChargingInfo:%s\n",
-                               fac->u.AOCDcur.currency, fac->u.AOCDcur.currencyAmount, fac->u.AOCDcur.multiplier,
-                               (fac->u.AOCDcur.typeOfChargingInfo == 0) ? "subTotal" : "total");
-               }
-               break;
-       case Fac_AOCDChargingUnit:
-               if (fac->u.AOCDchu.chargeNotAvailable) {
-                       chan_misdn_log(1, bc->port, " --> AOCD charging unit: charge not available\n");
-               } else if (fac->u.AOCDchu.freeOfCharge) {
-                       chan_misdn_log(1, bc->port, " --> AOCD charging unit: free of charge\n");
-               } else if (fac->u.AOCDchu.billingId >= 0) {
-                       chan_misdn_log(1, bc->port, " --> AOCD charging unit: recordedUnits:%d typeOfChargingInfo:%s billingId:%d\n",
-                               fac->u.AOCDchu.recordedUnits, (fac->u.AOCDchu.typeOfChargingInfo == 0) ? "subTotal" : "total", fac->u.AOCDchu.billingId);
-               } else {
-                       chan_misdn_log(1, bc->port, " --> AOCD charging unit: recordedUnits:%d typeOfChargingInfo:%s\n",
-                               fac->u.AOCDchu.recordedUnits, (fac->u.AOCDchu.typeOfChargingInfo == 0) ? "subTotal" : "total");
-               }
-               break;
-#if defined(AST_MISDN_ENHANCEMENTS)
-       case Fac_ERROR:
-               chan_misdn_log(1, bc->port, " --> ERROR: InvokeID:%d, Code:0x%02x\n",
-                       fac->u.ERROR.invokeId, fac->u.ERROR.errorValue);
-               break;
-       case Fac_RESULT:
-               chan_misdn_log(1, bc->port, " --> RESULT: InvokeID:%d\n",
-                       fac->u.RESULT.InvokeID);
-               break;
-       case Fac_REJECT:
-               if (fac->u.REJECT.InvokeIDPresent) {
-                       chan_misdn_log(1, bc->port, " --> REJECT: InvokeID:%d, Code:0x%02x\n",
-                               fac->u.REJECT.InvokeID, fac->u.REJECT.Code);
-               } else {
-                       chan_misdn_log(1, bc->port, " --> REJECT: Code:0x%02x\n",
-                               fac->u.REJECT.Code);
-               }
-               break;
-       case Fac_EctExecute:
-               chan_misdn_log(1, bc->port, " --> EctExecute: InvokeID:%d\n",
-                       fac->u.EctExecute.InvokeID);
-               break;
-       case Fac_ExplicitEctExecute:
-               chan_misdn_log(1, bc->port, " --> ExplicitEctExecute: InvokeID:%d LinkID:%d\n",
-                       fac->u.ExplicitEctExecute.InvokeID,
-                       fac->u.ExplicitEctExecute.LinkID);
-               break;
-       case Fac_RequestSubaddress:
-               chan_misdn_log(1, bc->port, " --> RequestSubaddress: InvokeID:%d\n",
-                       fac->u.RequestSubaddress.InvokeID);
-               break;
-       case Fac_SubaddressTransfer:
-               chan_misdn_log(1, bc->port, " --> SubaddressTransfer: InvokeID:%d\n",
-                       fac->u.SubaddressTransfer.InvokeID);
-               print_facility_Subaddress(1, &fac->u.SubaddressTransfer.Subaddress, bc);
-               break;
-       case Fac_EctLinkIdRequest:
-               chan_misdn_log(1, bc->port, " --> EctLinkIdRequest: InvokeID:%d\n",
-                       fac->u.EctLinkIdRequest.InvokeID);
-               switch (fac->u.EctLinkIdRequest.ComponentType) {
-               case FacComponent_Invoke:
-                       chan_misdn_log(1, bc->port, " -->  Invoke\n");
-                       break;
-               case FacComponent_Result:
-                       chan_misdn_log(1, bc->port, " -->  Result: LinkID:%d\n",
-                               fac->u.EctLinkIdRequest.Component.Result.LinkID);
-                       break;
-               default:
-                       break;
-               }
-               break;
-       case Fac_EctInform:
-               chan_misdn_log(1, bc->port, " --> EctInform: InvokeID:%d Status:%d\n",
-                       fac->u.EctInform.InvokeID,
-                       fac->u.EctInform.Status);
-               if (fac->u.EctInform.RedirectionPresent) {
-                       chan_misdn_log(1, bc->port, " -->  Redirection Number\n");
-                       print_facility_PresentedNumberUnscreened(2, &fac->u.EctInform.Redirection, bc);
-               }
-               break;
-       case Fac_EctLoopTest:
-               chan_misdn_log(1, bc->port, " --> EctLoopTest: InvokeID:%d\n",
-                       fac->u.EctLoopTest.InvokeID);
-               switch (fac->u.EctLoopTest.ComponentType) {
-               case FacComponent_Invoke:
-                       chan_misdn_log(1, bc->port, " -->  Invoke: CallTransferID:%d\n",
-                               fac->u.EctLoopTest.Component.Invoke.CallTransferID);
-                       break;
-               case FacComponent_Result:
-                       chan_misdn_log(1, bc->port, " -->  Result: LoopResult:%d\n",
-                               fac->u.EctLoopTest.Component.Result.LoopResult);
-                       break;
-               default:
-                       break;
-               }
-               break;
-       case Fac_StatusRequest:
-               chan_misdn_log(1, bc->port, " --> StatusRequest: InvokeID:%d\n",
-                       fac->u.StatusRequest.InvokeID);
-               switch (fac->u.StatusRequest.ComponentType) {
-               case FacComponent_Invoke:
-                       chan_misdn_log(1, bc->port, " -->  Invoke: Compatibility:%d\n",
-                               fac->u.StatusRequest.Component.Invoke.CompatibilityMode);
-                       break;
-               case FacComponent_Result:
-                       chan_misdn_log(1, bc->port, " -->  Result: Status:%d\n",
-                               fac->u.StatusRequest.Component.Result.Status);
-                       break;
-               default:
-                       break;
-               }
-               break;
-       case Fac_CallInfoRetain:
-               chan_misdn_log(1, bc->port, " --> CallInfoRetain: InvokeID:%d, LinkageID:%d\n",
-                       fac->u.CallInfoRetain.InvokeID, fac->u.CallInfoRetain.CallLinkageID);
-               break;
-       case Fac_CCBSDeactivate:
-               chan_misdn_log(1, bc->port, " --> CCBSDeactivate: InvokeID:%d\n",
-                       fac->u.CCBSDeactivate.InvokeID);
-               switch (fac->u.CCBSDeactivate.ComponentType) {
-               case FacComponent_Invoke:
-                       chan_misdn_log(1, bc->port, " -->  Invoke: CCBSReference:%d\n",
-                               fac->u.CCBSDeactivate.Component.Invoke.CCBSReference);
-                       break;
-               case FacComponent_Result:
-                       chan_misdn_log(1, bc->port, " -->  Result\n");
-                       break;
-               default:
-                       break;
-               }
-               break;
-       case Fac_CCBSErase:
-               chan_misdn_log(1, bc->port, " --> CCBSErase: InvokeID:%d, CCBSReference:%d RecallMode:%d, Reason:%d\n",
-                       fac->u.CCBSErase.InvokeID, fac->u.CCBSErase.CCBSReference,
-                       fac->u.CCBSErase.RecallMode, fac->u.CCBSErase.Reason);
-               chan_misdn_log(1, bc->port, " -->  AddressOfB\n");
-               print_facility_Address(2, &fac->u.CCBSErase.AddressOfB, bc);
-               print_facility_Q931_Bc_Hlc_Llc(1, &fac->u.CCBSErase.Q931ie, bc);
-               break;
-       case Fac_CCBSRemoteUserFree:
-               chan_misdn_log(1, bc->port, " --> CCBSRemoteUserFree: InvokeID:%d, CCBSReference:%d RecallMode:%d\n",
-                       fac->u.CCBSRemoteUserFree.InvokeID, fac->u.CCBSRemoteUserFree.CCBSReference,
-                       fac->u.CCBSRemoteUserFree.RecallMode);
-               chan_misdn_log(1, bc->port, " -->  AddressOfB\n");
-               print_facility_Address(2, &fac->u.CCBSRemoteUserFree.AddressOfB, bc);
-               print_facility_Q931_Bc_Hlc_Llc(1, &fac->u.CCBSRemoteUserFree.Q931ie, bc);
-               break;
-       case Fac_CCBSCall:
-               chan_misdn_log(1, bc->port, " --> CCBSCall: InvokeID:%d, CCBSReference:%d\n",
-                       fac->u.CCBSCall.InvokeID, fac->u.CCBSCall.CCBSReference);
-               break;
-       case Fac_CCBSStatusRequest:
-               chan_misdn_log(1, bc->port, " --> CCBSStatusRequest: InvokeID:%d\n",
-                       fac->u.CCBSStatusRequest.InvokeID);
-               switch (fac->u.CCBSStatusRequest.ComponentType) {
-               case FacComponent_Invoke:
-                       chan_misdn_log(1, bc->port, " -->  Invoke: CCBSReference:%d RecallMode:%d\n",
-                               fac->u.CCBSStatusRequest.Component.Invoke.CCBSReference,
-                               fac->u.CCBSStatusRequest.Component.Invoke.RecallMode);
-                       print_facility_Q931_Bc_Hlc_Llc(2, &fac->u.CCBSStatusRequest.Component.Invoke.Q931ie, bc);
-                       break;
-               case FacComponent_Result:
-                       chan_misdn_log(1, bc->port, " -->  Result: Free:%d\n",
-                               fac->u.CCBSStatusRequest.Component.Result.Free);
-                       break;
-               default:
-                       break;
-               }
-               break;
-       case Fac_CCBSBFree:
-               chan_misdn_log(1, bc->port, " --> CCBSBFree: InvokeID:%d, CCBSReference:%d RecallMode:%d\n",
-                       fac->u.CCBSBFree.InvokeID, fac->u.CCBSBFree.CCBSReference,
-                       fac->u.CCBSBFree.RecallMode);
-               chan_misdn_log(1, bc->port, " -->  AddressOfB\n");
-               print_facility_Address(2, &fac->u.CCBSBFree.AddressOfB, bc);
-               print_facility_Q931_Bc_Hlc_Llc(1, &fac->u.CCBSBFree.Q931ie, bc);
-               break;
-       case Fac_EraseCallLinkageID:
-               chan_misdn_log(1, bc->port, " --> EraseCallLinkageID: InvokeID:%d, LinkageID:%d\n",
-                       fac->u.EraseCallLinkageID.InvokeID, fac->u.EraseCallLinkageID.CallLinkageID);
-               break;
-       case Fac_CCBSStopAlerting:
-               chan_misdn_log(1, bc->port, " --> CCBSStopAlerting: InvokeID:%d, CCBSReference:%d\n",
-                       fac->u.CCBSStopAlerting.InvokeID, fac->u.CCBSStopAlerting.CCBSReference);
-               break;
-       case Fac_CCBSRequest:
-               chan_misdn_log(1, bc->port, " --> CCBSRequest: InvokeID:%d\n",
-                       fac->u.CCBSRequest.InvokeID);
-               switch (fac->u.CCBSRequest.ComponentType) {
-               case FacComponent_Invoke:
-                       chan_misdn_log(1, bc->port, " -->  Invoke: LinkageID:%d\n",
-                               fac->u.CCBSRequest.Component.Invoke.CallLinkageID);
-                       break;
-               case FacComponent_Result:
-                       chan_misdn_log(1, bc->port, " -->  Result: CCBSReference:%d RecallMode:%d\n",
-                               fac->u.CCBSRequest.Component.Result.CCBSReference,
-                               fac->u.CCBSRequest.Component.Result.RecallMode);
-                       break;
-               default:
-                       break;
-               }
-               break;
-       case Fac_CCBSInterrogate:
-               chan_misdn_log(1, bc->port, " --> CCBSInterrogate: InvokeID:%d\n",
-                       fac->u.CCBSInterrogate.InvokeID);
-               switch (fac->u.CCBSInterrogate.ComponentType) {
-               case FacComponent_Invoke:
-                       chan_misdn_log(1, bc->port, " -->  Invoke\n");
-                       if (fac->u.CCBSInterrogate.Component.Invoke.CCBSReferencePresent) {
-                               chan_misdn_log(1, bc->port, " -->   CCBSReference:%d\n",
-                                       fac->u.CCBSInterrogate.Component.Invoke.CCBSReference);
-                       }
-                       if (fac->u.CCBSInterrogate.Component.Invoke.AParty.LengthOfNumber) {
-                               chan_misdn_log(1, bc->port, " -->   AParty\n");
-                               print_facility_PartyNumber(3, &fac->u.CCBSInterrogate.Component.Invoke.AParty, bc);
-                       }
-                       break;
-               case FacComponent_Result:
-                       chan_misdn_log(1, bc->port, " -->  Result: RecallMode:%d\n",
-                               fac->u.CCBSInterrogate.Component.Result.RecallMode);
-                       if (fac->u.CCBSInterrogate.Component.Result.NumRecords) {
-                               for (Index = 0; Index < fac->u.CCBSInterrogate.Component.Result.NumRecords; ++Index) {
-                                       chan_misdn_log(1, bc->port, " -->   CallDetails[%d]:\n", Index);
-                                       print_facility_CallInformation(3, &fac->u.CCBSInterrogate.Component.Result.CallDetails[Index], bc);
-                               }
-                       }
-                       break;
-               default:
-                       break;
-               }
-               break;
-       case Fac_CCNRRequest:
-               chan_misdn_log(1, bc->port, " --> CCNRRequest: InvokeID:%d\n",
-                       fac->u.CCNRRequest.InvokeID);
-               switch (fac->u.CCNRRequest.ComponentType) {
-               case FacComponent_Invoke:
-                       chan_misdn_log(1, bc->port, " -->  Invoke: LinkageID:%d\n",
-                               fac->u.CCNRRequest.Component.Invoke.CallLinkageID);
-                       break;
-               case FacComponent_Result:
-                       chan_misdn_log(1, bc->port, " -->  Result: CCBSReference:%d RecallMode:%d\n",
-                               fac->u.CCNRRequest.Component.Result.CCBSReference,
-                               fac->u.CCNRRequest.Component.Result.RecallMode);
-                       break;
-               default:
-                       break;
-               }
-               break;
-       case Fac_CCNRInterrogate:
-               chan_misdn_log(1, bc->port, " --> CCNRInterrogate: InvokeID:%d\n",
-                       fac->u.CCNRInterrogate.InvokeID);
-               switch (fac->u.CCNRInterrogate.ComponentType) {
-               case FacComponent_Invoke:
-                       chan_misdn_log(1, bc->port, " -->  Invoke\n");
-                       if (fac->u.CCNRInterrogate.Component.Invoke.CCBSReferencePresent) {
-                               chan_misdn_log(1, bc->port, " -->   CCBSReference:%d\n",
-                                       fac->u.CCNRInterrogate.Component.Invoke.CCBSReference);
-                       }
-                       if (fac->u.CCNRInterrogate.Component.Invoke.AParty.LengthOfNumber) {
-                               chan_misdn_log(1, bc->port, " -->   AParty\n");
-                               print_facility_PartyNumber(3, &fac->u.CCNRInterrogate.Component.Invoke.AParty, bc);
-                       }
-                       break;
-               case FacComponent_Result:
-                       chan_misdn_log(1, bc->port, " -->  Result: RecallMode:%d\n",
-                               fac->u.CCNRInterrogate.Component.Result.RecallMode);
-                       if (fac->u.CCNRInterrogate.Component.Result.NumRecords) {
-                               for (Index = 0; Index < fac->u.CCNRInterrogate.Component.Result.NumRecords; ++Index) {
-                                       chan_misdn_log(1, bc->port, " -->   CallDetails[%d]:\n", Index);
-                                       print_facility_CallInformation(3, &fac->u.CCNRInterrogate.Component.Result.CallDetails[Index], bc);
-                               }
-                       }
-                       break;
-               default:
-                       break;
-               }
-               break;
-       case Fac_CCBS_T_Call:
-               chan_misdn_log(1, bc->port, " --> CCBS_T_Call: InvokeID:%d\n",
-                       fac->u.CCBS_T_Call.InvokeID);
-               break;
-       case Fac_CCBS_T_Suspend:
-               chan_misdn_log(1, bc->port, " --> CCBS_T_Suspend: InvokeID:%d\n",
-                       fac->u.CCBS_T_Suspend.InvokeID);
-               break;
-       case Fac_CCBS_T_Resume:
-               chan_misdn_log(1, bc->port, " --> CCBS_T_Resume: InvokeID:%d\n",
-                       fac->u.CCBS_T_Resume.InvokeID);
-               break;
-       case Fac_CCBS_T_RemoteUserFree:
-               chan_misdn_log(1, bc->port, " --> CCBS_T_RemoteUserFree: InvokeID:%d\n",
-                       fac->u.CCBS_T_RemoteUserFree.InvokeID);
-               break;
-       case Fac_CCBS_T_Available:
-               chan_misdn_log(1, bc->port, " --> CCBS_T_Available: InvokeID:%d\n",
-                       fac->u.CCBS_T_Available.InvokeID);
-               break;
-       case Fac_CCBS_T_Request:
-               chan_misdn_log(1, bc->port, " --> CCBS_T_Request: InvokeID:%d\n",
-                       fac->u.CCBS_T_Request.InvokeID);
-               switch (fac->u.CCBS_T_Request.ComponentType) {
-               case FacComponent_Invoke:
-                       chan_misdn_log(1, bc->port, " -->  Invoke\n");
-                       chan_misdn_log(1, bc->port, " -->   DestinationAddress:\n");
-                       print_facility_Address(3, &fac->u.CCBS_T_Request.Component.Invoke.Destination, bc);
-                       print_facility_Q931_Bc_Hlc_Llc(2, &fac->u.CCBS_T_Request.Component.Invoke.Q931ie, bc);
-                       if (fac->u.CCBS_T_Request.Component.Invoke.RetentionSupported) {
-                               chan_misdn_log(1, bc->port, " -->   RetentionSupported:1\n");
-                       }
-                       if (fac->u.CCBS_T_Request.Component.Invoke.PresentationAllowedIndicatorPresent) {
-                               chan_misdn_log(1, bc->port, " -->   PresentationAllowed:%d\n",
-                                       fac->u.CCBS_T_Request.Component.Invoke.PresentationAllowedIndicator);
-                       }
-                       if (fac->u.CCBS_T_Request.Component.Invoke.Originating.Party.LengthOfNumber) {
-                               chan_misdn_log(1, bc->port, " -->   OriginatingAddress:\n");
-                               print_facility_Address(3, &fac->u.CCBS_T_Request.Component.Invoke.Originating, bc);
-                       }
-                       break;
-               case FacComponent_Result:
-                       chan_misdn_log(1, bc->port, " -->  Result: RetentionSupported:%d\n",
-                               fac->u.CCBS_T_Request.Component.Result.RetentionSupported);
-                       break;
-               default:
-                       break;
-               }
-               break;
-       case Fac_CCNR_T_Request:
-               chan_misdn_log(1, bc->port, " --> CCNR_T_Request: InvokeID:%d\n",
-                       fac->u.CCNR_T_Request.InvokeID);
-               switch (fac->u.CCNR_T_Request.ComponentType) {
-               case FacComponent_Invoke:
-                       chan_misdn_log(1, bc->port, " -->  Invoke\n");
-                       chan_misdn_log(1, bc->port, " -->   DestinationAddress:\n");
-                       print_facility_Address(3, &fac->u.CCNR_T_Request.Component.Invoke.Destination, bc);
-                       print_facility_Q931_Bc_Hlc_Llc(2, &fac->u.CCNR_T_Request.Component.Invoke.Q931ie, bc);
-                       if (fac->u.CCNR_T_Request.Component.Invoke.RetentionSupported) {
-                               chan_misdn_log(1, bc->port, " -->   RetentionSupported:1\n");
-                       }
-                       if (fac->u.CCNR_T_Request.Component.Invoke.PresentationAllowedIndicatorPresent) {
-                               chan_misdn_log(1, bc->port, " -->   PresentationAllowed:%d\n",
-                                       fac->u.CCNR_T_Request.Component.Invoke.PresentationAllowedIndicator);
-                       }
-                       if (fac->u.CCNR_T_Request.Component.Invoke.Originating.Party.LengthOfNumber) {
-                               chan_misdn_log(1, bc->port, " -->   OriginatingAddress:\n");
-                               print_facility_Address(3, &fac->u.CCNR_T_Request.Component.Invoke.Originating, bc);
-                       }
-                       break;
-               case FacComponent_Result:
-                       chan_misdn_log(1, bc->port, " -->  Result: RetentionSupported:%d\n",
-                               fac->u.CCNR_T_Request.Component.Result.RetentionSupported);
-                       break;
-               default:
-                       break;
-               }
-               break;
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-       case Fac_None:
-               /* No facility so print nothing */
-               break;
-       default:
-               chan_misdn_log(1, bc->port, " --> unknown facility\n");
-               break;
-       }
-}
-
-static void print_bearer(struct misdn_bchannel *bc)
-{
-       chan_misdn_log(2, bc->port, " --> Bearer: %s\n", bearer2str(bc->capability));
-
-       switch(bc->law) {
-       case INFO_CODEC_ALAW:
-               chan_misdn_log(2, bc->port, " --> Codec: Alaw\n");
-               break;
-       case INFO_CODEC_ULAW:
-               chan_misdn_log(2, bc->port, " --> Codec: Ulaw\n");
-               break;
-       }
-}
-
-/*!
- * \internal
- * \brief Prefix a string to another string in place.
- *
- * \param str_prefix String to prefix to the main string.
- * \param str_main String to get the prefix added to it.
- * \param size Buffer size of the main string (Includes null terminator).
- *
- * \note The str_main buffer size must be greater than one.
- *
- * \return Nothing
- */
-static void misdn_prefix_string(const char *str_prefix, char *str_main, size_t size)
-{
-       size_t len_over;
-       size_t len_total;
-       size_t len_main;
-       size_t len_prefix;
-
-       len_prefix = strlen(str_prefix);
-       if (!len_prefix) {
-               /* There is no prefix to prepend. */
-               return;
-       }
-       len_main = strlen(str_main);
-       len_total = len_prefix + len_main;
-       if (size <= len_total) {
-               /* We need to truncate since the buffer is too small. */
-               len_over = len_total + 1 - size;
-               if (len_over <= len_main) {
-                       len_main -= len_over;
-               } else {
-                       len_over -= len_main;
-                       len_main = 0;
-                       len_prefix -= len_over;
-               }
-       }
-       if (len_main) {
-               memmove(str_main + len_prefix, str_main, len_main);
-       }
-       memcpy(str_main, str_prefix, len_prefix);
-       str_main[len_prefix + len_main] = '\0';
-}
-
-/*!
- * \internal
- * \brief Add a configured prefix to the given number.
- *
- * \param port Logical port number
- * \param number_type Type-of-number passed in.
- * \param number Given number string to add prefix
- * \param size Buffer size number string occupies.
- *
- * \return Nothing
- */
-static void misdn_add_number_prefix(int port, enum mISDN_NUMBER_TYPE number_type, char *number, size_t size)
-{
-       enum misdn_cfg_elements type_prefix;
-       char num_prefix[MISDN_MAX_NUMBER_LEN];
-
-       /* Get prefix string. */
-       switch (number_type) {
-       case NUMTYPE_UNKNOWN:
-               type_prefix = MISDN_CFG_TON_PREFIX_UNKNOWN;
-               break;
-       case NUMTYPE_INTERNATIONAL:
-               type_prefix = MISDN_CFG_TON_PREFIX_INTERNATIONAL;
-               break;
-       case NUMTYPE_NATIONAL:
-               type_prefix = MISDN_CFG_TON_PREFIX_NATIONAL;
-               break;
-       case NUMTYPE_NETWORK_SPECIFIC:
-               type_prefix = MISDN_CFG_TON_PREFIX_NETWORK_SPECIFIC;
-               break;
-       case NUMTYPE_SUBSCRIBER:
-               type_prefix = MISDN_CFG_TON_PREFIX_SUBSCRIBER;
-               break;
-       case NUMTYPE_ABBREVIATED:
-               type_prefix = MISDN_CFG_TON_PREFIX_ABBREVIATED;
-               break;
-       default:
-               /* Type-of-number does not have a prefix that can be added. */
-               return;
-       }
-       misdn_cfg_get(port, type_prefix, num_prefix, sizeof(num_prefix));
-
-       misdn_prefix_string(num_prefix, number, size);
-}
-
-static void export_aoc_vars(int originator, struct ast_channel *ast, struct misdn_bchannel *bc)
-{
-       RAII_VAR(struct ast_channel *, chan, NULL, ast_channel_cleanup);
-       char buf[128];
-
-       if (!bc->AOCD_need_export || !ast) {
-               return;
-       }
-
-       if (originator == ORG_AST) {
-               chan = ast_channel_bridge_peer(ast);
-               if (!chan) {
-                       return;
-               }
-       } else {
-               chan = ast_channel_ref(ast);
-       }
-
-       switch (bc->AOCDtype) {
-       case Fac_AOCDCurrency:
-               pbx_builtin_setvar_helper(chan, "AOCD_Type", "currency");
-               if (bc->AOCD.currency.chargeNotAvailable) {
-                       pbx_builtin_setvar_helper(chan, "AOCD_ChargeAvailable", "no");
-               } else {
-                       pbx_builtin_setvar_helper(chan, "AOCD_ChargeAvailable", "yes");
-                       if (bc->AOCD.currency.freeOfCharge) {
-                               pbx_builtin_setvar_helper(chan, "AOCD_FreeOfCharge", "yes");
-                       } else {
-                               pbx_builtin_setvar_helper(chan, "AOCD_FreeOfCharge", "no");
-                               if (snprintf(buf, sizeof(buf), "%d %s", bc->AOCD.currency.currencyAmount * bc->AOCD.currency.multiplier, bc->AOCD.currency.currency) < sizeof(buf)) {
-                                       pbx_builtin_setvar_helper(chan, "AOCD_Amount", buf);
-                                       if (bc->AOCD.currency.billingId >= 0 && snprintf(buf, sizeof(buf), "%d", bc->AOCD.currency.billingId) < sizeof(buf)) {
-                                               pbx_builtin_setvar_helper(chan, "AOCD_BillingId", buf);
-                                       }
-                               }
-                       }
-               }
-               break;
-       case Fac_AOCDChargingUnit:
-               pbx_builtin_setvar_helper(chan, "AOCD_Type", "charging_unit");
-               if (bc->AOCD.chargingUnit.chargeNotAvailable) {
-                       pbx_builtin_setvar_helper(chan, "AOCD_ChargeAvailable", "no");
-               } else {
-                       pbx_builtin_setvar_helper(chan, "AOCD_ChargeAvailable", "yes");
-                       if (bc->AOCD.chargingUnit.freeOfCharge) {
-                               pbx_builtin_setvar_helper(chan, "AOCD_FreeOfCharge", "yes");
-                       } else {
-                               pbx_builtin_setvar_helper(chan, "AOCD_FreeOfCharge", "no");
-                               if (snprintf(buf, sizeof(buf), "%d", bc->AOCD.chargingUnit.recordedUnits) < sizeof(buf)) {
-                                       pbx_builtin_setvar_helper(chan, "AOCD_RecordedUnits", buf);
-                                       if (bc->AOCD.chargingUnit.billingId >= 0 && snprintf(buf, sizeof(buf), "%d", bc->AOCD.chargingUnit.billingId) < sizeof(buf)) {
-                                               pbx_builtin_setvar_helper(chan, "AOCD_BillingId", buf);
-                                       }
-                               }
-                       }
-               }
-               break;
-       default:
-               break;
-       }
-
-       bc->AOCD_need_export = 0;
-}
-
-/*************** Helpers END *************/
-
-static void sighandler(int sig)
-{
-}
-
-static void *misdn_tasks_thread_func(void *data)
-{
-       int wait;
-       struct sigaction sa;
-
-       sa.sa_handler = sighandler;
-       sa.sa_flags = SA_NODEFER;
-       sigemptyset(&sa.sa_mask);
-       sigaddset(&sa.sa_mask, SIGUSR1);
-       sigaction(SIGUSR1, &sa, NULL);
-
-       sem_post((sem_t *)data);
-
-       while (1) {
-               wait = ast_sched_wait(misdn_tasks);
-               if (wait < 0) {
-                       wait = 8000;
-               }
-               if (poll(NULL, 0, wait) < 0) {
-                       chan_misdn_log(4, 0, "Waking up misdn_tasks thread\n");
-               }
-               ast_sched_runq(misdn_tasks);
-       }
-       return NULL;
-}
-
-static void misdn_tasks_init(void)
-{
-       sem_t blocker;
-       int i = 5;
-
-       if (sem_init(&blocker, 0, 0)) {
-               perror("chan_misdn: Failed to initialize semaphore!");
-               exit(1);
-       }
-
-       chan_misdn_log(4, 0, "Starting misdn_tasks thread\n");
-
-       misdn_tasks = ast_sched_context_create();
-       pthread_create(&misdn_tasks_thread, NULL, misdn_tasks_thread_func, &blocker);
-
-       while (sem_wait(&blocker) && --i) {
-       }
-       sem_destroy(&blocker);
-}
-
-static void misdn_tasks_destroy(void)
-{
-       if (misdn_tasks) {
-               chan_misdn_log(4, 0, "Killing misdn_tasks thread\n");
-               if (pthread_cancel(misdn_tasks_thread) == 0) {
-                       cb_log(4, 0, "Joining misdn_tasks thread\n");
-                       pthread_join(misdn_tasks_thread, NULL);
-               }
-               ast_sched_context_destroy(misdn_tasks);
-       }
-}
-
-static inline void misdn_tasks_wakeup(void)
-{
-       pthread_kill(misdn_tasks_thread, SIGUSR1);
-}
-
-static inline int _misdn_tasks_add_variable(int timeout, ast_sched_cb callback, const void *data, int variable)
-{
-       int task_id;
-
-       if (!misdn_tasks) {
-               misdn_tasks_init();
-       }
-       task_id = ast_sched_add_variable(misdn_tasks, timeout, callback, data, variable);
-       misdn_tasks_wakeup();
-
-       return task_id;
-}
-
-static int misdn_tasks_add(int timeout, ast_sched_cb callback, const void *data)
-{
-       return _misdn_tasks_add_variable(timeout, callback, data, 0);
-}
-
-static int misdn_tasks_add_variable(int timeout, ast_sched_cb callback, const void *data)
-{
-       return _misdn_tasks_add_variable(timeout, callback, data, 1);
-}
-
-static void misdn_tasks_remove(int task_id)
-{
-       AST_SCHED_DEL(misdn_tasks, task_id);
-}
-
-static int misdn_l1_task(const void *vdata)
-{
-       const int *data = vdata;
-
-       misdn_lib_isdn_l1watcher(*data);
-       chan_misdn_log(5, *data, "L1watcher timeout\n");
-       return 1;
-}
-
-static int misdn_overlap_dial_task(const void *data)
-{
-       struct timeval tv_end, tv_now;
-       int diff;
-       struct chan_list *ch = (struct chan_list *) data;
-       char *dad;
-
-       chan_misdn_log(4, ch->bc->port, "overlap dial task, chan_state: %d\n", ch->state);
-
-       if (ch->state != MISDN_WAITING4DIGS) {
-               ch->overlap_dial_task = -1;
-               return 0;
-       }
-
-       ast_mutex_lock(&ch->overlap_tv_lock);
-       tv_end = ch->overlap_tv;
-       ast_mutex_unlock(&ch->overlap_tv_lock);
-
-       tv_end.tv_sec += ch->overlap_dial;
-       tv_now = ast_tvnow();
-
-       diff = ast_tvdiff_ms(tv_end, tv_now);
-       if (100 < diff) {
-               return diff;
-       }
-
-       /* if we are 100ms near the timeout, we are satisfied.. */
-       stop_indicate(ch);
-
-       if (ast_strlen_zero(ch->bc->dialed.number)) {
-               dad = "s";
-               ast_channel_exten_set(ch->ast, dad);
-       } else {
-               dad = ch->bc->dialed.number;
-       }
-
-       if (ast_exists_extension(ch->ast, ch->context, dad, 1, ch->bc->caller.number)) {
-               ch->state = MISDN_DIALING;
-               if (pbx_start_chan(ch) < 0) {
-                       chan_misdn_log(-1, ch->bc->port, "ast_pbx_start returned < 0 in misdn_overlap_dial_task\n");
-                       goto misdn_overlap_dial_task_disconnect;
-               }
-       } else {
-misdn_overlap_dial_task_disconnect:
-               hanguptone_indicate(ch);
-               ch->bc->out_cause = AST_CAUSE_UNALLOCATED;
-               ch->state = MISDN_CLEANING;
-               misdn_lib_send_event(ch->bc, EVENT_DISCONNECT);
-       }
-       ch->overlap_dial_task = -1;
-       return 0;
-}
-
-static void send_digit_to_chan(struct chan_list *cl, char digit)
-{
-       static const char * const dtmf_tones[] = {
-/* *INDENT-OFF* */
-               "!941+1336/100,!0/100", /* 0 */
-               "!697+1209/100,!0/100", /* 1 */
-               "!697+1336/100,!0/100", /* 2 */
-               "!697+1477/100,!0/100", /* 3 */
-               "!770+1209/100,!0/100", /* 4 */
-               "!770+1336/100,!0/100", /* 5 */
-               "!770+1477/100,!0/100", /* 6 */
-               "!852+1209/100,!0/100", /* 7 */
-               "!852+1336/100,!0/100", /* 8 */
-               "!852+1477/100,!0/100", /* 9 */
-               "!697+1633/100,!0/100", /* A */
-               "!770+1633/100,!0/100", /* B */
-               "!852+1633/100,!0/100", /* C */
-               "!941+1633/100,!0/100", /* D */
-               "!941+1209/100,!0/100", /* * */
-               "!941+1477/100,!0/100", /* # */
-/* *INDENT-ON* */
-       };
-       struct ast_channel *chan = cl->ast;
-
-       if (digit >= '0' && digit <='9') {
-               ast_playtones_start(chan, 0, dtmf_tones[digit - '0'], 0);
-       } else if (digit >= 'A' && digit <= 'D') {
-               ast_playtones_start(chan, 0, dtmf_tones[digit - 'A' + 10], 0);
-       } else if (digit == '*') {
-               ast_playtones_start(chan, 0, dtmf_tones[14], 0);
-       } else if (digit == '#') {
-               ast_playtones_start(chan, 0, dtmf_tones[15], 0);
-       } else {
-               /* not handled */
-               ast_debug(1, "Unable to handle DTMF tone '%c' for '%s'\n", digit, ast_channel_name(chan));
-       }
-}
-
-/*** CLI HANDLING ***/
-static char *handle_cli_misdn_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
-{
-       int level;
-
-       switch (cmd) {
-       case CLI_INIT:
-               e->command = "misdn set debug [on|off]";
-               e->usage =
-                       "Usage: misdn set debug {on|off|<level>} [only] | [port <port> [only]]\n"
-                       "       Set the debug level of the mISDN channel.\n";
-               return NULL;
-       case CLI_GENERATE:
-               return complete_debug_port(a);
-       }
-
-       if (a->argc < 4 || a->argc > 7) {
-               return CLI_SHOWUSAGE;
-       }
-
-       if (!strcasecmp(a->argv[3], "on")) {
-               level = 1;
-       } else if (!strcasecmp(a->argv[3], "off")) {
-               level = 0;
-       } else if (isdigit(a->argv[3][0])) {
-               level = atoi(a->argv[3]);
-       } else {
-               return CLI_SHOWUSAGE;
-       }
-
-       switch (a->argc) {
-       case 4:
-       case 5:
-               {
-                       int i;
-                       int only = 0;
-                       if (a->argc == 5) {
-                               if (strncasecmp(a->argv[4], "only", strlen(a->argv[4]))) {
-                                       return CLI_SHOWUSAGE;
-                               } else {
-                                       only = 1;
-                               }
-                       }
-
-                       for (i = 0; i <= max_ports; i++) {
-                               misdn_debug[i] = level;
-                               misdn_debug_only[i] = only;
-                       }
-                       ast_cli(a->fd, "changing debug level for all ports to %d%s\n", misdn_debug[0], only ? " (only)" : "");
-               }
-               break;
-       case 6:
-       case 7:
-               {
-                       int port;
-                       if (strncasecmp(a->argv[4], "port", strlen(a->argv[4])))
-                               return CLI_SHOWUSAGE;
-                       port = atoi(a->argv[5]);
-                       if (port <= 0 || port > max_ports) {
-                               switch (max_ports) {
-                               case 0:
-                                       ast_cli(a->fd, "port number not valid! no ports available so you won't get lucky with any number here...\n");
-                                       break;
-                               case 1:
-                                       ast_cli(a->fd, "port number not valid! only port 1 is available.\n");
-                                       break;
-                               default:
-                                       ast_cli(a->fd, "port number not valid! only ports 1 to %d are available.\n", max_ports);
-                               }
-                               return 0;
-                       }
-                       if (a->argc == 7) {
-                               if (strncasecmp(a->argv[6], "only", strlen(a->argv[6]))) {
-                                       return CLI_SHOWUSAGE;
-                               } else {
-                                       misdn_debug_only[port] = 1;
-                               }
-                       } else {
-                               misdn_debug_only[port] = 0;
-                       }
-                       misdn_debug[port] = level;
-                       ast_cli(a->fd, "changing debug level to %d%s for port %d\n", misdn_debug[port], misdn_debug_only[port] ? " (only)" : "", port);
-               }
-       }
-
-       return CLI_SUCCESS;
-}
-
-static char *handle_cli_misdn_set_crypt_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
-{
-       switch (cmd) {
-       case CLI_INIT:
-               e->command = "misdn set crypt debug";
-               e->usage =
-                       "Usage: misdn set crypt debug <level>\n"
-                       "       Set the crypt debug level of the mISDN channel. Level\n"
-                       "       must be 1 or 2.\n";
-               return NULL;
-       case CLI_GENERATE:
-               return NULL;
-       }
-
-       if (a->argc != 5) {
-               return CLI_SHOWUSAGE;
-       }
-
-       /* XXX Is this supposed to not do anything? XXX */
-
-       return CLI_SUCCESS;
-}
-
-static char *handle_cli_misdn_port_block(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
-{
-       switch (cmd) {
-       case CLI_INIT:
-               e->command = "misdn port block";
-               e->usage =
-                       "Usage: misdn port block <port>\n"
-                       "       Block the specified port by <port>.\n";
-               return NULL;
-       case CLI_GENERATE:
-               return NULL;
-       }
-
-       if (a->argc != 4) {
-               return CLI_SHOWUSAGE;
-       }
-
-       misdn_lib_port_block(atoi(a->argv[3]));
-
-       return CLI_SUCCESS;
-}
-
-static char *handle_cli_misdn_port_unblock(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
-{
-       switch (cmd) {
-       case CLI_INIT:
-               e->command = "misdn port unblock";
-               e->usage =
-                       "Usage: misdn port unblock <port>\n"
-                       "       Unblock the port specified by <port>.\n";
-               return NULL;
-       case CLI_GENERATE:
-               return NULL;
-       }
-
-       if (a->argc != 4) {
-               return CLI_SHOWUSAGE;
-       }
-
-       misdn_lib_port_unblock(atoi(a->argv[3]));
-
-       return CLI_SUCCESS;
-}
-
-static char *handle_cli_misdn_restart_port(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
-{
-       switch (cmd) {
-       case CLI_INIT:
-               e->command = "misdn restart port";
-               e->usage =
-                       "Usage: misdn restart port <port>\n"
-                       "       Restart the given port.\n";
-               return NULL;
-       case CLI_GENERATE:
-               return NULL;
-       }
-
-       if (a->argc != 4) {
-               return CLI_SHOWUSAGE;
-       }
-
-       misdn_lib_port_restart(atoi(a->argv[3]));
-
-       return CLI_SUCCESS;
-}
-
-static char *handle_cli_misdn_restart_pid(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
-{
-       switch (cmd) {
-       case CLI_INIT:
-               e->command = "misdn restart pid";
-               e->usage =
-                       "Usage: misdn restart pid <pid>\n"
-                       "       Restart the given pid\n";
-               return NULL;
-       case CLI_GENERATE:
-               return NULL;
-       }
-
-       if (a->argc != 4) {
-               return CLI_SHOWUSAGE;
-       }
-
-       misdn_lib_pid_restart(atoi(a->argv[3]));
-
-       return CLI_SUCCESS;
-}
-
-static char *handle_cli_misdn_port_up(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
-{
-       switch (cmd) {
-       case CLI_INIT:
-               e->command = "misdn port up";
-               e->usage =
-                       "Usage: misdn port up <port>\n"
-                       "       Try to establish L1 on the given port.\n";
-               return NULL;
-       case CLI_GENERATE:
-               return NULL;
-       }
-
-       if (a->argc != 4) {
-               return CLI_SHOWUSAGE;
-       }
-
-       misdn_lib_get_port_up(atoi(a->argv[3]));
-
-       return CLI_SUCCESS;
-}
-
-static char *handle_cli_misdn_port_down(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
-{
-       switch (cmd) {
-       case CLI_INIT:
-               e->command = "misdn port down";
-               e->usage =
-                       "Usage: misdn port down <port>\n"
-                       "       Try to deactivate the L1 on the given port.\n";
-               return NULL;
-       case CLI_GENERATE:
-               return NULL;
-       }
-
-       if (a->argc != 4) {
-               return CLI_SHOWUSAGE;
-       }
-
-       misdn_lib_get_port_down(atoi(a->argv[3]));
-
-       return CLI_SUCCESS;
-}
-
-static inline void show_config_description(int fd, enum misdn_cfg_elements elem)
-{
-       char section[BUFFERSIZE];
-       char name[BUFFERSIZE];
-       char desc[BUFFERSIZE];
-       char def[BUFFERSIZE];
-       char tmp[BUFFERSIZE];
-
-       misdn_cfg_get_name(elem, tmp, sizeof(tmp));
-       term_color(name, tmp, COLOR_BRWHITE, 0, sizeof(tmp));
-       misdn_cfg_get_desc(elem, desc, sizeof(desc), def, sizeof(def));
-
-       if (elem < MISDN_CFG_LAST) {
-               term_color(section, "PORTS SECTION", COLOR_YELLOW, 0, sizeof(section));
-       } else {
-               term_color(section, "GENERAL SECTION", COLOR_YELLOW, 0, sizeof(section));
-       }
-
-       if (*def) {
-               ast_cli(fd, "[%s] %s   (Default: %s)\n\t%s\n", section, name, def, desc);
-       } else {
-               ast_cli(fd, "[%s] %s\n\t%s\n", section, name, desc);
-       }
-}
-
-static char *handle_cli_misdn_show_config(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
-{
-       char buffer[BUFFERSIZE];
-       enum misdn_cfg_elements elem;
-       int linebreak;
-       int onlyport = -1;
-       int ok = 0;
-
-       switch (cmd) {
-       case CLI_INIT:
-               e->command = "misdn show config";
-               e->usage =
-                       "Usage: misdn show config [<port> | description <config element> | descriptions [general|ports]]\n"
-                       "       Use 0 for <port> to only print the general config.\n";
-               return NULL;
-       case CLI_GENERATE:
-               return complete_show_config(a);
-       }
-
-       if (a->argc >= 4) {
-               if (!strcmp(a->argv[3], "description")) {
-                       if (a->argc == 5) {
-                               enum misdn_cfg_elements elem = misdn_cfg_get_elem(a->argv[4]);
-                               if (elem == MISDN_CFG_FIRST) {
-                                       ast_cli(a->fd, "Unknown element: %s\n", a->argv[4]);
-                               } else {
-                                       show_config_description(a->fd, elem);
-                               }
-                               return CLI_SUCCESS;
-                       }
-                       return CLI_SHOWUSAGE;
-               } else if (!strcmp(a->argv[3], "descriptions")) {
-                       if ((a->argc == 4) || ((a->argc == 5) && !strcmp(a->argv[4], "general"))) {
-                               for (elem = MISDN_GEN_FIRST + 1; elem < MISDN_GEN_LAST; ++elem) {
-                                       show_config_description(a->fd, elem);
-                                       ast_cli(a->fd, "\n");
-                               }
-                               ok = 1;
-                       }
-                       if ((a->argc == 4) || ((a->argc == 5) && !strcmp(a->argv[4], "ports"))) {
-                               for (elem = MISDN_CFG_FIRST + 1; elem < MISDN_CFG_LAST - 1 /* the ptp hack, remove the -1 when ptp is gone */; ++elem) {
-                                       show_config_description(a->fd, elem);
-                                       ast_cli(a->fd, "\n");
-                               }
-                               ok = 1;
-                       }
-                       return ok ? CLI_SUCCESS : CLI_SHOWUSAGE;
-               } else if (!sscanf(a->argv[3], "%5d", &onlyport) || onlyport < 0) {
-                       ast_cli(a->fd, "Unknown option: %s\n", a->argv[3]);
-                       return CLI_SHOWUSAGE;
-               }
-       }
-
-       if (a->argc == 3 || onlyport == 0) {
-               ast_cli(a->fd, "mISDN General-Config:\n");
-               for (elem = MISDN_GEN_FIRST + 1, linebreak = 1; elem < MISDN_GEN_LAST; elem++, linebreak++) {
-                       misdn_cfg_get_config_string(0, elem, buffer, sizeof(buffer));
-                       ast_cli(a->fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : "");
-               }
-               ast_cli(a->fd, "\n");
-       }
-
-       if (onlyport < 0) {
-               int port = misdn_cfg_get_next_port(0);
-
-               for (; port > 0; port = misdn_cfg_get_next_port(port)) {
-                       ast_cli(a->fd, "\n[PORT %d]\n", port);
-                       for (elem = MISDN_CFG_FIRST + 1, linebreak = 1; elem < MISDN_CFG_LAST; elem++, linebreak++) {
-                               misdn_cfg_get_config_string(port, elem, buffer, sizeof(buffer));
-                               ast_cli(a->fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : "");
-                       }
-                       ast_cli(a->fd, "\n");
-               }
-       }
-
-       if (onlyport > 0) {
-               if (misdn_cfg_is_port_valid(onlyport)) {
-                       ast_cli(a->fd, "[PORT %d]\n", onlyport);
-                       for (elem = MISDN_CFG_FIRST + 1, linebreak = 1; elem < MISDN_CFG_LAST; elem++, linebreak++) {
-                               misdn_cfg_get_config_string(onlyport, elem, buffer, sizeof(buffer));
-                               ast_cli(a->fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : "");
-                       }
-                       ast_cli(a->fd, "\n");
-               } else {
-                       ast_cli(a->fd, "Port %d is not active!\n", onlyport);
-               }
-       }
-
-       return CLI_SUCCESS;
-}
-
-struct state_struct {
-       enum misdn_chan_state state;
-       char txt[255];
-};
-
-static const struct state_struct state_array[] = {
-/* *INDENT-OFF* */
-       { MISDN_NOTHING,             "NOTHING" },             /* at beginning */
-       { MISDN_WAITING4DIGS,        "WAITING4DIGS" },        /* when waiting for infos */
-       { MISDN_EXTCANTMATCH,        "EXTCANTMATCH" },        /* when asterisk couldn't match our ext */
-       { MISDN_INCOMING_SETUP,      "INCOMING SETUP" },      /* when pbx_start */
-       { MISDN_DIALING,             "DIALING" },             /* when pbx_start */
-       { MISDN_PROGRESS,            "PROGRESS" },            /* when pbx_start */
-       { MISDN_PROCEEDING,          "PROCEEDING" },          /* when pbx_start */
-       { MISDN_CALLING,             "CALLING" },             /* when misdn_call is called */
-       { MISDN_CALLING_ACKNOWLEDGE, "CALLING_ACKNOWLEDGE" }, /* when misdn_call is called */
-       { MISDN_ALERTING,            "ALERTING" },            /* when Alerting */
-       { MISDN_BUSY,                "BUSY" },                /* when BUSY */
-       { MISDN_CONNECTED,           "CONNECTED" },           /* when connected */
-       { MISDN_DISCONNECTED,        "DISCONNECTED" },        /* when connected */
-       { MISDN_CLEANING,            "CLEANING" },            /* when hangup from * but we were connected before */
-/* *INDENT-ON* */
-};
-
-static const char *misdn_get_ch_state(struct chan_list *p)
-{
-       int i;
-       static char state[8];
-
-       if (!p) {
-               return NULL;
-       }
-
-       for (i = 0; i < ARRAY_LEN(state_array); i++) {
-               if (state_array[i].state == p->state) {
-                       return state_array[i].txt;
-               }
-       }
-
-       snprintf(state, sizeof(state), "%d", p->state) ;
-
-       return state;
-}
-
-
-static void reload_config(void)
-{
-       int i, cfg_debug;
-
-       if (!g_config_initialized) {
-               ast_log(LOG_WARNING, "chan_misdn is not initialized properly, still reloading ?\n");
-               return ;
-       }
-
-       free_robin_list();
-       misdn_cfg_reload();
-       misdn_cfg_update_ptp();
-       misdn_cfg_get(0, MISDN_GEN_TRACEFILE, global_tracefile, sizeof(global_tracefile));
-       misdn_cfg_get(0, MISDN_GEN_DEBUG, &cfg_debug, sizeof(cfg_debug));
-
-       for (i = 0;  i <= max_ports; i++) {
-               misdn_debug[i] = cfg_debug;
-               misdn_debug_only[i] = 0;
-       }
-}
-
-static char *handle_cli_misdn_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
-{
-       switch (cmd) {
-       case CLI_INIT:
-               e->command = "misdn reload";
-               e->usage =
-                       "Usage: misdn reload\n"
-                       "       Reload internal mISDN config, read from the config\n"
-                       "       file.\n";
-               return NULL;
-       case CLI_GENERATE:
-               return NULL;
-       }
-
-       if (a->argc != 2) {
-               return CLI_SHOWUSAGE;
-       }
-
-       ast_cli(a->fd, "Reloading mISDN configuration\n");
-       reload_config();
-       return CLI_SUCCESS;
-}
-
-static void print_bc_info(int fd, struct chan_list *help, struct misdn_bchannel *bc)
-{
-       struct ast_channel *ast = help->ast;
-
-       ast_cli(fd,
-               "* Pid:%d Port:%d Ch:%d Mode:%s Orig:%s dialed:%s\n"
-               "  --> caller:\"%s\" <%s>\n"
-               "  --> redirecting-from:\"%s\" <%s>\n"
-               "  --> redirecting-to:\"%s\" <%s>\n"
-               "  --> context:%s state:%s\n",
-               bc->pid,
-               bc->port,
-               bc->channel,
-               bc->nt ? "NT" : "TE",
-               help->originator == ORG_AST ? "*" : "I",
-               ast ? ast_channel_exten(ast) : "",
-               (ast && ast_channel_caller(ast)->id.name.valid && ast_channel_caller(ast)->id.name.str)
-                       ? ast_channel_caller(ast)->id.name.str : "",
-               (ast && ast_channel_caller(ast)->id.number.valid && ast_channel_caller(ast)->id.number.str)
-                       ? ast_channel_caller(ast)->id.number.str : "",
-               bc->redirecting.from.name,
-               bc->redirecting.from.number,
-               bc->redirecting.to.name,
-               bc->redirecting.to.number,
-               ast ? ast_channel_context(ast) : "",
-               misdn_get_ch_state(help));
-       if (misdn_debug[bc->port] > 0) {
-               ast_cli(fd,
-                       "  --> astname: %s\n"
-                       "  --> ch_l3id: %x\n"
-                       "  --> ch_addr: %x\n"
-                       "  --> bc_addr: %x\n"
-                       "  --> bc_l3id: %x\n"
-                       "  --> display: %s\n"
-                       "  --> activated: %d\n"
-                       "  --> state: %s\n"
-                       "  --> capability: %s\n"
-#ifdef MISDN_1_2
-                       "  --> pipeline: %s\n"
-#else
-                       "  --> echo_cancel: %d\n"
-#endif
-                       "  --> notone : rx %d tx:%d\n"
-                       "  --> bc_hold: %d\n",
-                       ast ? ast_channel_name(ast) : "",
-                       help->l3id,
-                       help->addr,
-                       bc->addr,
-                       bc->l3_id,
-                       bc->display,
-                       bc->active,
-                       bc_state2str(bc->bc_state),
-                       bearer2str(bc->capability),
-#ifdef MISDN_1_2
-                       bc->pipeline,
-#else
-                       bc->ec_enable,
-#endif
-                       help->norxtone, help->notxtone,
-                       bc->holded);
-       }
-}
-
-static char *handle_cli_misdn_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
-{
-       struct chan_list *help;
-
-       switch (cmd) {
-       case CLI_INIT:
-               e->command = "misdn show channels";
-               e->usage =
-                       "Usage: misdn show channels\n"
-                       "       Show the internal mISDN channel list\n";
-               return NULL;
-       case CLI_GENERATE:
-               return NULL;
-       }
-
-       if (a->argc != 3) {
-               return CLI_SHOWUSAGE;
-       }
-
-       ast_cli(a->fd, "Channel List: %p\n", cl_te);
-
-       /*
-        * Walking the list and dumping the channel information could
-        * take awhile.  With the list locked for the duration, the
-        * channel driver cannot process signaling messages.  However,
-        * since this is a CLI command it should not be run very often.
-        */
-       ast_mutex_lock(&cl_te_lock);
-       for (help = cl_te; help; help = help->next) {
-               struct misdn_bchannel *bc = help->bc;
-               struct ast_channel *ast = help->ast;
-               if (!ast) {
-                       if (!bc) {
-                               ast_cli(a->fd, "chan_list obj. with l3id:%x has no bc and no ast Leg\n", help->l3id);
-                               continue;
-                       }
-                       ast_cli(a->fd, "bc with pid:%d has no Ast Leg\n", bc->pid);
-               }
-
-               if (misdn_debug[0] > 2) {
-                       ast_cli(a->fd, "Bc:%p Ast:%p\n", bc, ast);
-               }
-               if (bc) {
-                       print_bc_info(a->fd, help, bc);
-               } else {
-                       if (help->hold.state != MISDN_HOLD_IDLE) {
-                               ast_cli(a->fd, "ITS A HELD CALL BC:\n");
-                               ast_cli(a->fd, " --> l3_id: %x\n"
-                                       " --> dialed:%s\n"
-                                       " --> caller:\"%s\" <%s>\n"
-                                       " --> hold_port: %d\n"
-                                       " --> hold_channel: %d\n",
-                                       help->l3id,
-                                       ast_channel_exten(ast),
-                                       S_COR(ast_channel_caller(ast)->id.name.valid, ast_channel_caller(ast)->id.name.str, ""),
-                                       S_COR(ast_channel_caller(ast)->id.number.valid, ast_channel_caller(ast)->id.number.str, ""),
-                                       help->hold.port,
-                                       help->hold.channel
-                                       );
-                       } else {
-                               ast_cli(a->fd, "* Channel in unknown STATE !!! Exten:%s, Callerid:%s\n",
-                                       ast_channel_exten(ast),
-                                       S_COR(ast_channel_caller(ast)->id.number.valid, ast_channel_caller(ast)->id.number.str, ""));
-                       }
-               }
-       }
-       ast_mutex_unlock(&cl_te_lock);
-
-       misdn_dump_chanlist();
-
-       return CLI_SUCCESS;
-}
-
-static char *handle_cli_misdn_show_channel(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
-{
-       struct chan_list *help;
-
-       switch (cmd) {
-       case CLI_INIT:
-               e->command = "misdn show channel";
-               e->usage =
-                       "Usage: misdn show channel <channel>\n"
-                       "       Show an internal mISDN channel\n.";
-               return NULL;
-       case CLI_GENERATE:
-               return complete_ch(a);
-       }
-
-       if (a->argc != 4) {
-               return CLI_SHOWUSAGE;
-       }
-
-       ast_mutex_lock(&cl_te_lock);
-       for (help = cl_te; help; help = help->next) {
-               struct misdn_bchannel *bc = help->bc;
-               struct ast_channel *ast = help->ast;
-
-               if (bc && ast) {
-                       if (!strcasecmp(ast_channel_name(ast), a->argv[3])) {
-                               print_bc_info(a->fd, help, bc);
-                               break;
-                       }
-               }
-       }
-       ast_mutex_unlock(&cl_te_lock);
-
-       return CLI_SUCCESS;
-}
-
-static char *handle_cli_misdn_set_tics(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
-{
-       switch (cmd) {
-       case CLI_INIT:
-               e->command = "misdn set tics";
-               e->usage =
-                       "Usage: misdn set tics <value>\n";
-               return NULL;
-       case CLI_GENERATE:
-               return NULL;
-       }
-
-       if (a->argc != 4) {
-               return CLI_SHOWUSAGE;
-       }
-
-       /* XXX Wow, this does... a whole lot of nothing... XXX */
-       MAXTICS = atoi(a->argv[3]);
-
-       return CLI_SUCCESS;
-}
-
-static char *handle_cli_misdn_show_stacks(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
-{
-       int port;
-
-       switch (cmd) {
-       case CLI_INIT:
-               e->command = "misdn show stacks";
-               e->usage =
-                       "Usage: misdn show stacks\n"
-                       "       Show internal mISDN stack_list.\n";
-               return NULL;
-       case CLI_GENERATE:
-               return NULL;
-       }
-
-       if (a->argc != 3) {
-               return CLI_SHOWUSAGE;
-       }
-
-       ast_cli(a->fd, "BEGIN STACK_LIST:\n");
-       for (port = misdn_cfg_get_next_port(0); port > 0;
-               port = misdn_cfg_get_next_port(port)) {
-               char buf[128];
-
-               get_show_stack_details(port, buf);
-               ast_cli(a->fd, "  %s  Debug:%d%s\n", buf, misdn_debug[port], misdn_debug_only[port] ? "(only)" : "");
-       }
-
-       return CLI_SUCCESS;
-}
-
-static char *handle_cli_misdn_show_ports_stats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
-{
-       int port;
-
-       switch (cmd) {
-       case CLI_INIT:
-               e->command = "misdn show ports stats";
-               e->usage =
-                       "Usage: misdn show ports stats\n"
-                       "       Show mISDNs channel's call statistics per port.\n";
-               return NULL;
-       case CLI_GENERATE:
-               return NULL;
-       }
-
-       if (a->argc != 4) {
-               return CLI_SHOWUSAGE;
-       }
-
-       ast_cli(a->fd, "Port\tin_calls\tout_calls\n");
-       for (port = misdn_cfg_get_next_port(0); port > 0;
-               port = misdn_cfg_get_next_port(port)) {
-               ast_cli(a->fd, "%d\t%d\t\t%d\n", port, misdn_in_calls[port], misdn_out_calls[port]);
-       }
-       ast_cli(a->fd, "\n");
-
-       return CLI_SUCCESS;
-}
-
-static char *handle_cli_misdn_show_port(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
-{
-       int port;
-       char buf[128];
-
-       switch (cmd) {
-       case CLI_INIT:
-               e->command = "misdn show port";
-               e->usage =
-                       "Usage: misdn show port <port>\n"
-                       "       Show detailed information for given port.\n";
-               return NULL;
-       case CLI_GENERATE:
-               return NULL;
-       }
-
-       if (a->argc != 4) {
-               return CLI_SHOWUSAGE;
-       }
-
-       port = atoi(a->argv[3]);
-
-       ast_cli(a->fd, "BEGIN STACK_LIST:\n");
-       get_show_stack_details(port, buf);
-       ast_cli(a->fd, "  %s  Debug:%d%s\n", buf, misdn_debug[port], misdn_debug_only[port] ? "(only)" : "");
-
-       return CLI_SUCCESS;
-}
-
-#if defined(AST_MISDN_ENHANCEMENTS) && defined(CCBS_TEST_MESSAGES)
-static const struct FacParm Fac_Msgs[] = {
-/* *INDENT-OFF* */
-       [0].Function = Fac_ERROR,
-       [0].u.ERROR.invokeId = 8,
-       [0].u.ERROR.errorValue = FacError_CCBS_AlreadyAccepted,
-
-       [1].Function = Fac_RESULT,
-       [1].u.RESULT.InvokeID = 9,
-
-       [2].Function = Fac_REJECT,
-       [2].u.REJECT.Code = FacReject_Gen_BadlyStructuredComponent,
-
-       [3].Function = Fac_REJECT,
-       [3].u.REJECT.InvokeIDPresent = 1,
-       [3].u.REJECT.InvokeID = 10,
-       [3].u.REJECT.Code = FacReject_Inv_InitiatorReleasing,
-
-       [4].Function = Fac_REJECT,
-       [4].u.REJECT.InvokeIDPresent = 1,
-       [4].u.REJECT.InvokeID = 11,
-       [4].u.REJECT.Code = FacReject_Res_MistypedResult,
-
-       [5].Function = Fac_REJECT,
-       [5].u.REJECT.InvokeIDPresent = 1,
-       [5].u.REJECT.InvokeID = 12,
-       [5].u.REJECT.Code = FacReject_Err_ErrorResponseUnexpected,
-
-       [6].Function = Fac_StatusRequest,
-       [6].u.StatusRequest.InvokeID = 13,
-       [6].u.StatusRequest.ComponentType = FacComponent_Invoke,
-       [6].u.StatusRequest.Component.Invoke.Q931ie.Bc.Length = 2,
-       [6].u.StatusRequest.Component.Invoke.Q931ie.Bc.Contents = "AB",
-       [6].u.StatusRequest.Component.Invoke.Q931ie.Llc.Length = 3,
-       [6].u.StatusRequest.Component.Invoke.Q931ie.Llc.Contents = "CDE",
-       [6].u.StatusRequest.Component.Invoke.Q931ie.Hlc.Length = 4,
-       [6].u.StatusRequest.Component.Invoke.Q931ie.Hlc.Contents = "FGHI",
-       [6].u.StatusRequest.Component.Invoke.CompatibilityMode = 1,
-
-       [7].Function = Fac_StatusRequest,
-       [7].u.StatusRequest.InvokeID = 14,
-       [7].u.StatusRequest.ComponentType = FacComponent_Result,
-       [7].u.StatusRequest.Component.Result.Status = 2,
-
-       [8].Function = Fac_CallInfoRetain,
-       [8].u.CallInfoRetain.InvokeID = 15,
-       [8].u.CallInfoRetain.CallLinkageID = 115,
-
-       [9].Function = Fac_EraseCallLinkageID,
-       [9].u.EraseCallLinkageID.InvokeID = 16,
-       [9].u.EraseCallLinkageID.CallLinkageID = 105,
-
-       [10].Function = Fac_CCBSDeactivate,
-       [10].u.CCBSDeactivate.InvokeID = 17,
-       [10].u.CCBSDeactivate.ComponentType = FacComponent_Invoke,
-       [10].u.CCBSDeactivate.Component.Invoke.CCBSReference = 2,
-
-       [11].Function = Fac_CCBSDeactivate,
-       [11].u.CCBSDeactivate.InvokeID = 18,
-       [11].u.CCBSDeactivate.ComponentType = FacComponent_Result,
-
-       [12].Function = Fac_CCBSErase,
-       [12].u.CCBSErase.InvokeID = 19,
-       [12].u.CCBSErase.Q931ie.Bc.Length = 2,
-       [12].u.CCBSErase.Q931ie.Bc.Contents = "JK",
-       [12].u.CCBSErase.AddressOfB.Party.Type = 0,
-       [12].u.CCBSErase.AddressOfB.Party.LengthOfNumber = 5,
-       [12].u.CCBSErase.AddressOfB.Party.Number = "33403",
-       [12].u.CCBSErase.AddressOfB.Subaddress.Type = 0,
-       [12].u.CCBSErase.AddressOfB.Subaddress.Length = 4,
-       [12].u.CCBSErase.AddressOfB.Subaddress.u.UserSpecified.Information = "3748",
-       [12].u.CCBSErase.RecallMode = 1,
-       [12].u.CCBSErase.CCBSReference = 102,
-       [12].u.CCBSErase.Reason = 3,
-
-       [13].Function = Fac_CCBSErase,
-       [13].u.CCBSErase.InvokeID = 20,
-       [13].u.CCBSErase.Q931ie.Bc.Length = 2,
-       [13].u.CCBSErase.Q931ie.Bc.Contents = "JK",
-       [13].u.CCBSErase.AddressOfB.Party.Type = 1,
-       [13].u.CCBSErase.AddressOfB.Party.LengthOfNumber = 11,
-       [13].u.CCBSErase.AddressOfB.Party.TypeOfNumber = 1,
-       [13].u.CCBSErase.AddressOfB.Party.Number = "18003020102",
-       [13].u.CCBSErase.AddressOfB.Subaddress.Type = 0,
-       [13].u.CCBSErase.AddressOfB.Subaddress.Length = 4,
-       [13].u.CCBSErase.AddressOfB.Subaddress.u.UserSpecified.OddCountPresent = 1,
-       [13].u.CCBSErase.AddressOfB.Subaddress.u.UserSpecified.OddCount = 1,
-       [13].u.CCBSErase.AddressOfB.Subaddress.u.UserSpecified.Information = "3748",
-       [13].u.CCBSErase.RecallMode = 1,
-       [13].u.CCBSErase.CCBSReference = 102,
-       [13].u.CCBSErase.Reason = 3,
-
-       [14].Function = Fac_CCBSErase,
-       [14].u.CCBSErase.InvokeID = 21,
-       [14].u.CCBSErase.Q931ie.Bc.Length = 2,
-       [14].u.CCBSErase.Q931ie.Bc.Contents = "JK",
-       [14].u.CCBSErase.AddressOfB.Party.Type = 2,
-       [14].u.CCBSErase.AddressOfB.Party.LengthOfNumber = 4,
-       [14].u.CCBSErase.AddressOfB.Party.Number = "1803",
-       [14].u.CCBSErase.AddressOfB.Subaddress.Type = 1,
-       [14].u.CCBSErase.AddressOfB.Subaddress.Length = 4,
-       [14].u.CCBSErase.AddressOfB.Subaddress.u.Nsap = "6492",
-       [14].u.CCBSErase.RecallMode = 1,
-       [14].u.CCBSErase.CCBSReference = 102,
-       [14].u.CCBSErase.Reason = 3,
-
-       [15].Function = Fac_CCBSErase,
-       [15].u.CCBSErase.InvokeID = 22,
-       [15].u.CCBSErase.Q931ie.Bc.Length = 2,
-       [15].u.CCBSErase.Q931ie.Bc.Contents = "JK",
-       [15].u.CCBSErase.AddressOfB.Party.Type = 3,
-       [15].u.CCBSErase.AddressOfB.Party.LengthOfNumber = 4,
-       [15].u.CCBSErase.AddressOfB.Party.Number = "1803",
-       [15].u.CCBSErase.RecallMode = 1,
-       [15].u.CCBSErase.CCBSReference = 102,
-       [15].u.CCBSErase.Reason = 3,
-
-       [16].Function = Fac_CCBSErase,
-       [16].u.CCBSErase.InvokeID = 23,
-       [16].u.CCBSErase.Q931ie.Bc.Length = 2,
-       [16].u.CCBSErase.Q931ie.Bc.Contents = "JK",
-       [16].u.CCBSErase.AddressOfB.Party.Type = 4,
-       [16].u.CCBSErase.AddressOfB.Party.LengthOfNumber = 4,
-       [16].u.CCBSErase.AddressOfB.Party.Number = "1803",
-       [16].u.CCBSErase.RecallMode = 1,
-       [16].u.CCBSErase.CCBSReference = 102,
-       [16].u.CCBSErase.Reason = 3,
-
-       [17].Function = Fac_CCBSErase,
-       [17].u.CCBSErase.InvokeID = 24,
-       [17].u.CCBSErase.Q931ie.Bc.Length = 2,
-       [17].u.CCBSErase.Q931ie.Bc.Contents = "JK",
-       [17].u.CCBSErase.AddressOfB.Party.Type = 5,
-       [17].u.CCBSErase.AddressOfB.Party.LengthOfNumber = 11,
-       [17].u.CCBSErase.AddressOfB.Party.TypeOfNumber = 4,
-       [17].u.CCBSErase.AddressOfB.Party.Number = "18003020102",
-       [17].u.CCBSErase.RecallMode = 1,
-       [17].u.CCBSErase.CCBSReference = 102,
-       [17].u.CCBSErase.Reason = 3,
-
-       [18].Function = Fac_CCBSErase,
-       [18].u.CCBSErase.InvokeID = 25,
-       [18].u.CCBSErase.Q931ie.Bc.Length = 2,
-       [18].u.CCBSErase.Q931ie.Bc.Contents = "JK",
-       [18].u.CCBSErase.AddressOfB.Party.Type = 8,
-       [18].u.CCBSErase.AddressOfB.Party.LengthOfNumber = 4,
-       [18].u.CCBSErase.AddressOfB.Party.Number = "1803",
-       [18].u.CCBSErase.RecallMode = 1,
-       [18].u.CCBSErase.CCBSReference = 102,
-       [18].u.CCBSErase.Reason = 3,
-
-       [19].Function = Fac_CCBSRemoteUserFree,
-       [19].u.CCBSRemoteUserFree.InvokeID = 26,
-       [19].u.CCBSRemoteUserFree.Q931ie.Bc.Length = 2,
-       [19].u.CCBSRemoteUserFree.Q931ie.Bc.Contents = "JK",
-       [19].u.CCBSRemoteUserFree.AddressOfB.Party.Type = 8,
-       [19].u.CCBSRemoteUserFree.AddressOfB.Party.LengthOfNumber = 4,
-       [19].u.CCBSRemoteUserFree.AddressOfB.Party.Number = "1803",
-       [19].u.CCBSRemoteUserFree.RecallMode = 1,
-       [19].u.CCBSRemoteUserFree.CCBSReference = 102,
-
-       [20].Function = Fac_CCBSCall,
-       [20].u.CCBSCall.InvokeID = 27,
-       [20].u.CCBSCall.CCBSReference = 115,
-
-       [21].Function = Fac_CCBSStatusRequest,
-       [21].u.CCBSStatusRequest.InvokeID = 28,
-       [21].u.CCBSStatusRequest.ComponentType = FacComponent_Invoke,
-       [21].u.CCBSStatusRequest.Component.Invoke.Q931ie.Bc.Length = 2,
-       [21].u.CCBSStatusRequest.Component.Invoke.Q931ie.Bc.Contents = "JK",
-       [21].u.CCBSStatusRequest.Component.Invoke.RecallMode = 1,
-       [21].u.CCBSStatusRequest.Component.Invoke.CCBSReference = 102,
-
-       [22].Function = Fac_CCBSStatusRequest,
-       [22].u.CCBSStatusRequest.InvokeID = 29,
-       [22].u.CCBSStatusRequest.ComponentType = FacComponent_Result,
-       [22].u.CCBSStatusRequest.Component.Result.Free = 1,
-
-       [23].Function = Fac_CCBSBFree,
-       [23].u.CCBSBFree.InvokeID = 30,
-       [23].u.CCBSBFree.Q931ie.Bc.Length = 2,
-       [23].u.CCBSBFree.Q931ie.Bc.Contents = "JK",
-       [23].u.CCBSBFree.AddressOfB.Party.Type = 8,
-       [23].u.CCBSBFree.AddressOfB.Party.LengthOfNumber = 4,
-       [23].u.CCBSBFree.AddressOfB.Party.Number = "1803",
-       [23].u.CCBSBFree.RecallMode = 1,
-       [23].u.CCBSBFree.CCBSReference = 14,
-
-       [24].Function = Fac_CCBSStopAlerting,
-       [24].u.CCBSStopAlerting.InvokeID = 31,
-       [24].u.CCBSStopAlerting.CCBSReference = 37,
-
-       [25].Function = Fac_CCBSRequest,
-       [25].u.CCBSRequest.InvokeID = 32,
-       [25].u.CCBSRequest.ComponentType = FacComponent_Invoke,
-       [25].u.CCBSRequest.Component.Invoke.CallLinkageID = 57,
-
-       [26].Function = Fac_CCBSRequest,
-       [26].u.CCBSRequest.InvokeID = 33,
-       [26].u.CCBSRequest.ComponentType = FacComponent_Result,
-       [26].u.CCBSRequest.Component.Result.RecallMode = 1,
-       [26].u.CCBSRequest.Component.Result.CCBSReference = 102,
-
-       [27].Function = Fac_CCBSInterrogate,
-       [27].u.CCBSInterrogate.InvokeID = 34,
-       [27].u.CCBSInterrogate.ComponentType = FacComponent_Invoke,
-       [27].u.CCBSInterrogate.Component.Invoke.AParty.Type = 8,
-       [27].u.CCBSInterrogate.Component.Invoke.AParty.LengthOfNumber = 4,
-       [27].u.CCBSInterrogate.Component.Invoke.AParty.Number = "1803",
-       [27].u.CCBSInterrogate.Component.Invoke.CCBSReferencePresent = 1,
-       [27].u.CCBSInterrogate.Component.Invoke.CCBSReference = 76,
-
-       [28].Function = Fac_CCBSInterrogate,
-       [28].u.CCBSInterrogate.InvokeID = 35,
-       [28].u.CCBSInterrogate.ComponentType = FacComponent_Invoke,
-       [28].u.CCBSInterrogate.Component.Invoke.AParty.Type = 8,
-       [28].u.CCBSInterrogate.Component.Invoke.AParty.LengthOfNumber = 4,
-       [28].u.CCBSInterrogate.Component.Invoke.AParty.Number = "1803",
-
-       [29].Function = Fac_CCBSInterrogate,
-       [29].u.CCBSInterrogate.InvokeID = 36,
-       [29].u.CCBSInterrogate.ComponentType = FacComponent_Invoke,
-       [29].u.CCBSInterrogate.Component.Invoke.CCBSReferencePresent = 1,
-       [29].u.CCBSInterrogate.Component.Invoke.CCBSReference = 76,
-
-       [30].Function = Fac_CCBSInterrogate,
-       [30].u.CCBSInterrogate.InvokeID = 37,
-       [30].u.CCBSInterrogate.ComponentType = FacComponent_Invoke,
-
-       [31].Function = Fac_CCBSInterrogate,
-       [31].u.CCBSInterrogate.InvokeID = 38,
-       [31].u.CCBSInterrogate.ComponentType = FacComponent_Result,
-       [31].u.CCBSInterrogate.Component.Result.RecallMode = 1,
-
-       [32].Function = Fac_CCBSInterrogate,
-       [32].u.CCBSInterrogate.InvokeID = 39,
-       [32].u.CCBSInterrogate.ComponentType = FacComponent_Result,
-       [32].u.CCBSInterrogate.Component.Result.RecallMode = 1,
-       [32].u.CCBSInterrogate.Component.Result.NumRecords = 1,
-       [32].u.CCBSInterrogate.Component.Result.CallDetails[0].CCBSReference = 12,
-       [32].u.CCBSInterrogate.Component.Result.CallDetails[0].Q931ie.Bc.Length = 2,
-       [32].u.CCBSInterrogate.Component.Result.CallDetails[0].Q931ie.Bc.Contents = "JK",
-       [32].u.CCBSInterrogate.Component.Result.CallDetails[0].AddressOfB.Party.Type = 8,
-       [32].u.CCBSInterrogate.Component.Result.CallDetails[0].AddressOfB.Party.LengthOfNumber = 4,
-       [32].u.CCBSInterrogate.Component.Result.CallDetails[0].AddressOfB.Party.Number = "1803",
-       [32].u.CCBSInterrogate.Component.Result.CallDetails[0].SubaddressOfA.Type = 1,
-       [32].u.CCBSInterrogate.Component.Result.CallDetails[0].SubaddressOfA.Length = 4,
-       [32].u.CCBSInterrogate.Component.Result.CallDetails[0].SubaddressOfA.u.Nsap = "6492",
-
-       [33].Function = Fac_CCBSInterrogate,
-       [33].u.CCBSInterrogate.InvokeID = 40,
-       [33].u.CCBSInterrogate.ComponentType = FacComponent_Result,
-       [33].u.CCBSInterrogate.Component.Result.RecallMode = 1,
-       [33].u.CCBSInterrogate.Component.Result.NumRecords = 2,
-       [33].u.CCBSInterrogate.Component.Result.CallDetails[0].CCBSReference = 12,
-       [33].u.CCBSInterrogate.Component.Result.CallDetails[0].Q931ie.Bc.Length = 2,
-       [33].u.CCBSInterrogate.Component.Result.CallDetails[0].Q931ie.Bc.Contents = "JK",
-       [33].u.CCBSInterrogate.Component.Result.CallDetails[0].AddressOfB.Party.Type = 8,
-       [33].u.CCBSInterrogate.Component.Result.CallDetails[0].AddressOfB.Party.LengthOfNumber = 4,
-       [33].u.CCBSInterrogate.Component.Result.CallDetails[0].AddressOfB.Party.Number = "1803",
-       [33].u.CCBSInterrogate.Component.Result.CallDetails[1].CCBSReference = 102,
-       [33].u.CCBSInterrogate.Component.Result.CallDetails[1].Q931ie.Bc.Length = 2,
-       [33].u.CCBSInterrogate.Component.Result.CallDetails[1].Q931ie.Bc.Contents = "LM",
-       [33].u.CCBSInterrogate.Component.Result.CallDetails[1].AddressOfB.Party.Type = 8,
-       [33].u.CCBSInterrogate.Component.Result.CallDetails[1].AddressOfB.Party.LengthOfNumber = 4,
-       [33].u.CCBSInterrogate.Component.Result.CallDetails[1].AddressOfB.Party.Number = "6229",
-       [33].u.CCBSInterrogate.Component.Result.CallDetails[1].AddressOfB.Subaddress.Type = 1,
-       [33].u.CCBSInterrogate.Component.Result.CallDetails[1].AddressOfB.Subaddress.Length = 4,
-       [33].u.CCBSInterrogate.Component.Result.CallDetails[1].AddressOfB.Subaddress.u.Nsap = "8592",
-       [33].u.CCBSInterrogate.Component.Result.CallDetails[1].SubaddressOfA.Type = 1,
-       [33].u.CCBSInterrogate.Component.Result.CallDetails[1].SubaddressOfA.Length = 4,
-       [33].u.CCBSInterrogate.Component.Result.CallDetails[1].SubaddressOfA.u.Nsap = "6492",
-
-       [34].Function = Fac_CCNRRequest,
-       [34].u.CCNRRequest.InvokeID = 512,
-       [34].u.CCNRRequest.ComponentType = FacComponent_Invoke,
-       [34].u.CCNRRequest.Component.Invoke.CallLinkageID = 57,
-
-       [35].Function = Fac_CCNRRequest,
-       [35].u.CCNRRequest.InvokeID = 150,
-       [35].u.CCNRRequest.ComponentType = FacComponent_Result,
-       [35].u.CCNRRequest.Component.Result.RecallMode = 1,
-       [35].u.CCNRRequest.Component.Result.CCBSReference = 102,
-
-       [36].Function = Fac_CCNRInterrogate,
-       [36].u.CCNRInterrogate.InvokeID = -129,
-       [36].u.CCNRInterrogate.ComponentType = FacComponent_Invoke,
-
-       [37].Function = Fac_CCNRInterrogate,
-       [37].u.CCNRInterrogate.InvokeID = -3,
-       [37].u.CCNRInterrogate.ComponentType = FacComponent_Result,
-       [37].u.CCNRInterrogate.Component.Result.RecallMode = 1,
-
-       [38].Function = Fac_CCBS_T_Call,
-       [38].u.EctExecute.InvokeID = 41,
-
-       [39].Function = Fac_CCBS_T_Suspend,
-       [39].u.EctExecute.InvokeID = 42,
-
-       [40].Function = Fac_CCBS_T_Resume,
-       [40].u.EctExecute.InvokeID = 43,
-
-       [41].Function = Fac_CCBS_T_RemoteUserFree,
-       [41].u.EctExecute.InvokeID = 44,
-
-       [42].Function = Fac_CCBS_T_Available,
-       [42].u.EctExecute.InvokeID = 45,
-
-       [43].Function = Fac_CCBS_T_Request,
-       [43].u.CCBS_T_Request.InvokeID = 46,
-       [43].u.CCBS_T_Request.ComponentType = FacComponent_Invoke,
-       [43].u.CCBS_T_Request.Component.Invoke.Destination.Party.Type = 8,
-       [43].u.CCBS_T_Request.Component.Invoke.Destination.Party.LengthOfNumber = 4,
-       [43].u.CCBS_T_Request.Component.Invoke.Destination.Party.Number = "6229",
-       [43].u.CCBS_T_Request.Component.Invoke.Q931ie.Bc.Length = 2,
-       [43].u.CCBS_T_Request.Component.Invoke.Q931ie.Bc.Contents = "LM",
-       [43].u.CCBS_T_Request.Component.Invoke.RetentionSupported = 1,
-       [43].u.CCBS_T_Request.Component.Invoke.PresentationAllowedIndicatorPresent = 1,
-       [43].u.CCBS_T_Request.Component.Invoke.PresentationAllowedIndicator = 1,
-       [43].u.CCBS_T_Request.Component.Invoke.Originating.Party.Type = 8,
-       [43].u.CCBS_T_Request.Component.Invoke.Originating.Party.LengthOfNumber = 4,
-       [43].u.CCBS_T_Request.Component.Invoke.Originating.Party.Number = "9864",
-
-       [44].Function = Fac_CCBS_T_Request,
-       [44].u.CCBS_T_Request.InvokeID = 47,
-       [44].u.CCBS_T_Request.ComponentType = FacComponent_Invoke,
-       [44].u.CCBS_T_Request.Component.Invoke.Destination.Party.Type = 8,
-       [44].u.CCBS_T_Request.Component.Invoke.Destination.Party.LengthOfNumber = 4,
-       [44].u.CCBS_T_Request.Component.Invoke.Destination.Party.Number = "6229",
-       [44].u.CCBS_T_Request.Component.Invoke.Q931ie.Bc.Length = 2,
-       [44].u.CCBS_T_Request.Component.Invoke.Q931ie.Bc.Contents = "LM",
-       [44].u.CCBS_T_Request.Component.Invoke.PresentationAllowedIndicatorPresent = 1,
-       [44].u.CCBS_T_Request.Component.Invoke.PresentationAllowedIndicator = 1,
-       [44].u.CCBS_T_Request.Component.Invoke.Originating.Party.Type = 8,
-       [44].u.CCBS_T_Request.Component.Invoke.Originating.Party.LengthOfNumber = 4,
-       [44].u.CCBS_T_Request.Component.Invoke.Originating.Party.Number = "9864",
-
-       [45].Function = Fac_CCBS_T_Request,
-       [45].u.CCBS_T_Request.InvokeID = 48,
-       [45].u.CCBS_T_Request.ComponentType = FacComponent_Invoke,
-       [45].u.CCBS_T_Request.Component.Invoke.Destination.Party.Type = 8,
-       [45].u.CCBS_T_Request.Component.Invoke.Destination.Party.LengthOfNumber = 4,
-       [45].u.CCBS_T_Request.Component.Invoke.Destination.Party.Number = "6229",
-       [45].u.CCBS_T_Request.Component.Invoke.Q931ie.Bc.Length = 2,
-       [45].u.CCBS_T_Request.Component.Invoke.Q931ie.Bc.Contents = "LM",
-       [45].u.CCBS_T_Request.Component.Invoke.Originating.Party.Type = 8,
-       [45].u.CCBS_T_Request.Component.Invoke.Originating.Party.LengthOfNumber = 4,
-       [45].u.CCBS_T_Request.Component.Invoke.Originating.Party.Number = "9864",
-
-       [46].Function = Fac_CCBS_T_Request,
-       [46].u.CCBS_T_Request.InvokeID = 49,
-       [46].u.CCBS_T_Request.ComponentType = FacComponent_Invoke,
-       [46].u.CCBS_T_Request.Component.Invoke.Destination.Party.Type = 8,
-       [46].u.CCBS_T_Request.Component.Invoke.Destination.Party.LengthOfNumber = 4,
-       [46].u.CCBS_T_Request.Component.Invoke.Destination.Party.Number = "6229",
-       [46].u.CCBS_T_Request.Component.Invoke.Q931ie.Bc.Length = 2,
-       [46].u.CCBS_T_Request.Component.Invoke.Q931ie.Bc.Contents = "LM",
-       [46].u.CCBS_T_Request.Component.Invoke.PresentationAllowedIndicatorPresent = 1,
-       [46].u.CCBS_T_Request.Component.Invoke.PresentationAllowedIndicator = 1,
-
-       [47].Function = Fac_CCBS_T_Request,
-       [47].u.CCBS_T_Request.InvokeID = 50,
-       [47].u.CCBS_T_Request.ComponentType = FacComponent_Invoke,
-       [47].u.CCBS_T_Request.Component.Invoke.Destination.Party.Type = 8,
-       [47].u.CCBS_T_Request.Component.Invoke.Destination.Party.LengthOfNumber = 4,
-       [47].u.CCBS_T_Request.Component.Invoke.Destination.Party.Number = "6229",
-       [47].u.CCBS_T_Request.Component.Invoke.Q931ie.Bc.Length = 2,
-       [47].u.CCBS_T_Request.Component.Invoke.Q931ie.Bc.Contents = "LM",
-
-       [48].Function = Fac_CCBS_T_Request,
-       [48].u.CCBS_T_Request.InvokeID = 51,
-       [48].u.CCBS_T_Request.ComponentType = FacComponent_Result,
-       [48].u.CCBS_T_Request.Component.Result.RetentionSupported = 1,
-
-       [49].Function = Fac_CCNR_T_Request,
-       [49].u.CCNR_T_Request.InvokeID = 52,
-       [49].u.CCNR_T_Request.ComponentType = FacComponent_Invoke,
-       [49].u.CCNR_T_Request.Component.Invoke.Destination.Party.Type = 8,
-       [49].u.CCNR_T_Request.Component.Invoke.Destination.Party.LengthOfNumber = 4,
-       [49].u.CCNR_T_Request.Component.Invoke.Destination.Party.Number = "6229",
-       [49].u.CCNR_T_Request.Component.Invoke.Q931ie.Bc.Length = 2,
-       [49].u.CCNR_T_Request.Component.Invoke.Q931ie.Bc.Contents = "LM",
-
-       [50].Function = Fac_CCNR_T_Request,
-       [50].u.CCNR_T_Request.InvokeID = 53,
-       [50].u.CCNR_T_Request.ComponentType = FacComponent_Result,
-       [50].u.CCNR_T_Request.Component.Result.RetentionSupported = 1,
-
-       [51].Function = Fac_EctExecute,
-       [51].u.EctExecute.InvokeID = 54,
-
-       [52].Function = Fac_ExplicitEctExecute,
-       [52].u.ExplicitEctExecute.InvokeID = 55,
-       [52].u.ExplicitEctExecute.LinkID = 23,
-
-       [53].Function = Fac_RequestSubaddress,
-       [53].u.RequestSubaddress.InvokeID = 56,
-
-       [54].Function = Fac_SubaddressTransfer,
-       [54].u.SubaddressTransfer.InvokeID = 57,
-       [54].u.SubaddressTransfer.Subaddress.Type = 1,
-       [54].u.SubaddressTransfer.Subaddress.Length = 4,
-       [54].u.SubaddressTransfer.Subaddress.u.Nsap = "6492",
-
-       [55].Function = Fac_EctLinkIdRequest,
-       [55].u.EctLinkIdRequest.InvokeID = 58,
-       [55].u.EctLinkIdRequest.ComponentType = FacComponent_Invoke,
-
-       [56].Function = Fac_EctLinkIdRequest,
-       [56].u.EctLinkIdRequest.InvokeID = 59,
-       [56].u.EctLinkIdRequest.ComponentType = FacComponent_Result,
-       [56].u.EctLinkIdRequest.Component.Result.LinkID = 76,
-
-       [57].Function = Fac_EctInform,
-       [57].u.EctInform.InvokeID = 60,
-       [57].u.EctInform.Status = 1,
-       [57].u.EctInform.RedirectionPresent = 1,
-       [57].u.EctInform.Redirection.Type = 0,
-       [57].u.EctInform.Redirection.Unscreened.Type = 8,
-       [57].u.EctInform.Redirection.Unscreened.LengthOfNumber = 4,
-       [57].u.EctInform.Redirection.Unscreened.Number = "6229",
-
-       [58].Function = Fac_EctInform,
-       [58].u.EctInform.InvokeID = 61,
-       [58].u.EctInform.Status = 1,
-       [58].u.EctInform.RedirectionPresent = 1,
-       [58].u.EctInform.Redirection.Type = 1,
-
-       [59].Function = Fac_EctInform,
-       [59].u.EctInform.InvokeID = 62,
-       [59].u.EctInform.Status = 1,
-       [59].u.EctInform.RedirectionPresent = 1,
-       [59].u.EctInform.Redirection.Type = 2,
-
-       [60].Function = Fac_EctInform,
-       [60].u.EctInform.InvokeID = 63,
-       [60].u.EctInform.Status = 1,
-       [60].u.EctInform.RedirectionPresent = 1,
-       [60].u.EctInform.Redirection.Type = 3,
-       [60].u.EctInform.Redirection.Unscreened.Type = 8,
-       [60].u.EctInform.Redirection.Unscreened.LengthOfNumber = 4,
-       [60].u.EctInform.Redirection.Unscreened.Number = "3340",
-
-       [61].Function = Fac_EctInform,
-       [61].u.EctInform.InvokeID = 64,
-       [61].u.EctInform.Status = 1,
-       [61].u.EctInform.RedirectionPresent = 0,
-
-       [62].Function = Fac_EctLoopTest,
-       [62].u.EctLoopTest.InvokeID = 65,
-       [62].u.EctLoopTest.ComponentType = FacComponent_Invoke,
-       [62].u.EctLoopTest.Component.Invoke.CallTransferID = 7,
-
-       [63].Function = Fac_EctLoopTest,
-       [63].u.EctLoopTest.InvokeID = 66,
-       [63].u.EctLoopTest.ComponentType = FacComponent_Result,
-       [63].u.EctLoopTest.Component.Result.LoopResult = 2,
-
-       [64].Function = Fac_ActivationDiversion,
-       [64].u.ActivationDiversion.InvokeID = 67,
-       [64].u.ActivationDiversion.ComponentType = FacComponent_Invoke,
-       [64].u.ActivationDiversion.Component.Invoke.Procedure = 2,
-       [64].u.ActivationDiversion.Component.Invoke.BasicService = 3,
-       [64].u.ActivationDiversion.Component.Invoke.ForwardedTo.Party.Type = 4,
-       [64].u.ActivationDiversion.Component.Invoke.ForwardedTo.Party.LengthOfNumber = 4,
-       [64].u.ActivationDiversion.Component.Invoke.ForwardedTo.Party.Number = "1803",
-       [64].u.ActivationDiversion.Component.Invoke.ServedUser.Type = 4,
-       [64].u.ActivationDiversion.Component.Invoke.ServedUser.LengthOfNumber = 4,
-       [64].u.ActivationDiversion.Component.Invoke.ServedUser.Number = "5398",
-
-       [65].Function = Fac_ActivationDiversion,
-       [65].u.ActivationDiversion.InvokeID = 68,
-       [65].u.ActivationDiversion.ComponentType = FacComponent_Invoke,
-       [65].u.ActivationDiversion.Component.Invoke.Procedure = 1,
-       [65].u.ActivationDiversion.Component.Invoke.BasicService = 5,
-       [65].u.ActivationDiversion.Component.Invoke.ForwardedTo.Party.Type = 4,
-       [65].u.ActivationDiversion.Component.Invoke.ForwardedTo.Party.LengthOfNumber = 4,
-       [65].u.ActivationDiversion.Component.Invoke.ForwardedTo.Party.Number = "1803",
-
-       [66].Function = Fac_ActivationDiversion,
-       [66].u.ActivationDiversion.InvokeID = 69,
-       [66].u.ActivationDiversion.ComponentType = FacComponent_Result,
-
-       [67].Function = Fac_DeactivationDiversion,
-       [67].u.DeactivationDiversion.InvokeID = 70,
-       [67].u.DeactivationDiversion.ComponentType = FacComponent_Invoke,
-       [67].u.DeactivationDiversion.Component.Invoke.Procedure = 1,
-       [67].u.DeactivationDiversion.Component.Invoke.BasicService = 5,
-
-       [68].Function = Fac_DeactivationDiversion,
-       [68].u.DeactivationDiversion.InvokeID = 71,
-       [68].u.DeactivationDiversion.ComponentType = FacComponent_Result,
-
-       [69].Function = Fac_ActivationStatusNotificationDiv,
-       [69].u.ActivationStatusNotificationDiv.InvokeID = 72,
-       [69].u.ActivationStatusNotificationDiv.Procedure = 1,
-       [69].u.ActivationStatusNotificationDiv.BasicService = 5,
-       [69].u.ActivationStatusNotificationDiv.ForwardedTo.Party.Type = 4,
-       [69].u.ActivationStatusNotificationDiv.ForwardedTo.Party.LengthOfNumber = 4,
-       [69].u.ActivationStatusNotificationDiv.ForwardedTo.Party.Number = "1803",
-
-       [70].Function = Fac_DeactivationStatusNotificationDiv,
-       [70].u.DeactivationStatusNotificationDiv.InvokeID = 73,
-       [70].u.DeactivationStatusNotificationDiv.Procedure = 1,
-       [70].u.DeactivationStatusNotificationDiv.BasicService = 5,
-
-       [71].Function = Fac_InterrogationDiversion,
-       [71].u.InterrogationDiversion.InvokeID = 74,
-       [71].u.InterrogationDiversion.ComponentType = FacComponent_Invoke,
-       [71].u.InterrogationDiversion.Component.Invoke.Procedure = 1,
-       [71].u.InterrogationDiversion.Component.Invoke.BasicService = 5,
-
-       [72].Function = Fac_InterrogationDiversion,
-       [72].u.InterrogationDiversion.InvokeID = 75,
-       [72].u.InterrogationDiversion.ComponentType = FacComponent_Invoke,
-       [72].u.InterrogationDiversion.Component.Invoke.Procedure = 1,
-
-       [73].Function = Fac_InterrogationDiversion,
-       [73].u.InterrogationDiversion.InvokeID = 76,
-       [73].u.InterrogationDiversion.ComponentType = FacComponent_Result,
-       [73].u.InterrogationDiversion.Component.Result.NumRecords = 2,
-       [73].u.InterrogationDiversion.Component.Result.List[0].Procedure = 2,
-       [73].u.InterrogationDiversion.Component.Result.List[0].BasicService = 5,
-       [73].u.InterrogationDiversion.Component.Result.List[0].ForwardedTo.Party.Type = 4,
-       [73].u.InterrogationDiversion.Component.Result.List[0].ForwardedTo.Party.LengthOfNumber = 4,
-       [73].u.InterrogationDiversion.Component.Result.List[0].ForwardedTo.Party.Number = "1803",
-       [73].u.InterrogationDiversion.Component.Result.List[1].Procedure = 1,
-       [73].u.InterrogationDiversion.Component.Result.List[1].BasicService = 3,
-       [73].u.InterrogationDiversion.Component.Result.List[1].ForwardedTo.Party.Type = 4,
-       [73].u.InterrogationDiversion.Component.Result.List[1].ForwardedTo.Party.LengthOfNumber = 4,
-       [73].u.InterrogationDiversion.Component.Result.List[1].ForwardedTo.Party.Number = "1903",
-       [73].u.InterrogationDiversion.Component.Result.List[1].ServedUser.Type = 4,
-       [73].u.InterrogationDiversion.Component.Result.List[1].ServedUser.LengthOfNumber = 4,
-       [73].u.InterrogationDiversion.Component.Result.List[1].ServedUser.Number = "5398",
-
-       [74].Function = Fac_DiversionInformation,
-       [74].u.DiversionInformation.InvokeID = 77,
-       [74].u.DiversionInformation.DiversionReason = 3,
-       [74].u.DiversionInformation.BasicService = 5,
-       [74].u.DiversionInformation.ServedUserSubaddress.Type = 1,
-       [74].u.DiversionInformation.ServedUserSubaddress.Length = 4,
-       [74].u.DiversionInformation.ServedUserSubaddress.u.Nsap = "6492",
-       [74].u.DiversionInformation.CallingAddressPresent = 1,
-       [74].u.DiversionInformation.CallingAddress.Type = 0,
-       [74].u.DiversionInformation.CallingAddress.Address.ScreeningIndicator = 3,
-       [74].u.DiversionInformation.CallingAddress.Address.Party.Type = 4,
-       [74].u.DiversionInformation.CallingAddress.Address.Party.LengthOfNumber = 4,
-       [74].u.DiversionInformation.CallingAddress.Address.Party.Number = "1803",
-       [74].u.DiversionInformation.OriginalCalledPresent = 1,
-       [74].u.DiversionInformation.OriginalCalled.Type = 1,
-       [74].u.DiversionInformation.LastDivertingPresent = 1,
-       [74].u.DiversionInformation.LastDiverting.Type = 2,
-       [74].u.DiversionInformation.LastDivertingReasonPresent = 1,
-       [74].u.DiversionInformation.LastDivertingReason = 3,
-       [74].u.DiversionInformation.UserInfo.Length = 5,
-       [74].u.DiversionInformation.UserInfo.Contents = "79828",
-
-       [75].Function = Fac_DiversionInformation,
-       [75].u.DiversionInformation.InvokeID = 78,
-       [75].u.DiversionInformation.DiversionReason = 3,
-       [75].u.DiversionInformation.BasicService = 5,
-       [75].u.DiversionInformation.CallingAddressPresent = 1,
-       [75].u.DiversionInformation.CallingAddress.Type = 1,
-       [75].u.DiversionInformation.OriginalCalledPresent = 1,
-       [75].u.DiversionInformation.OriginalCalled.Type = 2,
-       [75].u.DiversionInformation.LastDivertingPresent = 1,
-       [75].u.DiversionInformation.LastDiverting.Type = 1,
-
-       [76].Function = Fac_DiversionInformation,
-       [76].u.DiversionInformation.InvokeID = 79,
-       [76].u.DiversionInformation.DiversionReason = 2,
-       [76].u.DiversionInformation.BasicService = 3,
-       [76].u.DiversionInformation.CallingAddressPresent = 1,
-       [76].u.DiversionInformation.CallingAddress.Type = 2,
-
-       [77].Function = Fac_DiversionInformation,
-       [77].u.DiversionInformation.InvokeID = 80,
-       [77].u.DiversionInformation.DiversionReason = 3,
-       [77].u.DiversionInformation.BasicService = 5,
-       [77].u.DiversionInformation.CallingAddressPresent = 1,
-       [77].u.DiversionInformation.CallingAddress.Type = 3,
-       [77].u.DiversionInformation.CallingAddress.Address.ScreeningIndicator = 2,
-       [77].u.DiversionInformation.CallingAddress.Address.Party.Type = 4,
-       [77].u.DiversionInformation.CallingAddress.Address.Party.LengthOfNumber = 4,
-       [77].u.DiversionInformation.CallingAddress.Address.Party.Number = "1803",
-
-       [78].Function = Fac_DiversionInformation,
-       [78].u.DiversionInformation.InvokeID = 81,
-       [78].u.DiversionInformation.DiversionReason = 2,
-       [78].u.DiversionInformation.BasicService = 4,
-       [78].u.DiversionInformation.UserInfo.Length = 5,
-       [78].u.DiversionInformation.UserInfo.Contents = "79828",
-
-       [79].Function = Fac_DiversionInformation,
-       [79].u.DiversionInformation.InvokeID = 82,
-       [79].u.DiversionInformation.DiversionReason = 2,
-       [79].u.DiversionInformation.BasicService = 4,
-
-       [80].Function = Fac_CallDeflection,
-       [80].u.CallDeflection.InvokeID = 83,
-       [80].u.CallDeflection.ComponentType = FacComponent_Invoke,
-       [80].u.CallDeflection.Component.Invoke.Deflection.Party.Type = 4,
-       [80].u.CallDeflection.Component.Invoke.Deflection.Party.LengthOfNumber = 4,
-       [80].u.CallDeflection.Component.Invoke.Deflection.Party.Number = "1803",
-       [80].u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUserPresent = 1,
-       [80].u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUser = 1,
-
-       [81].Function = Fac_CallDeflection,
-       [81].u.CallDeflection.InvokeID = 84,
-       [81].u.CallDeflection.ComponentType = FacComponent_Invoke,
-       [81].u.CallDeflection.Component.Invoke.Deflection.Party.Type = 4,
-       [81].u.CallDeflection.Component.Invoke.Deflection.Party.LengthOfNumber = 4,
-       [81].u.CallDeflection.Component.Invoke.Deflection.Party.Number = "1803",
-       [81].u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUserPresent = 1,
-       [81].u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUser = 0,
-
-       [82].Function = Fac_CallDeflection,
-       [82].u.CallDeflection.InvokeID = 85,
-       [82].u.CallDeflection.ComponentType = FacComponent_Invoke,
-       [82].u.CallDeflection.Component.Invoke.Deflection.Party.Type = 4,
-       [82].u.CallDeflection.Component.Invoke.Deflection.Party.LengthOfNumber = 4,
-       [82].u.CallDeflection.Component.Invoke.Deflection.Party.Number = "1803",
-
-       [83].Function = Fac_CallDeflection,
-       [83].u.CallDeflection.InvokeID = 86,
-       [83].u.CallDeflection.ComponentType = FacComponent_Result,
-
-       [84].Function = Fac_CallRerouteing,
-       [84].u.CallRerouteing.InvokeID = 87,
-       [84].u.CallRerouteing.ComponentType = FacComponent_Invoke,
-       [84].u.CallRerouteing.Component.Invoke.ReroutingReason = 3,
-       [84].u.CallRerouteing.Component.Invoke.ReroutingCounter = 2,
-       [84].u.CallRerouteing.Component.Invoke.CalledAddress.Party.Type = 4,
-       [84].u.CallRerouteing.Component.Invoke.CalledAddress.Party.LengthOfNumber = 4,
-       [84].u.CallRerouteing.Component.Invoke.CalledAddress.Party.Number = "1803",
-       [84].u.CallRerouteing.Component.Invoke.Q931ie.Bc.Length = 2,
-       [84].u.CallRerouteing.Component.Invoke.Q931ie.Bc.Contents = "RT",
-       [84].u.CallRerouteing.Component.Invoke.Q931ie.Hlc.Length = 3,
-       [84].u.CallRerouteing.Component.Invoke.Q931ie.Hlc.Contents = "RTG",
-       [84].u.CallRerouteing.Component.Invoke.Q931ie.Llc.Length = 2,
-       [84].u.CallRerouteing.Component.Invoke.Q931ie.Llc.Contents = "MY",
-       [84].u.CallRerouteing.Component.Invoke.Q931ie.UserInfo.Length = 5,
-       [84].u.CallRerouteing.Component.Invoke.Q931ie.UserInfo.Contents = "YEHAW",
-       [84].u.CallRerouteing.Component.Invoke.LastRerouting.Type = 1,
-       [84].u.CallRerouteing.Component.Invoke.SubscriptionOption = 2,
-       [84].u.CallRerouteing.Component.Invoke.CallingPartySubaddress.Type = 1,
-       [84].u.CallRerouteing.Component.Invoke.CallingPartySubaddress.Length = 4,
-       [84].u.CallRerouteing.Component.Invoke.CallingPartySubaddress.u.Nsap = "6492",
-
-       [85].Function = Fac_CallRerouteing,
-       [85].u.CallRerouteing.InvokeID = 88,
-       [85].u.CallRerouteing.ComponentType = FacComponent_Invoke,
-       [85].u.CallRerouteing.Component.Invoke.ReroutingReason = 3,
-       [85].u.CallRerouteing.Component.Invoke.ReroutingCounter = 2,
-       [85].u.CallRerouteing.Component.Invoke.CalledAddress.Party.Type = 4,
-       [85].u.CallRerouteing.Component.Invoke.CalledAddress.Party.LengthOfNumber = 4,
-       [85].u.CallRerouteing.Component.Invoke.CalledAddress.Party.Number = "1803",
-       [85].u.CallRerouteing.Component.Invoke.Q931ie.Bc.Length = 2,
-       [85].u.CallRerouteing.Component.Invoke.Q931ie.Bc.Contents = "RT",
-       [85].u.CallRerouteing.Component.Invoke.LastRerouting.Type = 1,
-       [85].u.CallRerouteing.Component.Invoke.SubscriptionOption = 2,
-
-       [86].Function = Fac_CallRerouteing,
-       [86].u.CallRerouteing.InvokeID = 89,
-       [86].u.CallRerouteing.ComponentType = FacComponent_Invoke,
-       [86].u.CallRerouteing.Component.Invoke.ReroutingReason = 3,
-       [86].u.CallRerouteing.Component.Invoke.ReroutingCounter = 2,
-       [86].u.CallRerouteing.Component.Invoke.CalledAddress.Party.Type = 4,
-       [86].u.CallRerouteing.Component.Invoke.CalledAddress.Party.LengthOfNumber = 4,
-       [86].u.CallRerouteing.Component.Invoke.CalledAddress.Party.Number = "1803",
-       [86].u.CallRerouteing.Component.Invoke.Q931ie.Bc.Length = 2,
-       [86].u.CallRerouteing.Component.Invoke.Q931ie.Bc.Contents = "RT",
-       [86].u.CallRerouteing.Component.Invoke.LastRerouting.Type = 2,
-
-       [87].Function = Fac_CallRerouteing,
-       [87].u.CallRerouteing.InvokeID = 90,
-       [87].u.CallRerouteing.ComponentType = FacComponent_Result,
-
-       [88].Function = Fac_InterrogateServedUserNumbers,
-       [88].u.InterrogateServedUserNumbers.InvokeID = 91,
-       [88].u.InterrogateServedUserNumbers.ComponentType = FacComponent_Invoke,
-
-       [89].Function = Fac_InterrogateServedUserNumbers,
-       [89].u.InterrogateServedUserNumbers.InvokeID = 92,
-       [89].u.InterrogateServedUserNumbers.ComponentType = FacComponent_Result,
-       [89].u.InterrogateServedUserNumbers.Component.Result.NumRecords = 2,
-       [89].u.InterrogateServedUserNumbers.Component.Result.List[0].Type = 4,
-       [89].u.InterrogateServedUserNumbers.Component.Result.List[0].LengthOfNumber = 4,
-       [89].u.InterrogateServedUserNumbers.Component.Result.List[0].Number = "1803",
-       [89].u.InterrogateServedUserNumbers.Component.Result.List[1].Type = 4,
-       [89].u.InterrogateServedUserNumbers.Component.Result.List[1].LengthOfNumber = 4,
-       [89].u.InterrogateServedUserNumbers.Component.Result.List[1].Number = "5786",
-
-       [90].Function = Fac_DivertingLegInformation1,
-       [90].u.DivertingLegInformation1.InvokeID = 93,
-       [90].u.DivertingLegInformation1.DiversionReason = 4,
-       [90].u.DivertingLegInformation1.SubscriptionOption = 1,
-       [90].u.DivertingLegInformation1.DivertedToPresent = 1,
-       [90].u.DivertingLegInformation1.DivertedTo.Type = 2,
-
-       [91].Function = Fac_DivertingLegInformation1,
-       [91].u.DivertingLegInformation1.InvokeID = 94,
-       [91].u.DivertingLegInformation1.DiversionReason = 4,
-       [91].u.DivertingLegInformation1.SubscriptionOption = 1,
-
-       [92].Function = Fac_DivertingLegInformation2,
-       [92].u.DivertingLegInformation2.InvokeID = 95,
-       [92].u.DivertingLegInformation2.DiversionCounter = 3,
-       [92].u.DivertingLegInformation2.DiversionReason = 2,
-       [92].u.DivertingLegInformation2.DivertingPresent = 1,
-       [92].u.DivertingLegInformation2.Diverting.Type = 2,
-       [92].u.DivertingLegInformation2.OriginalCalledPresent = 1,
-       [92].u.DivertingLegInformation2.OriginalCalled.Type = 1,
-
-       [93].Function = Fac_DivertingLegInformation2,
-       [93].u.DivertingLegInformation2.InvokeID = 96,
-       [93].u.DivertingLegInformation2.DiversionCounter = 3,
-       [93].u.DivertingLegInformation2.DiversionReason = 2,
-       [93].u.DivertingLegInformation2.OriginalCalledPresent = 1,
-       [93].u.DivertingLegInformation2.OriginalCalled.Type = 1,
-
-       [94].Function = Fac_DivertingLegInformation2,
-       [94].u.DivertingLegInformation2.InvokeID = 97,
-       [94].u.DivertingLegInformation2.DiversionCounter = 1,
-       [94].u.DivertingLegInformation2.DiversionReason = 2,
-
-       [95].Function = Fac_DivertingLegInformation3,
-       [95].u.DivertingLegInformation3.InvokeID = 98,
-       [95].u.DivertingLegInformation3.PresentationAllowedIndicator = 1,
-/* *INDENT-ON* */
-};
-#endif /* defined(AST_MISDN_ENHANCEMENTS) && defined(CCBS_TEST_MESSAGES) */
-
-static char *handle_cli_misdn_send_facility(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
-{
-       const char *channame;
-       const char *nr;
-       struct chan_list *tmp;
-       int port;
-       const char *served_nr;
-       struct misdn_bchannel dummy, *bc=&dummy;
-       unsigned max_len;
-
-       switch (cmd) {
-       case CLI_INIT:
-               e->command = "misdn send facility";
-               e->usage = "Usage: misdn send facility <type> <channel|port> \"<args>\" \n"
-               "\t type is one of:\n"
-               "\t - calldeflect\n"
-#if defined(AST_MISDN_ENHANCEMENTS)
-               "\t - callrerouting\n"
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-               "\t - CFActivate\n"
-               "\t - CFDeactivate\n";
-
-               return NULL;
-       case CLI_GENERATE:
-               return complete_ch(a);
-       }
-
-       if (a->argc < 5) {
-               return CLI_SHOWUSAGE;
-       }
-
-       if (strstr(a->argv[3], "calldeflect")) {
-               if (a->argc < 6) {
-                       ast_verbose("calldeflect requires 1 arg: ToNumber\n\n");
-                       return 0;
-               }
-               channame = a->argv[4];
-               nr = a->argv[5];
-
-               ast_verbose("Sending Calldeflection (%s) to %s\n", nr, channame);
-               tmp = get_chan_by_ast_name(channame);
-               if (!tmp) {
-                       ast_verbose("Sending CD with nr %s to %s failed: Channel does not exist.\n", nr, channame);
-                       return 0;
-               }
-               ao2_lock(tmp);
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-               max_len = sizeof(tmp->bc->fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.Number) - 1;
-               if (max_len < strlen(nr)) {
-                       ast_verbose("Sending CD with nr %s to %s failed: Number too long (up to %u digits are allowed).\n",
-                               nr, channame, max_len);
-                       ao2_unlock(tmp);
-                       chan_list_unref(tmp, "Number too long");
-                       return 0;
-               }
-               tmp->bc->fac_out.Function = Fac_CallDeflection;
-               tmp->bc->fac_out.u.CallDeflection.InvokeID = ++misdn_invoke_id;
-               tmp->bc->fac_out.u.CallDeflection.ComponentType = FacComponent_Invoke;
-               tmp->bc->fac_out.u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUserPresent = 1;
-               tmp->bc->fac_out.u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUser = 0;
-               tmp->bc->fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.Type = 0;/* unknown */
-               tmp->bc->fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.LengthOfNumber = strlen(nr);
-               strcpy((char *) tmp->bc->fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.Number, nr);
-               tmp->bc->fac_out.u.CallDeflection.Component.Invoke.Deflection.Subaddress.Length = 0;
-
-#else  /* !defined(AST_MISDN_ENHANCEMENTS) */
-
-               max_len = sizeof(tmp->bc->fac_out.u.CDeflection.DeflectedToNumber) - 1;
-               if (max_len < strlen(nr)) {
-                       ast_verbose("Sending CD with nr %s to %s failed: Number too long (up to %u digits are allowed).\n",
-                               nr, channame, max_len);
-                       ao2_unlock(tmp);
-                       chan_list_unref(tmp, "Number too long");
-                       return 0;
-               }
-               tmp->bc->fac_out.Function = Fac_CD;
-               tmp->bc->fac_out.u.CDeflection.PresentationAllowed = 0;
-               //tmp->bc->fac_out.u.CDeflection.DeflectedToSubaddress[0] = 0;
-               strcpy((char *) tmp->bc->fac_out.u.CDeflection.DeflectedToNumber, nr);
-#endif /* !defined(AST_MISDN_ENHANCEMENTS) */
-
-               /* Send message */
-               print_facility(&tmp->bc->fac_out, tmp->bc);
-               ao2_unlock(tmp);
-               misdn_lib_send_event(tmp->bc, EVENT_FACILITY);
-               chan_list_unref(tmp, "Send facility complete");
-#if defined(AST_MISDN_ENHANCEMENTS)
-       } else if (strstr(a->argv[3], "callrerouteing") || strstr(a->argv[3], "callrerouting")) {
-               if (a->argc < 6) {
-                       ast_verbose("callrerouting requires 1 arg: ToNumber\n\n");
-                       return 0;
-               }
-               channame = a->argv[4];
-               nr = a->argv[5];
-
-               ast_verbose("Sending Callrerouting (%s) to %s\n", nr, channame);
-               tmp = get_chan_by_ast_name(channame);
-               if (!tmp) {
-                       ast_verbose("Sending Call Rerouting with nr %s to %s failed: Channel does not exist.\n", nr, channame);
-                       return 0;
-               }
-               ao2_lock(tmp);
-
-               max_len = sizeof(tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.Number) - 1;
-               if (max_len < strlen(nr)) {
-                       ast_verbose("Sending Call Rerouting with nr %s to %s failed: Number too long (up to %u digits are allowed).\n",
-                               nr, channame, max_len);
-                       ao2_unlock(tmp);
-                       chan_list_unref(tmp, "Number too long");
-                       return 0;
-               }
-               tmp->bc->fac_out.Function = Fac_CallRerouteing;
-               tmp->bc->fac_out.u.CallRerouteing.InvokeID = ++misdn_invoke_id;
-               tmp->bc->fac_out.u.CallRerouteing.ComponentType = FacComponent_Invoke;
-
-               tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.ReroutingReason = 0;/* unknown */
-               tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.ReroutingCounter = 1;
-
-               tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.Type = 0;/* unknown */
-               tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.LengthOfNumber = strlen(nr);
-               strcpy((char *) tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.Number, nr);
-               tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Subaddress.Length = 0;
-
-               tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.CallingPartySubaddress.Length = 0;
-
-               /* 0x90 0x90 0xa3 3.1 kHz audio, circuit mode, 64kbit/sec, level1/a-Law */
-               tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Length = 3;
-               tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Contents[0] = 0x90;
-               tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Contents[1] = 0x90;
-               tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Contents[2] = 0xa3;
-               tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Hlc.Length = 0;
-               tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Llc.Length = 0;
-               tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.UserInfo.Length = 0;
-
-               tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.LastRerouting.Type = 1;/* presentationRestricted */
-               tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.SubscriptionOption = 0;/* no notification to caller */
-
-               /* Send message */
-               print_facility(&tmp->bc->fac_out, tmp->bc);
-               ao2_unlock(tmp);
-               misdn_lib_send_event(tmp->bc, EVENT_FACILITY);
-               chan_list_unref(tmp, "Send facility complete");
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-       } else if (strstr(a->argv[3], "CFActivate")) {
-               if (a->argc < 7) {
-                       ast_verbose("CFActivate requires 2 args: 1.FromNumber, 2.ToNumber\n\n");
-                       return 0;
-               }
-               port = atoi(a->argv[4]);
-               served_nr = a->argv[5];
-               nr = a->argv[6];
-
-               misdn_make_dummy(bc, port, 0, misdn_lib_port_is_nt(port), 0);
-
-               ast_verbose("Sending CFActivate  Port:(%d) FromNr. (%s) to Nr. (%s)\n", port, served_nr, nr);
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-               bc->fac_out.Function = Fac_ActivationDiversion;
-               bc->fac_out.u.ActivationDiversion.InvokeID = ++misdn_invoke_id;
-               bc->fac_out.u.ActivationDiversion.ComponentType = FacComponent_Invoke;
-               bc->fac_out.u.ActivationDiversion.Component.Invoke.BasicService = 0;/* allServices */
-               bc->fac_out.u.ActivationDiversion.Component.Invoke.Procedure = 0;/* cfu (Call Forward Unconditional) */
-               ast_copy_string((char *) bc->fac_out.u.ActivationDiversion.Component.Invoke.ServedUser.Number,
-                       served_nr, sizeof(bc->fac_out.u.ActivationDiversion.Component.Invoke.ServedUser.Number));
-               bc->fac_out.u.ActivationDiversion.Component.Invoke.ServedUser.LengthOfNumber =
-                       strlen((char *) bc->fac_out.u.ActivationDiversion.Component.Invoke.ServedUser.Number);
-               bc->fac_out.u.ActivationDiversion.Component.Invoke.ServedUser.Type = 0;/* unknown */
-               ast_copy_string((char *) bc->fac_out.u.ActivationDiversion.Component.Invoke.ForwardedTo.Party.Number,
-                       nr, sizeof(bc->fac_out.u.ActivationDiversion.Component.Invoke.ForwardedTo.Party.Number));
-               bc->fac_out.u.ActivationDiversion.Component.Invoke.ForwardedTo.Party.LengthOfNumber =
-                       strlen((char *) bc->fac_out.u.ActivationDiversion.Component.Invoke.ForwardedTo.Party.Number);
-               bc->fac_out.u.ActivationDiversion.Component.Invoke.ForwardedTo.Party.Type = 0;/* unknown */
-               bc->fac_out.u.ActivationDiversion.Component.Invoke.ForwardedTo.Subaddress.Length = 0;
-
-#else  /* !defined(AST_MISDN_ENHANCEMENTS) */
-
-               bc->fac_out.Function = Fac_CFActivate;
-               bc->fac_out.u.CFActivate.BasicService = 0; /* All Services */
-               bc->fac_out.u.CFActivate.Procedure = 0; /* Unconditional */
-               ast_copy_string((char *) bc->fac_out.u.CFActivate.ServedUserNumber, served_nr, sizeof(bc->fac_out.u.CFActivate.ServedUserNumber));
-               ast_copy_string((char *) bc->fac_out.u.CFActivate.ForwardedToNumber, nr, sizeof(bc->fac_out.u.CFActivate.ForwardedToNumber));
-#endif /* !defined(AST_MISDN_ENHANCEMENTS) */
-
-               /* Send message */
-               print_facility(&bc->fac_out, bc);
-               misdn_lib_send_event(bc, EVENT_FACILITY);
-       } else if (strstr(a->argv[3], "CFDeactivate")) {
-               if (a->argc < 6) {
-                       ast_verbose("CFDeactivate requires 1 arg: FromNumber\n\n");
-                       return 0;
-               }
-               port = atoi(a->argv[4]);
-               served_nr = a->argv[5];
-
-               misdn_make_dummy(bc, port, 0, misdn_lib_port_is_nt(port), 0);
-               ast_verbose("Sending CFDeactivate  Port:(%d) FromNr. (%s)\n", port, served_nr);
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-               bc->fac_out.Function = Fac_DeactivationDiversion;
-               bc->fac_out.u.DeactivationDiversion.InvokeID = ++misdn_invoke_id;
-               bc->fac_out.u.DeactivationDiversion.ComponentType = FacComponent_Invoke;
-               bc->fac_out.u.DeactivationDiversion.Component.Invoke.BasicService = 0;/* allServices */
-               bc->fac_out.u.DeactivationDiversion.Component.Invoke.Procedure = 0;/* cfu (Call Forward Unconditional) */
-               ast_copy_string((char *) bc->fac_out.u.DeactivationDiversion.Component.Invoke.ServedUser.Number,
-                       served_nr, sizeof(bc->fac_out.u.DeactivationDiversion.Component.Invoke.ServedUser.Number));
-               bc->fac_out.u.DeactivationDiversion.Component.Invoke.ServedUser.LengthOfNumber =
-                       strlen((char *) bc->fac_out.u.DeactivationDiversion.Component.Invoke.ServedUser.Number);
-               bc->fac_out.u.DeactivationDiversion.Component.Invoke.ServedUser.Type = 0;/* unknown */
-
-#else  /* !defined(AST_MISDN_ENHANCEMENTS) */
-
-               bc->fac_out.Function = Fac_CFDeactivate;
-               bc->fac_out.u.CFDeactivate.BasicService = 0; /* All Services */
-               bc->fac_out.u.CFDeactivate.Procedure = 0; /* Unconditional */
-               ast_copy_string((char *) bc->fac_out.u.CFActivate.ServedUserNumber, served_nr, sizeof(bc->fac_out.u.CFActivate.ServedUserNumber));
-#endif /* !defined(AST_MISDN_ENHANCEMENTS) */
-
-               /* Send message */
-               print_facility(&bc->fac_out, bc);
-               misdn_lib_send_event(bc, EVENT_FACILITY);
-#if defined(AST_MISDN_ENHANCEMENTS) && defined(CCBS_TEST_MESSAGES)
-       } else if (strstr(a->argv[3], "test")) {
-               int msg_number;
-
-               if (a->argc < 5) {
-                       ast_verbose("test (<port> [<msg#>]) | (<channel-name> <msg#>)\n\n");
-                       return 0;
-               }
-               port = atoi(a->argv[4]);
-
-               channame = a->argv[4];
-               tmp = get_chan_by_ast_name(channame);
-               if (tmp) {
-                       /* We are going to send this FACILITY message out on an existing connection */
-                       msg_number = atoi(a->argv[5]);
-                       if (msg_number < ARRAY_LEN(Fac_Msgs)) {
-                               ao2_lock(tmp);
-                               tmp->bc->fac_out = Fac_Msgs[msg_number];
-
-                               /* Send message */
-                               print_facility(&tmp->bc->fac_out, tmp->bc);
-                               ao2_unlock(tmp);
-                               misdn_lib_send_event(tmp->bc, EVENT_FACILITY);
-                       } else {
-                               ast_verbose("test <channel-name> <msg#>\n\n");
-                       }
-                       chan_list_unref(tmp, "Facility test done");
-               } else if (a->argc < 6) {
-                       for (msg_number = 0; msg_number < ARRAY_LEN(Fac_Msgs); ++msg_number) {
-                               misdn_make_dummy(bc, port, 0, misdn_lib_port_is_nt(port), 0);
-                               bc->fac_out = Fac_Msgs[msg_number];
-
-                               /* Send message */
-                               print_facility(&bc->fac_out, bc);
-                               misdn_lib_send_event(bc, EVENT_FACILITY);
-                               sleep(1);
-                       }
-               } else {
-                       msg_number = atoi(a->argv[5]);
-                       if (msg_number < ARRAY_LEN(Fac_Msgs)) {
-                               misdn_make_dummy(bc, port, 0, misdn_lib_port_is_nt(port), 0);
-                               bc->fac_out = Fac_Msgs[msg_number];
-
-                               /* Send message */
-                               print_facility(&bc->fac_out, bc);
-                               misdn_lib_send_event(bc, EVENT_FACILITY);
-                       } else {
-                               ast_verbose("test <port> [<msg#>]\n\n");
-                       }
-               }
-       } else if (strstr(a->argv[3], "register")) {
-               if (a->argc < 5) {
-                       ast_verbose("register <port>\n\n");
-                       return 0;
-               }
-               port = atoi(a->argv[4]);
-
-               bc = misdn_lib_get_register_bc(port);
-               if (!bc) {
-                       ast_verbose("Could not allocate REGISTER bc struct\n\n");
-                       return 0;
-               }
-               bc->fac_out = Fac_Msgs[45];
-
-               /* Send message */
-               print_facility(&bc->fac_out, bc);
-               misdn_lib_send_event(bc, EVENT_REGISTER);
-#endif /* defined(AST_MISDN_ENHANCEMENTS) && defined(CCBS_TEST_MESSAGES) */
-       }
-
-       return CLI_SUCCESS;
-}
-
-static char *handle_cli_misdn_send_restart(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
-{
-       int port;
-       int channel;
-
-       switch (cmd) {
-       case CLI_INIT:
-               e->command = "misdn send restart";
-               e->usage =
-                       "Usage: misdn send restart [port [channel]]\n"
-                       "       Send a restart for every bchannel on the given port.\n";
-               return NULL;
-       case CLI_GENERATE:
-               return NULL;
-       }
-
-       if (a->argc < 4 || a->argc > 5) {
-               return CLI_SHOWUSAGE;
-       }
-
-       port = atoi(a->argv[3]);
-
-       if (a->argc == 5) {
-               channel = atoi(a->argv[4]);
-               misdn_lib_send_restart(port, channel);
-       } else {
-               misdn_lib_send_restart(port, -1);
-       }
-
-       return CLI_SUCCESS;
-}
-
-static char *handle_cli_misdn_send_digit(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
-{
-       const char *channame;
-       const char *msg;
-       struct chan_list *tmp;
-       int i, msglen;
-
-       switch (cmd) {
-       case CLI_INIT:
-               e->command = "misdn send digit";
-               e->usage =
-                       "Usage: misdn send digit <channel> \"<msg>\" \n"
-                       "       Send <digit> to <channel> as DTMF Tone\n"
-                       "       when channel is a mISDN channel\n";
-               return NULL;
-       case CLI_GENERATE:
-               return complete_ch(a);
-       }
-
-       if (a->argc != 5) {
-               return CLI_SHOWUSAGE;
-       }
-
-       channame = a->argv[3];
-       msg = a->argv[4];
-       msglen = strlen(msg);
-
-       ast_cli(a->fd, "Sending %s to %s\n", msg, channame);
-
-       tmp = get_chan_by_ast_name(channame);
-       if (!tmp) {
-               ast_cli(a->fd, "Sending %s to %s failed Channel does not exist\n", msg, channame);
-               return CLI_SUCCESS;
-       }
-#if 1
-       for (i = 0; i < msglen; i++) {
-               if (!tmp->ast) {
-                       break;
-               }
-               ast_cli(a->fd, "Sending: %c\n", msg[i]);
-               send_digit_to_chan(tmp, msg[i]);
-               /* res = ast_safe_sleep(tmp->ast, 250); */
-               usleep(250000);
-               /* res = ast_waitfor(tmp->ast,100); */
-       }
-#else
-       if (tmp->ast) {
-               ast_dtmf_stream(tmp->ast, NULL, msg, 250);
-       }
-#endif
-       chan_list_unref(tmp, "Digit(s) sent");
-
-       return CLI_SUCCESS;
-}
-
-static char *handle_cli_misdn_toggle_echocancel(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
-{
-       const char *channame;
-       struct chan_list *tmp;
-
-       switch (cmd) {
-       case CLI_INIT:
-               e->command = "misdn toggle echocancel";
-               e->usage =
-                       "Usage: misdn toggle echocancel <channel>\n"
-                       "       Toggle EchoCancel on mISDN Channel.\n";
-               return NULL;
-       case CLI_GENERATE:
-               return complete_ch(a);
-       }
-
-       if (a->argc != 4) {
-               return CLI_SHOWUSAGE;
-       }
-
-       channame = a->argv[3];
-
-       ast_cli(a->fd, "Toggling EchoCancel on %s\n", channame);
-
-       tmp = get_chan_by_ast_name(channame);
-       if (!tmp) {
-               ast_cli(a->fd, "Toggling EchoCancel %s failed Channel does not exist\n", channame);
-               return CLI_SUCCESS;
-       }
-
-       tmp->toggle_ec = tmp->toggle_ec ? 0 : 1;
-
-       if (tmp->toggle_ec) {
-#ifdef MISDN_1_2
-               update_pipeline_config(tmp->bc);
-#else
-               update_ec_config(tmp->bc);
-#endif
-               manager_ec_enable(tmp->bc);
-       } else {
-               manager_ec_disable(tmp->bc);
-       }
-       chan_list_unref(tmp, "Done toggling echo cancel");
-
-       return CLI_SUCCESS;
-}
-
-static char *handle_cli_misdn_send_display(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
-{
-       const char *channame;
-       const char *msg;
-       struct chan_list *tmp;
-
-       switch (cmd) {
-       case CLI_INIT:
-               e->command = "misdn send display";
-               e->usage =
-                       "Usage: misdn send display <channel> \"<msg>\" \n"
-                       "       Send <msg> to <channel> as Display Message\n"
-                       "       when channel is a mISDN channel\n";
-               return NULL;
-       case CLI_GENERATE:
-               return complete_ch(a);
-       }
-
-       if (a->argc != 5) {
-               return CLI_SHOWUSAGE;
-       }
-
-       channame = a->argv[3];
-       msg = a->argv[4];
-
-       ast_cli(a->fd, "Sending %s to %s\n", msg, channame);
-
-       tmp = get_chan_by_ast_name(channame);
-       if (tmp && tmp->bc) {
-               ast_copy_string(tmp->bc->display, msg, sizeof(tmp->bc->display));
-               misdn_lib_send_event(tmp->bc, EVENT_INFORMATION);
-               chan_list_unref(tmp, "Done sending display");
-       } else {
-               if (tmp) {
-                       chan_list_unref(tmp, "Display failed");
-               }
-               ast_cli(a->fd, "No such channel %s\n", channame);
-               return CLI_SUCCESS;
-       }
-
-       return CLI_SUCCESS;
-}
-
-static char *complete_ch(struct ast_cli_args *a)
-{
-       return ast_complete_channels(a->line, a->word, a->pos, a->n, 3);
-}
-
-static char *complete_debug_port(struct ast_cli_args *a)
-{
-       if (a->n) {
-               return NULL;
-       }
-
-       switch (a->pos) {
-       case 4:
-               if (a->word[0] == 'p') {
-                       return ast_strdup("port");
-               } else if (a->word[0] == 'o') {
-                       return ast_strdup("only");
-               }
-               break;
-       case 6:
-               if (a->word[0] == 'o') {
-                       return ast_strdup("only");
-               }
-               break;
-       }
-       return NULL;
-}
-
-static char *complete_show_config(struct ast_cli_args *a)
-{
-       char buffer[BUFFERSIZE];
-       enum misdn_cfg_elements elem;
-       int wordlen = strlen(a->word);
-       int which = 0;
-       int port = 0;
-
-       switch (a->pos) {
-       case 3:
-               if ((!strncmp(a->word, "description", wordlen)) && (++which > a->n)) {
-                       return ast_strdup("description");
-               }
-               if ((!strncmp(a->word, "descriptions", wordlen)) && (++which > a->n)) {
-                       return ast_strdup("descriptions");
-               }
-               if ((!strncmp(a->word, "0", wordlen)) && (++which > a->n)) {
-                       return ast_strdup("0");
-               }
-               while ((port = misdn_cfg_get_next_port(port)) != -1) {
-                       snprintf(buffer, sizeof(buffer), "%d", port);
-                       if ((!strncmp(a->word, buffer, wordlen)) && (++which > a->n)) {
-                               return ast_strdup(buffer);
-                       }
-               }
-               break;
-       case 4:
-               if (strstr(a->line, "description ")) {
-                       for (elem = MISDN_CFG_FIRST + 1; elem < MISDN_GEN_LAST; ++elem) {
-                               if ((elem == MISDN_CFG_LAST) || (elem == MISDN_GEN_FIRST)) {
-                                       continue;
-                               }
-                               misdn_cfg_get_name(elem, buffer, sizeof(buffer));
-                               if (!wordlen || !strncmp(a->word, buffer, wordlen)) {
-                                       if (++which > a->n) {
-                                               return ast_strdup(buffer);
-                                       }
-                               }
-                       }
-               } else if (strstr(a->line, "descriptions ")) {
-                       if ((!wordlen || !strncmp(a->word, "general", wordlen)) && (++which > a->n)) {
-                               return ast_strdup("general");
-                       }
-                       if ((!wordlen || !strncmp(a->word, "ports", wordlen)) && (++which > a->n)) {
-                               return ast_strdup("ports");
-                       }
-               }
-               break;
-       }
-       return NULL;
-}
-
-static struct ast_cli_entry chan_misdn_clis[] = {
-/* *INDENT-OFF* */
-       AST_CLI_DEFINE(handle_cli_misdn_port_block,        "Block the given port"),
-       AST_CLI_DEFINE(handle_cli_misdn_port_down,         "Try to deactivate the L1 on the given port"),
-       AST_CLI_DEFINE(handle_cli_misdn_port_unblock,      "Unblock the given port"),
-       AST_CLI_DEFINE(handle_cli_misdn_port_up,           "Try to establish L1 on the given port"),
-       AST_CLI_DEFINE(handle_cli_misdn_reload,            "Reload internal mISDN config, read from the config file"),
-       AST_CLI_DEFINE(handle_cli_misdn_restart_pid,       "Restart the given pid"),
-       AST_CLI_DEFINE(handle_cli_misdn_restart_port,      "Restart the given port"),
-       AST_CLI_DEFINE(handle_cli_misdn_show_channel,      "Show an internal mISDN channel"),
-       AST_CLI_DEFINE(handle_cli_misdn_show_channels,     "Show the internal mISDN channel list"),
-       AST_CLI_DEFINE(handle_cli_misdn_show_config,       "Show internal mISDN config, read from the config file"),
-       AST_CLI_DEFINE(handle_cli_misdn_show_port,         "Show detailed information for given port"),
-       AST_CLI_DEFINE(handle_cli_misdn_show_ports_stats,  "Show mISDNs channel's call statistics per port"),
-       AST_CLI_DEFINE(handle_cli_misdn_show_stacks,       "Show internal mISDN stack_list"),
-       AST_CLI_DEFINE(handle_cli_misdn_send_facility,     "Sends a Facility Message to the mISDN Channel"),
-       AST_CLI_DEFINE(handle_cli_misdn_send_digit,        "Send DTMF digit to mISDN Channel"),
-       AST_CLI_DEFINE(handle_cli_misdn_send_display,      "Send Text to mISDN Channel"),
-       AST_CLI_DEFINE(handle_cli_misdn_send_restart,      "Send a restart for every bchannel on the given port"),
-       AST_CLI_DEFINE(handle_cli_misdn_set_crypt_debug,   "Set CryptDebuglevel of chan_misdn, at the moment, level={1,2}"),
-       AST_CLI_DEFINE(handle_cli_misdn_set_debug,         "Set Debuglevel of chan_misdn"),
-       AST_CLI_DEFINE(handle_cli_misdn_set_tics,          "???"),
-       AST_CLI_DEFINE(handle_cli_misdn_toggle_echocancel, "Toggle EchoCancel on mISDN Channel"),
-/* *INDENT-ON* */
-};
-
-/*! \brief Updates caller ID information from config */
-static void update_config(struct chan_list *ch)
-{
-       struct ast_channel *ast;
-       struct misdn_bchannel *bc;
-       int port;
-       int hdlc = 0;
-       int pres;
-       int screen;
-
-       if (!ch) {
-               ast_log(LOG_WARNING, "Cannot configure without chanlist\n");
-               return;
-       }
-
-       ast = ch->ast;
-       bc = ch->bc;
-       if (! ast || ! bc) {
-               ast_log(LOG_WARNING, "Cannot configure without ast || bc\n");
-               return;
-       }
-
-       port = bc->port;
-
-       chan_misdn_log(7, port, "update_config: Getting Config\n");
-
-       misdn_cfg_get(port, MISDN_CFG_HDLC, &hdlc, sizeof(int));
-       if (hdlc) {
-               switch (bc->capability) {
-               case INFO_CAPABILITY_DIGITAL_UNRESTRICTED:
-               case INFO_CAPABILITY_DIGITAL_RESTRICTED:
-                       chan_misdn_log(1, bc->port, " --> CONF HDLC\n");
-                       bc->hdlc = 1;
-                       break;
-               }
-       }
-
-
-       misdn_cfg_get(port, MISDN_CFG_PRES, &pres, sizeof(pres));
-       misdn_cfg_get(port, MISDN_CFG_SCREEN, &screen, sizeof(screen));
-       chan_misdn_log(2, port, " --> pres: %d screen: %d\n", pres, screen);
-
-       if (pres < 0 || screen < 0) {
-               chan_misdn_log(2, port, " --> pres: %x\n", ast_channel_connected(ast)->id.number.presentation);
-
-               bc->caller.presentation = ast_to_misdn_pres(ast_channel_connected(ast)->id.number.presentation);
-               chan_misdn_log(2, port, " --> PRES: %s(%d)\n", misdn_to_str_pres(bc->caller.presentation), bc->caller.presentation);
-
-               bc->caller.screening = ast_to_misdn_screen(ast_channel_connected(ast)->id.number.presentation);
-               chan_misdn_log(2, port, " --> SCREEN: %s(%d)\n", misdn_to_str_screen(bc->caller.screening), bc->caller.screening);
-       } else {
-               bc->caller.screening = screen;
-               bc->caller.presentation = pres;
-       }
-}
-
-
-static void config_jitterbuffer(struct chan_list *ch)
-{
-       struct misdn_bchannel *bc = ch->bc;
-       int len = ch->jb_len;
-       int threshold = ch->jb_upper_threshold;
-
-       chan_misdn_log(5, bc->port, "config_jb: Called\n");
-
-       if (!len) {
-               chan_misdn_log(1, bc->port, "config_jb: Deactivating Jitterbuffer\n");
-               bc->nojitter = 1;
-       } else {
-               if (len <= 100 || len > 8000) {
-                       chan_misdn_log(0, bc->port, "config_jb: Jitterbuffer out of Bounds, setting to 1000\n");
-                       len = 1000;
-               }
-
-               if (threshold > len) {
-                       chan_misdn_log(0, bc->port, "config_jb: Jitterbuffer Threshold > Jitterbuffer setting to Jitterbuffer -1\n");
-               }
-
-               if (ch->jb) {
-                       cb_log(0, bc->port, "config_jb: We've got a Jitterbuffer Already on this port.\n");
-                       misdn_jb_destroy(ch->jb);
-                       ch->jb = NULL;
-               }
-
-               ch->jb = misdn_jb_init(len, threshold);
-
-               if (!ch->jb) {
-                       bc->nojitter = 1;
-               }
-       }
-}
-
-
-void debug_numtype(int port, int numtype, char *type)
-{
-       switch (numtype) {
-       case NUMTYPE_UNKNOWN:
-               chan_misdn_log(2, port, " --> %s: Unknown\n", type);
-               break;
-       case NUMTYPE_INTERNATIONAL:
-               chan_misdn_log(2, port, " --> %s: International\n", type);
-               break;
-       case NUMTYPE_NATIONAL:
-               chan_misdn_log(2, port, " --> %s: National\n", type);
-               break;
-       case NUMTYPE_NETWORK_SPECIFIC:
-               chan_misdn_log(2, port, " --> %s: Network Specific\n", type);
-               break;
-       case NUMTYPE_SUBSCRIBER:
-               chan_misdn_log(2, port, " --> %s: Subscriber\n", type);
-               break;
-       case NUMTYPE_ABBREVIATED:
-               chan_misdn_log(2, port, " --> %s: Abbreviated\n", type);
-               break;
-               /* Maybe we should cut off the prefix if present ? */
-       default:
-               chan_misdn_log(0, port, " --> !!!! Wrong dialplan setting, please see the misdn.conf sample file\n ");
-               break;
-       }
-}
-
-
-#ifdef MISDN_1_2
-static int update_pipeline_config(struct misdn_bchannel *bc)
-{
-       int ec;
-
-       misdn_cfg_get(bc->port, MISDN_CFG_PIPELINE, bc->pipeline, sizeof(bc->pipeline));
-
-       if (*bc->pipeline) {
-               return 0;
-       }
-
-       misdn_cfg_get(bc->port, MISDN_CFG_ECHOCANCEL, &ec, sizeof(ec));
-       if (ec == 1) {
-               ast_copy_string(bc->pipeline, "mg2ec", sizeof(bc->pipeline));
-       } else if (ec > 1) {
-               snprintf(bc->pipeline, sizeof(bc->pipeline), "mg2ec(deftaps=%d)", ec);
-       }
-
-       return 0;
-}
-#else
-static int update_ec_config(struct misdn_bchannel *bc)
-{
-       int ec;
-       int port = bc->port;
-
-       misdn_cfg_get(port, MISDN_CFG_ECHOCANCEL, &ec, sizeof(ec));
-
-       if (ec == 1) {
-               bc->ec_enable = 1;
-       } else if (ec > 1) {
-               bc->ec_enable = 1;
-               bc->ec_deftaps = ec;
-       }
-
-       return 0;
-}
-#endif
-
-
-static int read_config(struct chan_list *ch)
-{
-       struct ast_channel *ast;
-       struct misdn_bchannel *bc;
-       int port;
-       int hdlc = 0;
-       char lang[BUFFERSIZE + 1];
-       char faxdetect[BUFFERSIZE + 1];
-       char buf[256];
-       char buf2[256];
-       ast_group_t pg;
-       ast_group_t cg;
-       struct ast_namedgroups *npg;
-       struct ast_namedgroups *ncg;
-       struct ast_str *tmp_str;
-
-       if (!ch) {
-               ast_log(LOG_WARNING, "Cannot configure without chanlist\n");
-               return -1;
-       }
-
-       ast = ch->ast;
-       bc = ch->bc;
-       if (! ast || ! bc) {
-               ast_log(LOG_WARNING, "Cannot configure without ast || bc\n");
-               return -1;
-       }
-
-       port = bc->port;
-       chan_misdn_log(1, port, "read_config: Getting Config\n");
-
-       misdn_cfg_get(port, MISDN_CFG_LANGUAGE, lang, sizeof(lang));
-       ast_channel_lock(ast);
-       ast_channel_language_set(ast, lang);
-       ast_channel_unlock(ast);
-
-       misdn_cfg_get(port, MISDN_CFG_MUSICCLASS, ch->mohinterpret, sizeof(ch->mohinterpret));
-
-       misdn_cfg_get(port, MISDN_CFG_TXGAIN, &bc->txgain, sizeof(bc->txgain));
-       misdn_cfg_get(port, MISDN_CFG_RXGAIN, &bc->rxgain, sizeof(bc->rxgain));
-
-       misdn_cfg_get(port, MISDN_CFG_INCOMING_EARLY_AUDIO, &ch->incoming_early_audio, sizeof(ch->incoming_early_audio));
-
-       misdn_cfg_get(port, MISDN_CFG_SENDDTMF, &bc->send_dtmf, sizeof(bc->send_dtmf));
-
-       misdn_cfg_get(port, MISDN_CFG_ASTDTMF, &ch->ast_dsp, sizeof(int));
-       if (ch->ast_dsp) {
-               ch->ignore_dtmf = 1;
-       }
-
-       misdn_cfg_get(port, MISDN_CFG_NEED_MORE_INFOS, &bc->need_more_infos, sizeof(bc->need_more_infos));
-       misdn_cfg_get(port, MISDN_CFG_NTTIMEOUT, &ch->nttimeout, sizeof(ch->nttimeout));
-
-       misdn_cfg_get(port, MISDN_CFG_NOAUTORESPOND_ON_SETUP, &ch->noautorespond_on_setup, sizeof(ch->noautorespond_on_setup));
-
-       misdn_cfg_get(port, MISDN_CFG_FAR_ALERTING, &ch->far_alerting, sizeof(ch->far_alerting));
-
-       misdn_cfg_get(port, MISDN_CFG_ALLOWED_BEARERS, &ch->allowed_bearers, sizeof(ch->allowed_bearers));
-
-       misdn_cfg_get(port, MISDN_CFG_FAXDETECT, faxdetect, sizeof(faxdetect));
-
-       misdn_cfg_get(port, MISDN_CFG_HDLC, &hdlc, sizeof(hdlc));
-       if (hdlc) {
-               switch (bc->capability) {
-               case INFO_CAPABILITY_DIGITAL_UNRESTRICTED:
-               case INFO_CAPABILITY_DIGITAL_RESTRICTED:
-                       chan_misdn_log(1, bc->port, " --> CONF HDLC\n");
-                       bc->hdlc = 1;
-                       break;
-               }
-
-       }
-       /*Initialize new Jitterbuffer*/
-       misdn_cfg_get(port, MISDN_CFG_JITTERBUFFER, &ch->jb_len, sizeof(ch->jb_len));
-       misdn_cfg_get(port, MISDN_CFG_JITTERBUFFER_UPPER_THRESHOLD, &ch->jb_upper_threshold, sizeof(ch->jb_upper_threshold));
-
-       config_jitterbuffer(ch);
-
-       misdn_cfg_get(bc->port, MISDN_CFG_CONTEXT, ch->context, sizeof(ch->context));
-
-       ast_channel_lock(ast);
-       ast_channel_context_set(ast, ch->context);
-       ast_channel_unlock(ast);
-
-#ifdef MISDN_1_2
-       update_pipeline_config(bc);
-#else
-       update_ec_config(bc);
-#endif
-
-       misdn_cfg_get(bc->port, MISDN_CFG_EARLY_BCONNECT, &bc->early_bconnect, sizeof(bc->early_bconnect));
-
-       misdn_cfg_get(port, MISDN_CFG_DISPLAY_CONNECTED, &bc->display_connected, sizeof(bc->display_connected));
-       misdn_cfg_get(port, MISDN_CFG_DISPLAY_SETUP, &bc->display_setup, sizeof(bc->display_setup));
-       misdn_cfg_get(port, MISDN_CFG_OUTGOING_COLP, &bc->outgoing_colp, sizeof(bc->outgoing_colp));
-
-       misdn_cfg_get(port, MISDN_CFG_PICKUPGROUP, &pg, sizeof(pg));
-       misdn_cfg_get(port, MISDN_CFG_CALLGROUP, &cg, sizeof(cg));
-       chan_misdn_log(5, port, " --> * CallGrp:%s PickupGrp:%s\n", ast_print_group(buf, sizeof(buf), cg), ast_print_group(buf2, sizeof(buf2), pg));
-       ast_channel_lock(ast);
-       ast_channel_pickupgroup_set(ast, pg);
-       ast_channel_callgroup_set(ast, cg);
-       ast_channel_unlock(ast);
-
-       misdn_cfg_get(port, MISDN_CFG_NAMEDPICKUPGROUP, &npg, sizeof(npg));
-       misdn_cfg_get(port, MISDN_CFG_NAMEDCALLGROUP, &ncg, sizeof(ncg));
-
-       tmp_str = ast_str_create(1024);
-       if (tmp_str) {
-               chan_misdn_log(5, port, " --> * NamedCallGrp:%s\n", ast_print_namedgroups(&tmp_str, ncg));
-               ast_str_reset(tmp_str);
-               chan_misdn_log(5, port, " --> * NamedPickupGrp:%s\n", ast_print_namedgroups(&tmp_str, npg));
-               ast_free(tmp_str);
-       }
-
-       ast_channel_lock(ast);
-       ast_channel_named_pickupgroups_set(ast, npg);
-       ast_channel_named_callgroups_set(ast, ncg);
-       ast_channel_unlock(ast);
-
-       if (ch->originator == ORG_AST) {
-               char callerid[BUFFERSIZE + 1];
-
-               /* ORIGINATOR Asterisk (outgoing call) */
-
-               misdn_cfg_get(port, MISDN_CFG_TE_CHOOSE_CHANNEL, &(bc->te_choose_channel), sizeof(bc->te_choose_channel));
-
-               if (strstr(faxdetect, "outgoing") || strstr(faxdetect, "both")) {
-                       ch->faxdetect = strstr(faxdetect, "nojump") ? 2 : 1;
-               }
-
-               misdn_cfg_get(port, MISDN_CFG_CALLERID, callerid, sizeof(callerid));
-               if (!ast_strlen_zero(callerid)) {
-                       char *cid_name = NULL;
-                       char *cid_num = NULL;
-
-                       ast_callerid_parse(callerid, &cid_name, &cid_num);
-                       if (cid_name) {
-                               ast_copy_string(bc->caller.name, cid_name, sizeof(bc->caller.name));
-                       } else {
-                               bc->caller.name[0] = '\0';
-                       }
-                       if (cid_num) {
-                               ast_copy_string(bc->caller.number, cid_num, sizeof(bc->caller.number));
-                       } else {
-                               bc->caller.number[0] = '\0';
-                       }
-                       chan_misdn_log(1, port, " --> * Setting caller to \"%s\" <%s>\n", bc->caller.name, bc->caller.number);
-               }
-
-               misdn_cfg_get(port, MISDN_CFG_DIALPLAN, &bc->dialed.number_type, sizeof(bc->dialed.number_type));
-               bc->dialed.number_plan = NUMPLAN_ISDN;
-               debug_numtype(port, bc->dialed.number_type, "TON");
-
-               ch->overlap_dial = 0;
-       } else {
-               /* ORIGINATOR MISDN (incoming call) */
-
-               if (strstr(faxdetect, "incoming") || strstr(faxdetect, "both")) {
-                       ch->faxdetect = (strstr(faxdetect, "nojump")) ? 2 : 1;
-               }
-
-               /* Add configured prefix to caller.number */
-               misdn_add_number_prefix(bc->port, bc->caller.number_type, bc->caller.number, sizeof(bc->caller.number));
-
-               if (ast_strlen_zero(bc->dialed.number) && !ast_strlen_zero(bc->keypad)) {
-                       ast_copy_string(bc->dialed.number, bc->keypad, sizeof(bc->dialed.number));
-               }
-
-               /* Add configured prefix to dialed.number */
-               misdn_add_number_prefix(bc->port, bc->dialed.number_type, bc->dialed.number, sizeof(bc->dialed.number));
-
-               ast_channel_lock(ast);
-               ast_channel_exten_set(ast, bc->dialed.number);
-               ast_channel_unlock(ast);
-
-               misdn_cfg_get(bc->port, MISDN_CFG_OVERLAP_DIAL, &ch->overlap_dial, sizeof(ch->overlap_dial));
-               ast_mutex_init(&ch->overlap_tv_lock);
-       } /* ORIG MISDN END */
-
-       misdn_cfg_get(port, MISDN_CFG_INCOMING_CALLERID_TAG, bc->incoming_cid_tag, sizeof(bc->incoming_cid_tag));
-       if (!ast_strlen_zero(bc->incoming_cid_tag)) {
-               chan_misdn_log(1, port, " --> * Setting incoming caller id tag to \"%s\"\n", bc->incoming_cid_tag);
-       }
-       ch->overlap_dial_task = -1;
-
-       if (ch->faxdetect  || ch->ast_dsp) {
-               misdn_cfg_get(port, MISDN_CFG_FAXDETECT_TIMEOUT, &ch->faxdetect_timeout, sizeof(ch->faxdetect_timeout));
-               if (!ch->dsp) {
-                       ch->dsp = ast_dsp_new();
-               }
-               if (ch->dsp) {
-                       ast_dsp_set_features(ch->dsp, DSP_FEATURE_DIGIT_DETECT | (ch->faxdetect ? DSP_FEATURE_FAX_DETECT : 0));
-               }
-       }
-
-       /* AOCD initialization */
-       bc->AOCDtype = Fac_None;
-
-       return 0;
-}
-
-/*!
- * \internal
- * \brief Send a connected line update to the other channel
- *
- * \param ast Current Asterisk channel
- * \param id Party id information to send to the other side
- * \param source Why are we sending this update
- * \param cid_tag User tag to apply to the party id.
- *
- * \return Nothing
- */
-static void misdn_queue_connected_line_update(struct ast_channel *ast, const struct misdn_party_id *id, enum AST_CONNECTED_LINE_UPDATE_SOURCE source, char *cid_tag)
-{
-       struct ast_party_connected_line connected;
-       struct ast_set_party_connected_line update_connected;
-
-       ast_party_connected_line_init(&connected);
-       memset(&update_connected, 0, sizeof(update_connected));
-       update_connected.id.number = 1;
-       connected.id.number.valid = 1;
-       connected.id.number.str = (char *) id->number;
-       connected.id.number.plan = misdn_to_ast_ton(id->number_type)
-               | misdn_to_ast_plan(id->number_plan);
-       connected.id.number.presentation = misdn_to_ast_pres(id->presentation)
-               | misdn_to_ast_screen(id->screening);
-
-       /*
-        * Make sure that any earlier private connected id
-        * representation at the remote end is invalidated
-        */
-       ast_set_party_id_all(&update_connected.priv);
-
-       connected.id.tag = cid_tag;
-       connected.source = source;
-       ast_channel_queue_connected_line_update(ast, &connected, &update_connected);
-}
-
-/*!
- * \internal
- * \brief Update the caller id party on this channel.
- *
- * \param ast Current Asterisk channel
- * \param id Remote party id information to update.
- * \param cid_tag User tag to apply to the party id.
- *
- * \return Nothing
- */
-static void misdn_update_caller_id(struct ast_channel *ast, const struct misdn_party_id *id, char *cid_tag)
-{
-       struct ast_party_caller caller;
-       struct ast_set_party_caller update_caller;
-
-       memset(&update_caller, 0, sizeof(update_caller));
-       update_caller.id.number = 1;
-       update_caller.ani.number = 1;
-
-       ast_channel_lock(ast);
-       ast_party_caller_set_init(&caller, ast_channel_caller(ast));
-
-       caller.id.number.valid = 1;
-       caller.id.number.str = (char *) id->number;
-       caller.id.number.plan = misdn_to_ast_ton(id->number_type)
-               | misdn_to_ast_plan(id->number_plan);
-       caller.id.number.presentation = misdn_to_ast_pres(id->presentation)
-               | misdn_to_ast_screen(id->screening);
-
-       caller.ani.number = caller.id.number;
-
-       caller.id.tag = cid_tag;
-       caller.ani.tag = cid_tag;
-
-       ast_channel_set_caller_event(ast, &caller, &update_caller);
-       ast_channel_unlock(ast);
-}
-
-/*!
- * \internal
- * \brief Update the remote party id information.
- *
- * \param ast Current Asterisk channel
- * \param id Remote party id information to update.
- * \param source Why are we sending this update
- * \param cid_tag User tag to apply to the party id.
- *
- * \return Nothing
- */
-static void misdn_update_remote_party(struct ast_channel *ast, const struct misdn_party_id *id, enum AST_CONNECTED_LINE_UPDATE_SOURCE source, char *cid_tag)
-{
-       misdn_update_caller_id(ast, id, cid_tag);
-       misdn_queue_connected_line_update(ast, id, source, cid_tag);
-}
-
-/*!
- * \internal
- * \brief Get the connected line information out of the Asterisk channel.
- *
- * \param ast Current Asterisk channel
- * \param bc Associated B channel
- * \param originator Who originally created this channel. ORG_AST or ORG_MISDN
- *
- * \return Nothing
- */
-static void misdn_get_connected_line(struct ast_channel *ast, struct misdn_bchannel *bc, int originator)
-{
-       int number_type;
-       struct ast_party_id connected_id = ast_channel_connected_effective_id(ast);
-
-       if (originator == ORG_MISDN) {
-               /* ORIGINATOR MISDN (incoming call) */
-
-               ast_copy_string(bc->connected.name,
-                       S_COR(connected_id.name.valid, connected_id.name.str, ""),
-                       sizeof(bc->connected.name));
-               if (connected_id.number.valid) {
-                       ast_copy_string(bc->connected.number, S_OR(connected_id.number.str, ""),
-                               sizeof(bc->connected.number));
-                       bc->connected.presentation = ast_to_misdn_pres(connected_id.number.presentation);
-                       bc->connected.screening = ast_to_misdn_screen(connected_id.number.presentation);
-                       bc->connected.number_type = ast_to_misdn_ton(connected_id.number.plan);
-                       bc->connected.number_plan = ast_to_misdn_plan(connected_id.number.plan);
-               } else {
-                       bc->connected.number[0] = '\0';
-                       bc->connected.presentation = 0;/* Allowed */
-                       bc->connected.screening = 0;/* Unscreened */
-                       bc->connected.number_type = NUMTYPE_UNKNOWN;
-                       bc->connected.number_plan = NUMPLAN_UNKNOWN;
-               }
-
-               misdn_cfg_get(bc->port, MISDN_CFG_CPNDIALPLAN, &number_type, sizeof(number_type));
-               if (0 <= number_type) {
-                       /* Force us to send in CONNECT message */
-                       bc->connected.number_type = number_type;
-                       bc->connected.number_plan = NUMPLAN_ISDN;
-               }
-               debug_numtype(bc->port, bc->connected.number_type, "CTON");
-       } else {
-               /* ORIGINATOR Asterisk (outgoing call) */
-
-               ast_copy_string(bc->caller.name,
-                       S_COR(connected_id.name.valid, connected_id.name.str, ""),
-                       sizeof(bc->caller.name));
-               if (connected_id.number.valid) {
-                       ast_copy_string(bc->caller.number, S_OR(connected_id.number.str, ""),
-                               sizeof(bc->caller.number));
-                       bc->caller.presentation = ast_to_misdn_pres(connected_id.number.presentation);
-                       bc->caller.screening = ast_to_misdn_screen(connected_id.number.presentation);
-                       bc->caller.number_type = ast_to_misdn_ton(connected_id.number.plan);
-                       bc->caller.number_plan = ast_to_misdn_plan(connected_id.number.plan);
-               } else {
-                       bc->caller.number[0] = '\0';
-                       bc->caller.presentation = 0;/* Allowed */
-                       bc->caller.screening = 0;/* Unscreened */
-                       bc->caller.number_type = NUMTYPE_UNKNOWN;
-                       bc->caller.number_plan = NUMPLAN_UNKNOWN;
-               }
-
-               misdn_cfg_get(bc->port, MISDN_CFG_LOCALDIALPLAN, &number_type, sizeof(number_type));
-               if (0 <= number_type) {
-                       /* Force us to send in SETUP message */
-                       bc->caller.number_type = number_type;
-                       bc->caller.number_plan = NUMPLAN_ISDN;
-               }
-               debug_numtype(bc->port, bc->caller.number_type, "LTON");
-       }
-}
-
-/*!
- * \internal
- * \brief Notify peer that the connected line has changed.
- *
- * \param ast Current Asterisk channel
- * \param bc Associated B channel
- * \param originator Who originally created this channel. ORG_AST or ORG_MISDN
- *
- * \return Nothing
- */
-static void misdn_update_connected_line(struct ast_channel *ast, struct misdn_bchannel *bc, int originator)
-{
-       struct chan_list *ch;
-
-       misdn_get_connected_line(ast, bc, originator);
-       if (originator == ORG_MISDN) {
-               bc->redirecting.to = bc->connected;
-       } else {
-               bc->redirecting.to = bc->caller;
-       }
-       switch (bc->outgoing_colp) {
-       case 1:/* restricted */
-               bc->redirecting.to.presentation = 1;/* restricted */
-               break;
-       case 2:/* blocked */
-               /* Don't tell the remote party that the call was transferred. */
-               return;
-       default:
-               break;
-       }
-
-       ch = MISDN_ASTERISK_TECH_PVT(ast);
-       if (ch->state == MISDN_CONNECTED
-               || originator != ORG_MISDN) {
-               int is_ptmp;
-
-               is_ptmp = !misdn_lib_is_ptp(bc->port);
-               if (is_ptmp) {
-                       /*
-                        * We should not send these messages to the network if we are
-                        * the CPE side since phones do not transfer calls within
-                        * themselves.  Well... If you consider handing the handset to
-                        * someone else a transfer then how is the network to know?
-                        */
-                       if (!misdn_lib_port_is_nt(bc->port)) {
-                               return;
-                       }
-                       if (ch->state != MISDN_CONNECTED) {
-                               /* Send NOTIFY(Nie(transfer-active), RDNie(redirecting.to data)) */
-                               bc->redirecting.to_changed = 1;
-                               bc->notify_description_code = mISDN_NOTIFY_CODE_CALL_TRANSFER_ACTIVE;
-                               misdn_lib_send_event(bc, EVENT_NOTIFY);
-#if defined(AST_MISDN_ENHANCEMENTS)
-                       } else {
-                               /* Send FACILITY(Fie(RequestSubaddress), Nie(transfer-active), RDNie(redirecting.to data)) */
-                               bc->redirecting.to_changed = 1;
-                               bc->notify_description_code = mISDN_NOTIFY_CODE_CALL_TRANSFER_ACTIVE;
-                               bc->fac_out.Function = Fac_RequestSubaddress;
-                               bc->fac_out.u.RequestSubaddress.InvokeID = ++misdn_invoke_id;
-
-                               /* Send message */
-                               print_facility(&bc->fac_out, bc);
-                               misdn_lib_send_event(bc, EVENT_FACILITY);
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-                       }
-#if defined(AST_MISDN_ENHANCEMENTS)
-               } else {
-                       /* Send FACILITY(Fie(EctInform(transfer-active, redirecting.to data))) */
-                       bc->fac_out.Function = Fac_EctInform;
-                       bc->fac_out.u.EctInform.InvokeID = ++misdn_invoke_id;
-                       bc->fac_out.u.EctInform.Status = 1;/* active */
-                       bc->fac_out.u.EctInform.RedirectionPresent = 1;/* Must be present when status is active */
-                       misdn_PresentedNumberUnscreened_fill(&bc->fac_out.u.EctInform.Redirection,
-                               &bc->redirecting.to);
-
-                       /* Send message */
-                       print_facility(&bc->fac_out, bc);
-                       misdn_lib_send_event(bc, EVENT_FACILITY);
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-               }
-       }
-}
-
-/*!
- * \internal
- * \brief Copy the redirecting information out of the Asterisk channel
- *
- * \param bc Associated B channel
- * \param ast Current Asterisk channel
- *
- * \return Nothing
- */
-static void misdn_copy_redirecting_from_ast(struct misdn_bchannel *bc, struct ast_channel *ast)
-{
-       struct ast_party_id from_id = ast_channel_redirecting_effective_from(ast);
-       struct ast_party_id to_id = ast_channel_redirecting_effective_to(ast);
-
-       ast_copy_string(bc->redirecting.from.name,
-               S_COR(from_id.name.valid, from_id.name.str, ""),
-               sizeof(bc->redirecting.from.name));
-       if (from_id.number.valid) {
-               ast_copy_string(bc->redirecting.from.number, S_OR(from_id.number.str, ""),
-                       sizeof(bc->redirecting.from.number));
-               bc->redirecting.from.presentation = ast_to_misdn_pres(from_id.number.presentation);
-               bc->redirecting.from.screening = ast_to_misdn_screen(from_id.number.presentation);
-               bc->redirecting.from.number_type = ast_to_misdn_ton(from_id.number.plan);
-               bc->redirecting.from.number_plan = ast_to_misdn_plan(from_id.number.plan);
-       } else {
-               bc->redirecting.from.number[0] = '\0';
-               bc->redirecting.from.presentation = 0;/* Allowed */
-               bc->redirecting.from.screening = 0;/* Unscreened */
-               bc->redirecting.from.number_type = NUMTYPE_UNKNOWN;
-               bc->redirecting.from.number_plan = NUMPLAN_UNKNOWN;
-       }
-
-       ast_copy_string(bc->redirecting.to.name,
-               S_COR(to_id.name.valid, to_id.name.str, ""),
-               sizeof(bc->redirecting.to.name));
-       if (to_id.number.valid) {
-               ast_copy_string(bc->redirecting.to.number, S_OR(to_id.number.str, ""),
-                       sizeof(bc->redirecting.to.number));
-               bc->redirecting.to.presentation = ast_to_misdn_pres(to_id.number.presentation);
-               bc->redirecting.to.screening = ast_to_misdn_screen(to_id.number.presentation);
-               bc->redirecting.to.number_type = ast_to_misdn_ton(to_id.number.plan);
-               bc->redirecting.to.number_plan = ast_to_misdn_plan(to_id.number.plan);
-       } else {
-               bc->redirecting.to.number[0] = '\0';
-               bc->redirecting.to.presentation = 0;/* Allowed */
-               bc->redirecting.to.screening = 0;/* Unscreened */
-               bc->redirecting.to.number_type = NUMTYPE_UNKNOWN;
-               bc->redirecting.to.number_plan = NUMPLAN_UNKNOWN;
-       }
-
-       bc->redirecting.reason = ast_to_misdn_reason(ast_channel_redirecting(ast)->reason.code);
-       bc->redirecting.count = ast_channel_redirecting(ast)->count;
-}
-
-/*!
- * \internal
- * \brief Copy the redirecting info into the Asterisk channel
- *
- * \param ast Current Asterisk channel
- * \param redirect Associated B channel redirecting info
- * \param tag Caller ID tag to set in the redirecting party fields
- *
- * \return Nothing
- */
-static void misdn_copy_redirecting_to_ast(struct ast_channel *ast, const struct misdn_party_redirecting *redirect, char *tag)
-{
-       struct ast_party_redirecting redirecting;
-       struct ast_set_party_redirecting update_redirecting;
-
-       ast_party_redirecting_set_init(&redirecting, ast_channel_redirecting(ast));
-       memset(&update_redirecting, 0, sizeof(update_redirecting));
-
-       update_redirecting.from.number = 1;
-       redirecting.from.number.valid = 1;
-       redirecting.from.number.str = (char *) redirect->from.number;
-       redirecting.from.number.plan =
-               misdn_to_ast_ton(redirect->from.number_type)
-               | misdn_to_ast_plan(redirect->from.number_plan);
-       redirecting.from.number.presentation =
-               misdn_to_ast_pres(redirect->from.presentation)
-               | misdn_to_ast_screen(redirect->from.screening);
-       redirecting.from.tag = tag;
-
-       update_redirecting.to.number = 1;
-       redirecting.to.number.valid = 1;
-       redirecting.to.number.str = (char *) redirect->to.number;
-       redirecting.to.number.plan =
-               misdn_to_ast_ton(redirect->to.number_type)
-               | misdn_to_ast_plan(redirect->to.number_plan);
-       redirecting.to.number.presentation =
-               misdn_to_ast_pres(redirect->to.presentation)
-               | misdn_to_ast_screen(redirect->to.screening);
-       redirecting.to.tag = tag;
-
-       redirecting.reason.code = misdn_to_ast_reason(redirect->reason);
-       redirecting.count = redirect->count;
-
-       ast_channel_set_redirecting(ast, &redirecting, &update_redirecting);
-}
-
-/*!
- * \internal
- * \brief Notify peer that the redirecting information has changed.
- *
- * \param ast Current Asterisk channel
- * \param bc Associated B channel
- * \param originator Who originally created this channel. ORG_AST or ORG_MISDN
- *
- * \return Nothing
- */
-static void misdn_update_redirecting(struct ast_channel *ast, struct misdn_bchannel *bc, int originator)
-{
-       int is_ptmp;
-
-       misdn_copy_redirecting_from_ast(bc, ast);
-       switch (bc->outgoing_colp) {
-       case 1:/* restricted */
-               bc->redirecting.to.presentation = 1;/* restricted */
-               break;
-       case 2:/* blocked */
-               /* Don't tell the remote party that the call was redirected. */
-               return;
-       default:
-               break;
-       }
-
-       if (originator != ORG_MISDN) {
-               return;
-       }
-
-       is_ptmp = !misdn_lib_is_ptp(bc->port);
-       if (is_ptmp) {
-               /*
-                * We should not send these messages to the network if we are
-                * the CPE side since phones do not redirect calls within
-                * themselves.  Well... If you consider someone else picking up
-                * the handset a redirection then how is the network to know?
-                */
-               if (!misdn_lib_port_is_nt(bc->port)) {
-                       return;
-               }
-               /* Send NOTIFY(call-is-diverting, redirecting.to data) */
-               bc->redirecting.to_changed = 1;
-               bc->notify_description_code = mISDN_NOTIFY_CODE_CALL_IS_DIVERTING;
-               misdn_lib_send_event(bc, EVENT_NOTIFY);
-#if defined(AST_MISDN_ENHANCEMENTS)
-       } else {
-               int match;      /* TRUE if the dialed number matches the redirecting to number */
-
-               match = (strcmp(ast_channel_exten(ast), bc->redirecting.to.number) == 0) ? 1 : 0;
-               if (!bc->div_leg_3_tx_pending
-                       || !match) {
-                       /* Send DivertingLegInformation1 */
-                       bc->fac_out.Function = Fac_DivertingLegInformation1;
-                       bc->fac_out.u.DivertingLegInformation1.InvokeID = ++misdn_invoke_id;
-                       bc->fac_out.u.DivertingLegInformation1.DiversionReason =
-                               misdn_to_diversion_reason(bc->redirecting.reason);
-                       bc->fac_out.u.DivertingLegInformation1.SubscriptionOption = 2;/* notificationWithDivertedToNr */
-                       bc->fac_out.u.DivertingLegInformation1.DivertedToPresent = 1;
-                       misdn_PresentedNumberUnscreened_fill(&bc->fac_out.u.DivertingLegInformation1.DivertedTo, &bc->redirecting.to);
-                       print_facility(&bc->fac_out, bc);
-                       misdn_lib_send_event(bc, EVENT_FACILITY);
-               }
-               bc->div_leg_3_tx_pending = 0;
-
-               /* Send DivertingLegInformation3 */
-               bc->fac_out.Function = Fac_DivertingLegInformation3;
-               bc->fac_out.u.DivertingLegInformation3.InvokeID = ++misdn_invoke_id;
-               bc->fac_out.u.DivertingLegInformation3.PresentationAllowedIndicator =
-                       bc->redirecting.to.presentation == 0 ? 1 : 0;
-               print_facility(&bc->fac_out, bc);
-               misdn_lib_send_event(bc, EVENT_FACILITY);
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-       }
-}
-
-
-/*****************************/
-/*** AST Indications Start ***/
-/*****************************/
-
-static int misdn_call(struct ast_channel *ast, const char *dest, int timeout)
-{
-       int port = 0;
-       int r;
-       int exceed;
-       int number_type;
-       struct chan_list *ch;
-       struct misdn_bchannel *newbc;
-       char *dest_cp;
-       int append_msn = 0;
-
-       AST_DECLARE_APP_ARGS(args,
-               AST_APP_ARG(intf);      /* The interface token is discarded. */
-               AST_APP_ARG(ext);       /* extension token */
-               AST_APP_ARG(opts);      /* options token */
-       );
-
-       if (!ast) {
-               ast_log(LOG_WARNING, " --> ! misdn_call called on ast_channel *ast where ast == NULL\n");
-               return -1;
-       }
-
-       if (((ast_channel_state(ast) != AST_STATE_DOWN) && (ast_channel_state(ast) != AST_STATE_RESERVED)) || !dest) {
-               ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast_channel_name(ast));
-               ast_channel_hangupcause_set(ast, AST_CAUSE_NORMAL_TEMPORARY_FAILURE);
-               ast_setstate(ast, AST_STATE_DOWN);
-               return -1;
-       }
-
-       ch = MISDN_ASTERISK_TECH_PVT(ast);
-       if (!ch) {
-               ast_log(LOG_WARNING, " --> ! misdn_call called on %s, chan_list *ch==NULL\n", ast_channel_name(ast));
-               ast_channel_hangupcause_set(ast, AST_CAUSE_NORMAL_TEMPORARY_FAILURE);
-               ast_setstate(ast, AST_STATE_DOWN);
-               return -1;
-       }
-
-       newbc = ch->bc;
-       if (!newbc) {
-               ast_log(LOG_WARNING, " --> ! misdn_call called on %s, newbc==NULL\n", ast_channel_name(ast));
-               ast_channel_hangupcause_set(ast, AST_CAUSE_NORMAL_TEMPORARY_FAILURE);
-               ast_setstate(ast, AST_STATE_DOWN);
-               return -1;
-       }
-
-       port = newbc->port;
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-       if ((ch->peer = misdn_cc_caller_get(ast))) {
-               chan_misdn_log(3, port, " --> Found CC caller data, peer:%s\n",
-                       ch->peer->chan ? "available" : "NULL");
-       }
-
-       if (ch->record_id != -1) {
-               struct misdn_cc_record *cc_record;
-
-               /* This is a call completion retry call */
-               AST_LIST_LOCK(&misdn_cc_records_db);
-               cc_record = misdn_cc_find_by_id(ch->record_id);
-               if (!cc_record) {
-                       AST_LIST_UNLOCK(&misdn_cc_records_db);
-                       ast_log(LOG_WARNING, " --> ! misdn_call called on %s, cc_record==NULL\n", ast_channel_name(ast));
-                       ast_channel_hangupcause_set(ast, AST_CAUSE_NORMAL_TEMPORARY_FAILURE);
-                       ast_setstate(ast, AST_STATE_DOWN);
-                       return -1;
-               }
-
-               /* Setup calling parameters to retry the call. */
-               newbc->dialed = cc_record->redial.dialed;
-               newbc->caller = cc_record->redial.caller;
-               memset(&newbc->redirecting, 0, sizeof(newbc->redirecting));
-               newbc->capability = cc_record->redial.capability;
-               newbc->hdlc = cc_record->redial.hdlc;
-               newbc->sending_complete = 1;
-
-               if (cc_record->ptp) {
-                       newbc->fac_out.Function = Fac_CCBS_T_Call;
-                       newbc->fac_out.u.CCBS_T_Call.InvokeID = ++misdn_invoke_id;
-               } else {
-                       newbc->fac_out.Function = Fac_CCBSCall;
-                       newbc->fac_out.u.CCBSCall.InvokeID = ++misdn_invoke_id;
-                       newbc->fac_out.u.CCBSCall.CCBSReference = cc_record->mode.ptmp.reference_id;
-               }
-               AST_LIST_UNLOCK(&misdn_cc_records_db);
-
-               ast_channel_exten_set(ast, newbc->dialed.number);
-
-               chan_misdn_log(1, port, "* Call completion to: %s\n", newbc->dialed.number);
-               chan_misdn_log(2, port, " --> * tech:%s context:%s\n", ast_channel_name(ast), ast_channel_context(ast));
-       } else
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-       {
-               struct ast_party_id connected_id = ast_channel_connected_effective_id(ast);
-
-               /*
-                * dest is ---v
-                * Dial(mISDN/g:group_name[/extension[/options]])
-                * Dial(mISDN/port[:preselected_channel][/extension[/options]])
-                *
-                * The dial extension could be empty if you are using MISDN_KEYPAD
-                * to control ISDN provider features.
-                */
-               dest_cp = ast_strdupa(dest);
-               AST_NONSTANDARD_APP_ARGS(args, dest_cp, '/');
-               if (!args.ext) {
-                       args.ext = "";
-               }
-
-               chan_misdn_log(1, port, "* CALL: %s\n", dest);
-               chan_misdn_log(2, port, " --> * dialed:%s tech:%s context:%s\n", args.ext, ast_channel_name(ast), ast_channel_context(ast));
-
-               ast_channel_exten_set(ast, args.ext);
-               ast_copy_string(newbc->dialed.number, args.ext, sizeof(newbc->dialed.number));
-
-               if (ast_strlen_zero(newbc->caller.name)
-                       && connected_id.name.valid
-                       && !ast_strlen_zero(connected_id.name.str)) {
-                       ast_copy_string(newbc->caller.name, connected_id.name.str, sizeof(newbc->caller.name));
-                       chan_misdn_log(3, port, " --> * set caller:\"%s\" <%s>\n", newbc->caller.name, newbc->caller.number);
-               }
-               if (ast_strlen_zero(newbc->caller.number)
-                       && connected_id.number.valid
-                       && !ast_strlen_zero(connected_id.number.str)) {
-                       ast_copy_string(newbc->caller.number, connected_id.number.str, sizeof(newbc->caller.number));
-                       chan_misdn_log(3, port, " --> * set caller:\"%s\" <%s>\n", newbc->caller.name, newbc->caller.number);
-               }
-
-               misdn_cfg_get(port, MISDN_CFG_APPEND_MSN_TO_CALLERID_TAG, &append_msn, sizeof(append_msn));
-               if (append_msn) {
-                       strncat(newbc->incoming_cid_tag, "_", sizeof(newbc->incoming_cid_tag) - strlen(newbc->incoming_cid_tag) - 1);
-                       strncat(newbc->incoming_cid_tag, newbc->caller.number, sizeof(newbc->incoming_cid_tag) - strlen(newbc->incoming_cid_tag) - 1);
-               }
-
-               ast_channel_caller(ast)->id.tag = ast_strdup(newbc->incoming_cid_tag);
-
-               misdn_cfg_get(port, MISDN_CFG_LOCALDIALPLAN, &number_type, sizeof(number_type));
-               if (number_type < 0) {
-                       if (connected_id.number.valid) {
-                               newbc->caller.number_type = ast_to_misdn_ton(connected_id.number.plan);
-                               newbc->caller.number_plan = ast_to_misdn_plan(connected_id.number.plan);
-                       } else {
-                               newbc->caller.number_type = NUMTYPE_UNKNOWN;
-                               newbc->caller.number_plan = NUMPLAN_ISDN;
-                       }
-               } else {
-                       /* Force us to send in SETUP message */
-                       newbc->caller.number_type = number_type;
-                       newbc->caller.number_plan = NUMPLAN_ISDN;
-               }
-               debug_numtype(port, newbc->caller.number_type, "LTON");
-
-               newbc->capability = ast_channel_transfercapability(ast);
-               pbx_builtin_setvar_helper(ast, "TRANSFERCAPABILITY", ast_transfercapability2str(newbc->capability));
-               if (ast_channel_transfercapability(ast) == INFO_CAPABILITY_DIGITAL_UNRESTRICTED) {
-                       chan_misdn_log(2, port, " --> * Call with flag Digital\n");
-               }
-
-               /* update caller screening and presentation */
-               update_config(ch);
-
-               /* fill in some ies from channel dialplan variables */
-               import_ch(ast, newbc, ch);
-
-               /* Finally The Options Override Everything */
-               if (!ast_strlen_zero(args.opts)) {
-                       misdn_set_opt_exec(ast, args.opts);
-               } else {
-                       chan_misdn_log(2, port, "NO OPTS GIVEN\n");
-               }
-               if (newbc->set_presentation) {
-                       newbc->caller.presentation = newbc->presentation;
-               }
-
-               misdn_copy_redirecting_from_ast(newbc, ast);
-               switch (newbc->outgoing_colp) {
-               case 1:/* restricted */
-               case 2:/* blocked */
-                       newbc->redirecting.from.presentation = 1;/* restricted */
-                       break;
-               default:
-                       break;
-               }
-#if defined(AST_MISDN_ENHANCEMENTS)
-               if (newbc->redirecting.from.number[0] && misdn_lib_is_ptp(port)) {
-                       if (newbc->redirecting.count < 1) {
-                               newbc->redirecting.count = 1;
-                       }
-
-                       /* Create DivertingLegInformation2 facility */
-                       newbc->fac_out.Function = Fac_DivertingLegInformation2;
-                       newbc->fac_out.u.DivertingLegInformation2.InvokeID = ++misdn_invoke_id;
-                       newbc->fac_out.u.DivertingLegInformation2.DivertingPresent = 1;
-                       misdn_PresentedNumberUnscreened_fill(
-                               &newbc->fac_out.u.DivertingLegInformation2.Diverting,
-                               &newbc->redirecting.from);
-                       switch (newbc->outgoing_colp) {
-                       case 2:/* blocked */
-                               /* Block the number going out */
-                               newbc->fac_out.u.DivertingLegInformation2.Diverting.Type = 1;/* presentationRestricted */
-
-                               /* Don't tell about any previous diversions or why for that matter. */
-                               newbc->fac_out.u.DivertingLegInformation2.DiversionCounter = 1;
-                               newbc->fac_out.u.DivertingLegInformation2.DiversionReason = 0;/* unknown */
-                               break;
-                       default:
-                               newbc->fac_out.u.DivertingLegInformation2.DiversionCounter =
-                                       newbc->redirecting.count;
-                               newbc->fac_out.u.DivertingLegInformation2.DiversionReason =
-                                       misdn_to_diversion_reason(newbc->redirecting.reason);
-                               break;
-                       }
-                       newbc->fac_out.u.DivertingLegInformation2.OriginalCalledPresent = 0;
-                       if (1 < newbc->fac_out.u.DivertingLegInformation2.DiversionCounter) {
-                               newbc->fac_out.u.DivertingLegInformation2.OriginalCalledPresent = 1;
-                               newbc->fac_out.u.DivertingLegInformation2.OriginalCalled.Type = 2;/* numberNotAvailableDueToInterworking */
-                       }
-
-                       /*
-                        * Expect a DivertingLegInformation3 to update the COLR of the
-                        * redirecting-to party we are attempting to call now.
-                        */
-                       newbc->div_leg_3_rx_wanted = 1;
-               }
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-       }
-
-       exceed = add_out_calls(port);
-       if (exceed != 0) {
-               char tmp[16];
-
-               snprintf(tmp, sizeof(tmp), "%d", exceed);
-               pbx_builtin_setvar_helper(ast, "MAX_OVERFLOW", tmp);
-               ast_channel_hangupcause_set(ast, AST_CAUSE_NORMAL_TEMPORARY_FAILURE);
-               ast_setstate(ast, AST_STATE_DOWN);
-               return -1;
-       }
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-       if (newbc->fac_out.Function != Fac_None) {
-               print_facility(&newbc->fac_out, newbc);
-       }
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-       r = misdn_lib_send_event(newbc, EVENT_SETUP);
-
-       /** we should have l3id after sending setup **/
-       ch->l3id = newbc->l3_id;
-
-       if (r == -ENOCHAN) {
-               chan_misdn_log(0, port, " --> * Theres no Channel at the moment .. !\n");
-               chan_misdn_log(1, port, " --> * SEND: State Down pid:%d\n", newbc ? newbc->pid : -1);
-               ast_channel_hangupcause_set(ast, AST_CAUSE_NORMAL_CIRCUIT_CONGESTION);
-               ast_setstate(ast, AST_STATE_DOWN);
-               return -1;
-       }
-
-       chan_misdn_log(2, port, " --> * SEND: State Dialing pid:%d\n", newbc ? newbc->pid : 1);
-
-       ast_setstate(ast, AST_STATE_DIALING);
-       ast_channel_hangupcause_set(ast, AST_CAUSE_NORMAL_CLEARING);
-
-       if (newbc->nt) {
-               stop_bc_tones(ch);
-       }
-
-       ch->state = MISDN_CALLING;
-
-       return 0;
-}
-
-
-static int misdn_answer(struct ast_channel *ast)
-{
-       struct chan_list *p;
-       const char *tmp;
-
-       if (!ast || !(p = MISDN_ASTERISK_TECH_PVT(ast))) {
-               return -1;
-       }
-
-       chan_misdn_log(1, p ? (p->bc ? p->bc->port : 0) : 0, "* ANSWER:\n");
-
-       if (!p) {
-               ast_log(LOG_WARNING, " --> Channel not connected ??\n");
-               ast_queue_hangup_with_cause(ast, AST_CAUSE_NETWORK_OUT_OF_ORDER);
-       }
-
-       if (!p->bc) {
-               chan_misdn_log(1, 0, " --> Got Answer, but there is no bc obj ??\n");
-
-               ast_queue_hangup_with_cause(ast, AST_CAUSE_PROTOCOL_ERROR);
-       }
-
-       ast_channel_lock(ast);
-       tmp = pbx_builtin_getvar_helper(ast, "CRYPT_KEY");
-       if (!ast_strlen_zero(tmp)) {
-               chan_misdn_log(1, p->bc->port, " --> Connection will be BF crypted\n");
-               ast_copy_string(p->bc->crypt_key, tmp, sizeof(p->bc->crypt_key));
-       } else {
-               chan_misdn_log(3, p->bc->port, " --> Connection is without BF encryption\n");
-       }
-
-       tmp = pbx_builtin_getvar_helper(ast, "MISDN_DIGITAL_TRANS");
-       if (!ast_strlen_zero(tmp) && ast_true(tmp)) {
-               chan_misdn_log(1, p->bc->port, " --> Connection is transparent digital\n");
-               p->bc->nodsp = 1;
-               p->bc->hdlc = 0;
-               p->bc->nojitter = 1;
-       }
-       ast_channel_unlock(ast);
-
-       p->state = MISDN_CONNECTED;
-       stop_indicate(p);
-
-       if (ast_strlen_zero(p->bc->connected.number)) {
-               chan_misdn_log(2,p->bc->port," --> empty connected number using dialed number\n");
-               ast_copy_string(p->bc->connected.number, p->bc->dialed.number, sizeof(p->bc->connected.number));
-
-               /*
-                * Use the misdn_set_opt() application to set the presentation
-                * before we answer or you can use the CONECTEDLINE() function
-                * to set everything before using the Answer() application.
-                */
-               p->bc->connected.presentation = p->bc->presentation;
-               p->bc->connected.screening = 0; /* unscreened */
-               p->bc->connected.number_type = p->bc->dialed.number_type;
-               p->bc->connected.number_plan = p->bc->dialed.number_plan;
-       }
-
-       switch (p->bc->outgoing_colp) {
-       case 1:/* restricted */
-       case 2:/* blocked */
-               p->bc->connected.presentation = 1;/* restricted */
-               break;
-       default:
-               break;
-       }
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-       if (p->bc->div_leg_3_tx_pending) {
-               p->bc->div_leg_3_tx_pending = 0;
-
-               /* Send DivertingLegInformation3 */
-               p->bc->fac_out.Function = Fac_DivertingLegInformation3;
-               p->bc->fac_out.u.DivertingLegInformation3.InvokeID = ++misdn_invoke_id;
-               p->bc->fac_out.u.DivertingLegInformation3.PresentationAllowedIndicator =
-                       (p->bc->connected.presentation == 0) ? 1 : 0;
-               print_facility(&p->bc->fac_out, p->bc);
-       }
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-       misdn_lib_send_event(p->bc, EVENT_CONNECT);
-       start_bc_tones(p);
-
-       return 0;
-}
-
-static int misdn_digit_begin(struct ast_channel *chan, char digit)
-{
-       /* XXX Modify this callback to support Asterisk controlling the length of DTMF */
-       return 0;
-}
-
-static int misdn_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
-{
-       struct chan_list *p;
-       struct misdn_bchannel *bc;
-       char buf[2] = { digit, 0 };
-
-       if (!ast || !(p = MISDN_ASTERISK_TECH_PVT(ast))) {
-               return -1;
-       }
-
-       bc = p->bc;
-       chan_misdn_log(1, bc ? bc->port : 0, "* IND : Digit %c\n", digit);
-
-       if (!bc) {
-               ast_log(LOG_WARNING, " --> !! Got Digit Event without having bchannel Object\n");
-               return -1;
-       }
-
-       switch (p->state) {
-       case MISDN_CALLING:
-               if (strlen(bc->infos_pending) < sizeof(bc->infos_pending) - 1) {
-                       strncat(bc->infos_pending, buf, sizeof(bc->infos_pending) - strlen(bc->infos_pending) - 1);
-               }
-               break;
-       case MISDN_CALLING_ACKNOWLEDGE:
-               ast_copy_string(bc->info_dad, buf, sizeof(bc->info_dad));
-               if (strlen(bc->dialed.number) < sizeof(bc->dialed.number) - 1) {
-                       strncat(bc->dialed.number, buf, sizeof(bc->dialed.number) - strlen(bc->dialed.number) - 1);
-               }
-               ast_channel_exten_set(p->ast, bc->dialed.number);
-               misdn_lib_send_event(bc, EVENT_INFORMATION);
-               break;
-       default:
-               if (bc->send_dtmf) {
-                       send_digit_to_chan(p, digit);
-               }
-               break;
-       }
-
-       return 0;
-}
-
-
-static int misdn_fixup(struct ast_channel *oldast, struct ast_channel *ast)
-{
-       struct chan_list *p;
-
-       if (!ast || !(p = MISDN_ASTERISK_TECH_PVT(ast))) {
-               return -1;
-       }
-
-       chan_misdn_log(1, p->bc ? p->bc->port : 0, "* IND: Got Fixup State:%s L3id:%x\n", misdn_get_ch_state(p), p->l3id);
-
-       p->ast = ast;
-
-       return 0;
-}
-
-
-
-static int misdn_indication(struct ast_channel *ast, int cond, const void *data, size_t datalen)
-{
-       struct chan_list *p;
-
-       if (!ast || !(p = MISDN_ASTERISK_TECH_PVT(ast))) {
-               ast_log(LOG_WARNING, "Returned -1 in misdn_indication\n");
-               return -1;
-       }
-
-       if (!p->bc) {
-               if (p->hold.state == MISDN_HOLD_IDLE) {
-                       chan_misdn_log(1, 0, "* IND : Indication [%d] ignored on %s\n", cond,
-                               ast_channel_name(ast));
-                       ast_log(LOG_WARNING, "Private Pointer but no bc ?\n");
-               } else {
-                       chan_misdn_log(1, 0, "* IND : Indication [%d] ignored on hold %s\n",
-                               cond, ast_channel_name(ast));
-               }
-               return -1;
-       }
-
-       chan_misdn_log(5, p->bc->port, "* IND : Indication [%d] on %s\n", cond, ast_channel_name(ast));
-
-       switch (cond) {
-       case AST_CONTROL_BUSY:
-               chan_misdn_log(1, p->bc->port, "* IND :\tbusy pid:%d\n", p->bc->pid);
-               ast_setstate(ast, AST_STATE_BUSY);
-
-               p->bc->out_cause = AST_CAUSE_USER_BUSY;
-               if (p->state != MISDN_CONNECTED) {
-                       start_bc_tones(p);
-                       misdn_lib_send_event(p->bc, EVENT_DISCONNECT);
-               }
-               return -1;
-       case AST_CONTROL_RING:
-               chan_misdn_log(1, p->bc->port, "* IND :\tring pid:%d\n", p->bc->pid);
-               return -1;
-       case AST_CONTROL_RINGING:
-               chan_misdn_log(1, p->bc->port, "* IND :\tringing pid:%d\n", p->bc->pid);
-               switch (p->state) {
-               case MISDN_ALERTING:
-                       chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d but I was Ringing before, so ignoring it\n", p->bc->pid);
-                       break;
-               case MISDN_CONNECTED:
-                       chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d but Connected, so just send TONE_ALERTING without state changes \n", p->bc->pid);
-                       return -1;
-               default:
-                       p->state = MISDN_ALERTING;
-                       chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d\n", p->bc->pid);
-                       misdn_lib_send_event(p->bc, EVENT_ALERTING);
-
-                       chan_misdn_log(3, p->bc->port, " --> * SEND: State Ring pid:%d\n", p->bc->pid);
-                       ast_setstate(ast, AST_STATE_RING);
-
-                       if (!p->bc->nt && (p->originator == ORG_MISDN) && !p->incoming_early_audio) {
-                               chan_misdn_log(2, p->bc->port, " --> incoming_early_audio off\n");
-                       } else {
-                               return -1;
-                       }
-               }
-               break;
-       case AST_CONTROL_ANSWER:
-               chan_misdn_log(1, p->bc->port, " --> * IND :\tanswer pid:%d\n", p->bc->pid);
-               start_bc_tones(p);
-               break;
-       case AST_CONTROL_TAKEOFFHOOK:
-               chan_misdn_log(1, p->bc->port, " --> *\ttakeoffhook pid:%d\n", p->bc->pid);
-               return -1;
-       case AST_CONTROL_OFFHOOK:
-               chan_misdn_log(1, p->bc->port, " --> *\toffhook pid:%d\n", p->bc->pid);
-               return -1;
-       case AST_CONTROL_FLASH:
-               chan_misdn_log(1, p->bc->port, " --> *\tflash pid:%d\n", p->bc->pid);
-               break;
-       case AST_CONTROL_PROGRESS:
-               chan_misdn_log(1, p->bc->port, " --> * IND :\tprogress pid:%d\n", p->bc->pid);
-               misdn_lib_send_event(p->bc, EVENT_PROGRESS);
-               break;
-       case AST_CONTROL_PROCEEDING:
-               chan_misdn_log(1, p->bc->port, " --> * IND :\tproceeding pid:%d\n", p->bc->pid);
-               misdn_lib_send_event(p->bc, EVENT_PROCEEDING);
-               break;
-       case AST_CONTROL_INCOMPLETE:
-               chan_misdn_log(1, p->bc->port, " --> *\tincomplete pid:%d\n", p->bc->pid);
-               if (!p->overlap_dial) {
-                       /* Overlapped dialing not enabled - send hangup */
-                       p->bc->out_cause = AST_CAUSE_INVALID_NUMBER_FORMAT;
-                       start_bc_tones(p);
-                       misdn_lib_send_event(p->bc, EVENT_DISCONNECT);
-
-                       if (p->bc->nt) {
-                               hanguptone_indicate(p);
-                       }
-               }
-               break;
-       case AST_CONTROL_CONGESTION:
-               chan_misdn_log(1, p->bc->port, " --> * IND :\tcongestion pid:%d\n", p->bc->pid);
-
-               p->bc->out_cause = AST_CAUSE_SWITCH_CONGESTION;
-               start_bc_tones(p);
-               misdn_lib_send_event(p->bc, EVENT_DISCONNECT);
-
-               if (p->bc->nt) {
-                       hanguptone_indicate(p);
-               }
-               break;
-       case -1 :
-               chan_misdn_log(1, p->bc->port, " --> * IND :\t-1! (stop indication) pid:%d\n", p->bc->pid);
-
-               stop_indicate(p);
-
-               if (p->state == MISDN_CONNECTED) {
-                       start_bc_tones(p);
-               }
-               break;
-       case AST_CONTROL_HOLD:
-               ast_moh_start(ast, data, p->mohinterpret);
-               chan_misdn_log(1, p->bc->port, " --> *\tHOLD pid:%d\n", p->bc->pid);
-               break;
-       case AST_CONTROL_UNHOLD:
-               ast_moh_stop(ast);
-               chan_misdn_log(1, p->bc->port, " --> *\tUNHOLD pid:%d\n", p->bc->pid);
-               break;
-       case AST_CONTROL_CONNECTED_LINE:
-               chan_misdn_log(1, p->bc->port, "* IND :\tconnected line update pid:%d\n", p->bc->pid);
-               misdn_update_connected_line(ast, p->bc, p->originator);
-               break;
-       case AST_CONTROL_REDIRECTING:
-               chan_misdn_log(1, p->bc->port, "* IND :\tredirecting info update pid:%d\n", p->bc->pid);
-               misdn_update_redirecting(ast, p->bc, p->originator);
-               break;
-       default:
-               chan_misdn_log(1, p->bc->port, " --> * Unknown Indication:%d pid:%d\n", cond, p->bc->pid);
-               /* fallthrough */
-       case AST_CONTROL_PVT_CAUSE_CODE:
-       case AST_CONTROL_MASQUERADE_NOTIFY:
-               return -1;
-       }
-
-       return 0;
-}
-
-static int misdn_hangup(struct ast_channel *ast)
-{
-       struct chan_list *p;
-       struct misdn_bchannel *bc;
-       const char *var;
-
-       if (!ast) {
-               return -1;
-       }
-
-       ast_debug(1, "misdn_hangup(%s)\n", ast_channel_name(ast));
-
-       /* Take the ast_channel's tech_pvt reference. */
-       ast_mutex_lock(&release_lock);
-       p = MISDN_ASTERISK_TECH_PVT(ast);
-       if (!p) {
-               ast_mutex_unlock(&release_lock);
-               return -1;
-       }
-       MISDN_ASTERISK_TECH_PVT_SET(ast, NULL);
-
-       if (!misdn_chan_is_valid(p)) {
-               ast_mutex_unlock(&release_lock);
-               chan_list_unref(p, "Release ast_channel reference.  Was not active?");
-               return 0;
-       }
-
-       if (p->hold.state == MISDN_HOLD_IDLE) {
-               bc = p->bc;
-       } else {
-               p->hold.state = MISDN_HOLD_DISCONNECT;
-               bc = misdn_lib_find_held_bc(p->hold.port, p->l3id);
-               if (!bc) {
-                       chan_misdn_log(4, p->hold.port,
-                               "misdn_hangup: Could not find held bc for (%s)\n", ast_channel_name(ast));
-                       release_chan_early(p);
-                       ast_mutex_unlock(&release_lock);
-                       chan_list_unref(p, "Release ast_channel reference");
-                       return 0;
-               }
-       }
-
-       if (ast_channel_state(ast) == AST_STATE_RESERVED || p->state == MISDN_NOTHING) {
-               /* between request and call */
-               ast_debug(1, "State Reserved (or nothing) => chanIsAvail\n");
-               release_chan_early(p);
-               if (bc) {
-                       misdn_lib_release(bc);
-               }
-               ast_mutex_unlock(&release_lock);
-               chan_list_unref(p, "Release ast_channel reference");
-               return 0;
-       }
-       if (!bc) {
-               ast_log(LOG_WARNING, "Hangup with private but no bc ? state:%s l3id:%x\n",
-                       misdn_get_ch_state(p), p->l3id);
-               release_chan_early(p);
-               ast_mutex_unlock(&release_lock);
-               chan_list_unref(p, "Release ast_channel reference");
-               return 0;
-       }
-
-       p->ast = NULL;
-       p->need_hangup = 0;
-       p->need_queue_hangup = 0;
-       p->need_busy = 0;
-
-       if (!bc->nt) {
-               stop_bc_tones(p);
-       }
-
-       bc->out_cause = ast_channel_hangupcause(ast) ? ast_channel_hangupcause(ast) : AST_CAUSE_NORMAL_CLEARING;
-
-       /* Channel lock is already held when we are called. */
-       //ast_channel_lock(ast);
-       var = pbx_builtin_getvar_helper(ast, "HANGUPCAUSE");
-       if (!var) {
-               var = pbx_builtin_getvar_helper(ast, "PRI_CAUSE");
-       }
-       if (var) {
-               int tmpcause;
-
-               tmpcause = atoi(var);
-               bc->out_cause = tmpcause ? tmpcause : AST_CAUSE_NORMAL_CLEARING;
-       }
-
-       var = pbx_builtin_getvar_helper(ast, "MISDN_USERUSER");
-       if (var) {
-               ast_log(LOG_NOTICE, "MISDN_USERUSER: %s\n", var);
-               ast_copy_string(bc->uu, var, sizeof(bc->uu));
-               bc->uulen = strlen(bc->uu);
-       }
-       //ast_channel_unlock(ast);
-
-       chan_misdn_log(1, bc->port,
-               "* IND : HANGUP\tpid:%d context:%s dialed:%s caller:\"%s\" <%s> State:%s\n",
-               bc->pid,
-               ast_channel_context(ast),
-               ast_channel_exten(ast),
-               (ast_channel_caller(ast)->id.name.valid && ast_channel_caller(ast)->id.name.str)
-                       ? ast_channel_caller(ast)->id.name.str : "",
-               (ast_channel_caller(ast)->id.number.valid && ast_channel_caller(ast)->id.number.str)
-                       ? ast_channel_caller(ast)->id.number.str : "",
-               misdn_get_ch_state(p));
-       chan_misdn_log(3, bc->port, " --> l3id:%x\n", p->l3id);
-       chan_misdn_log(3, bc->port, " --> cause:%d\n", bc->cause);
-       chan_misdn_log(2, bc->port, " --> out_cause:%d\n", bc->out_cause);
-
-       switch (p->state) {
-       case MISDN_INCOMING_SETUP:
-               /*
-                * This is the only place in misdn_hangup, where we
-                * can call release_chan, else it might create a lot of trouble.
-                */
-               ast_log(LOG_NOTICE, "release channel, in INCOMING_SETUP state.. no other events happened\n");
-               release_chan(p, bc);
-               misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE);
-               ast_mutex_unlock(&release_lock);
-               chan_list_unref(p, "Release ast_channel reference");
-               return 0;
-       case MISDN_DIALING:
-               if (p->hold.state == MISDN_HOLD_IDLE) {
-                       start_bc_tones(p);
-                       hanguptone_indicate(p);
-               }
-
-               if (bc->need_disconnect) {
-                       misdn_lib_send_event(bc, EVENT_DISCONNECT);
-               }
-               break;
-       case MISDN_CALLING_ACKNOWLEDGE:
-               if (p->hold.state == MISDN_HOLD_IDLE) {
-                       start_bc_tones(p);
-                       hanguptone_indicate(p);
-               }
-
-               if (bc->need_disconnect) {
-                       misdn_lib_send_event(bc, EVENT_DISCONNECT);
-               }
-               break;
-
-       case MISDN_CALLING:
-       case MISDN_ALERTING:
-       case MISDN_PROGRESS:
-       case MISDN_PROCEEDING:
-               if (p->originator != ORG_AST && p->hold.state == MISDN_HOLD_IDLE) {
-                       hanguptone_indicate(p);
-               }
-
-               if (bc->need_disconnect) {
-                       misdn_lib_send_event(bc, EVENT_DISCONNECT);
-               }
-               break;
-       case MISDN_CONNECTED:
-               /*  Alerting or Disconnect */
-               if (bc->nt && p->hold.state == MISDN_HOLD_IDLE) {
-                       start_bc_tones(p);
-                       hanguptone_indicate(p);
-                       bc->progress_indicator = INFO_PI_INBAND_AVAILABLE;
-               }
-               if (bc->need_disconnect) {
-                       misdn_lib_send_event(bc, EVENT_DISCONNECT);
-               }
-               break;
-       case MISDN_DISCONNECTED:
-               if (bc->need_release) {
-                       misdn_lib_send_event(bc, EVENT_RELEASE);
-               }
-               break;
-
-       case MISDN_CLEANING:
-               ast_mutex_unlock(&release_lock);
-               chan_list_unref(p, "Release ast_channel reference");
-               return 0;
-
-       case MISDN_BUSY:
-               break;
-       default:
-               if (bc->nt) {
-                       bc->out_cause = -1;
-                       if (bc->need_release) {
-                               misdn_lib_send_event(bc, EVENT_RELEASE);
-                       }
-               } else {
-                       if (bc->need_disconnect) {
-                               misdn_lib_send_event(bc, EVENT_DISCONNECT);
-                       }
-               }
-               break;
-       }
-
-       p->state = MISDN_CLEANING;
-       chan_misdn_log(3, bc->port, " --> Channel: %s hungup new state:%s\n", ast_channel_name(ast),
-               misdn_get_ch_state(p));
-
-       ast_mutex_unlock(&release_lock);
-       chan_list_unref(p, "Release ast_channel reference");
-       return 0;
-}
-
-
-static struct ast_frame *process_ast_dsp(struct chan_list *tmp, struct ast_frame *frame)
-{
-       struct ast_frame *f;
-
-       if (tmp->dsp) {
-               f = ast_dsp_process(tmp->ast, tmp->dsp, frame);
-       } else {
-               chan_misdn_log(0, tmp->bc->port, "No DSP-Path found\n");
-               return NULL;
-       }
-
-       if (!f || (f->frametype != AST_FRAME_DTMF)) {
-               return f;
-       }
-
-       ast_debug(1, "Detected inband DTMF digit: %c\n", f->subclass.integer);
-
-       if (tmp->faxdetect && (f->subclass.integer == 'f')) {
-               /* Fax tone -- Handle and return NULL */
-               if (!tmp->faxhandled) {
-                       struct ast_channel *ast = tmp->ast;
-                       tmp->faxhandled++;
-                       chan_misdn_log(0, tmp->bc->port, "Fax detected, preparing %s for fax transfer.\n", ast_channel_name(ast));
-                       tmp->bc->rxgain = 0;
-                       isdn_lib_update_rxgain(tmp->bc);
-                       tmp->bc->txgain = 0;
-                       isdn_lib_update_txgain(tmp->bc);
-#ifdef MISDN_1_2
-                       *tmp->bc->pipeline = 0;
-#else
-                       tmp->bc->ec_enable = 0;
-#endif
-                       isdn_lib_update_ec(tmp->bc);
-                       isdn_lib_stop_dtmf(tmp->bc);
-                       switch (tmp->faxdetect) {
-                       case 1:
-                               if (strcmp(ast_channel_exten(ast), "fax")) {
-                                       const char *context;
-                                       char context_tmp[BUFFERSIZE];
-                                       misdn_cfg_get(tmp->bc->port, MISDN_CFG_FAXDETECT_CONTEXT, &context_tmp, sizeof(context_tmp));
-                                       context = S_OR(context_tmp, S_OR(ast_channel_macrocontext(ast), ast_channel_context(ast)));
-                                       if (ast_exists_extension(ast, context, "fax", 1,
-                                               S_COR(ast_channel_caller(ast)->id.number.valid, ast_channel_caller(ast)->id.number.str, NULL))) {
-                                               ast_verb(3, "Redirecting %s to fax extension (context:%s)\n", ast_channel_name(ast), context);
-                                               /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */
-                                               pbx_builtin_setvar_helper(ast,"FAXEXTEN",ast_channel_exten(ast));
-                                               if (ast_async_goto(ast, context, "fax", 1)) {
-                                                       ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast_channel_name(ast), context);
-                                               }
-                                       } else {
-                                               ast_log(LOG_NOTICE, "Fax detected but no fax extension, context:%s exten:%s\n", context, ast_channel_exten(ast));
-                                       }
-                               } else {
-                                       ast_debug(1, "Already in a fax extension, not redirecting\n");
-                               }
-                               break;
-                       case 2:
-                               ast_verb(3, "Not redirecting %s to fax extension, nojump is set.\n", ast_channel_name(ast));
-                               break;
-                       default:
-                               break;
-                       }
-               } else {
-                       ast_debug(1, "Fax already handled\n");
-               }
-       }
-
-       if (tmp->ast_dsp && (f->subclass.integer != 'f')) {
-               chan_misdn_log(2, tmp->bc->port, " --> * SEND: DTMF (AST_DSP) :%c\n", f->subclass.integer);
-       }
-
-       return f;
-}
-
-
-static struct ast_frame *misdn_read(struct ast_channel *ast)
-{
-       struct chan_list *tmp;
-       int len, t;
-       struct pollfd pfd = { .fd = -1, .events = POLLIN };
-
-       if (!ast) {
-               chan_misdn_log(1, 0, "misdn_read called without ast\n");
-               return NULL;
-       }
-       if (!(tmp = MISDN_ASTERISK_TECH_PVT(ast))) {
-               chan_misdn_log(1, 0, "misdn_read called without ast->pvt\n");
-               return NULL;
-       }
-
-       if (!tmp->bc && tmp->hold.state == MISDN_HOLD_IDLE) {
-               chan_misdn_log(1, 0, "misdn_read called without bc\n");
-               return NULL;
-       }
-
-       pfd.fd = tmp->pipe[0];
-       t = ast_poll(&pfd, 1, 20);
-
-       if (t < 0) {
-               chan_misdn_log(-1, tmp->bc->port, "poll() error (err=%s)\n", strerror(errno));
-               return NULL;
-       }
-
-       if (!t) {
-               chan_misdn_log(3, tmp->bc->port, "poll() timed out\n");
-               len = 160;
-       } else if (pfd.revents & POLLIN) {
-               len = read(tmp->pipe[0], tmp->ast_rd_buf, sizeof(tmp->ast_rd_buf));
-
-               if (len <= 0) {
-                       /* we hangup here, since our pipe is closed */
-                       chan_misdn_log(2, tmp->bc->port, "misdn_read: Pipe closed, hanging up\n");
-                       return NULL;
-               }
-       } else {
-               return NULL;
-       }
-
-       tmp->frame.frametype = AST_FRAME_VOICE;
-       tmp->frame.subclass.format = ast_format_alaw;
-       tmp->frame.datalen = len;
-       tmp->frame.samples = len;
-       tmp->frame.mallocd = 0;
-       tmp->frame.offset = 0;
-       tmp->frame.delivery = ast_tv(0, 0);
-       tmp->frame.src = NULL;
-       tmp->frame.data.ptr = tmp->ast_rd_buf;
-
-       if (tmp->faxdetect && !tmp->faxhandled) {
-               if (tmp->faxdetect_timeout) {
-                       if (ast_tvzero(tmp->faxdetect_tv)) {
-                               tmp->faxdetect_tv = ast_tvnow();
-                               chan_misdn_log(2, tmp->bc->port, "faxdetect: starting detection with timeout: %ds ...\n", tmp->faxdetect_timeout);
-                               return process_ast_dsp(tmp, &tmp->frame);
-                       } else {
-                               struct timeval tv_now = ast_tvnow();
-                               int diff = ast_tvdiff_ms(tv_now, tmp->faxdetect_tv);
-                               if (diff <= (tmp->faxdetect_timeout * 1000)) {
-                                       chan_misdn_log(5, tmp->bc->port, "faxdetect: detecting ...\n");
-                                       return process_ast_dsp(tmp, &tmp->frame);
-                               } else {
-                                       chan_misdn_log(2, tmp->bc->port, "faxdetect: stopping detection (time ran out) ...\n");
-                                       tmp->faxdetect = 0;
-                                       return &tmp->frame;
-                               }
-                       }
-               } else {
-                       chan_misdn_log(5, tmp->bc->port, "faxdetect: detecting ... (no timeout)\n");
-                       return process_ast_dsp(tmp, &tmp->frame);
-               }
-       } else {
-               if (tmp->ast_dsp) {
-                       return process_ast_dsp(tmp, &tmp->frame);
-               } else {
-                       return &tmp->frame;
-               }
-       }
-}
-
-
-static int misdn_write(struct ast_channel *ast, struct ast_frame *frame)
-{
-       struct chan_list *ch;
-
-       if (!ast || !(ch = MISDN_ASTERISK_TECH_PVT(ast))) {
-               return -1;
-       }
-
-       if (ch->hold.state != MISDN_HOLD_IDLE) {
-               chan_misdn_log(7, 0, "misdn_write: Returning because hold active\n");
-               return 0;
-       }
-
-       if (!ch->bc) {
-               ast_log(LOG_WARNING, "private but no bc\n");
-               return -1;
-       }
-
-       if (ch->notxtone) {
-               chan_misdn_log(7, ch->bc->port, "misdn_write: Returning because notxtone\n");
-               return 0;
-       }
-
-
-       if (!frame->subclass.format) {
-               chan_misdn_log(4, ch->bc->port, "misdn_write: * prods us\n");
-               return 0;
-       }
-
-       if (ast_format_cmp(frame->subclass.format, ast_format_alaw) == AST_FORMAT_CMP_NOT_EQUAL) {
-               chan_misdn_log(-1, ch->bc->port, "Got Unsupported Frame with Format:%s\n",
-                       ast_format_get_name(frame->subclass.format));
-               return 0;
-       }
-
-
-       if (!frame->samples) {
-               chan_misdn_log(4, ch->bc->port, "misdn_write: zero write\n");
-
-               if (!strcmp(frame->src,"ast_prod")) {
-                       chan_misdn_log(1, ch->bc->port, "misdn_write: state (%s) prodded.\n", misdn_get_ch_state(ch));
-
-                       if (ch->ts) {
-                               chan_misdn_log(4, ch->bc->port, "Starting Playtones\n");
-                               misdn_lib_tone_generator_start(ch->bc);
-                       }
-                       return 0;
-               }
-
-               return -1;
-       }
-
-       if (!ch->bc->addr) {
-               chan_misdn_log(8, ch->bc->port, "misdn_write: no addr for bc dropping:%d\n", frame->samples);
-               return 0;
-       }
-
-#ifdef MISDN_DEBUG
-       {
-               int i;
-               int max = 5 > frame->samples ? frame->samples : 5;
-
-               ast_debug(1, "write2mISDN %p %d bytes: ", p, frame->samples);
-
-               for (i = 0; i < max; i++) {
-                       ast_debug(1, "%02hhx ", ((unsigned char *) frame->data.ptr)[i]);
-               }
-       }
-#endif
-
-       switch (ch->bc->bc_state) {
-       case BCHAN_ACTIVATED:
-       case BCHAN_BRIDGED:
-               break;
-       default:
-               if (!ch->dropped_frame_cnt) {
-                       chan_misdn_log(5, ch->bc->port,
-                               "BC not active (nor bridged) dropping: %d frames addr:%x exten:%s cid:%s ch->state:%s bc_state:%d l3id:%x\n",
-                               frame->samples, ch->bc->addr, ast_channel_exten(ast),
-                               S_COR(ast_channel_caller(ast)->id.number.valid, ast_channel_caller(ast)->id.number.str, ""),
-                               misdn_get_ch_state(ch), ch->bc->bc_state, ch->bc->l3_id);
-               }
-
-               if (++ch->dropped_frame_cnt > 100) {
-                       ch->dropped_frame_cnt = 0;
-                       chan_misdn_log(5, ch->bc->port, "BC not active (nor bridged) dropping: %d frames addr:%x  dropped > 100 frames!\n", frame->samples, ch->bc->addr);
-               }
-
-               return 0;
-       }
-
-       chan_misdn_log(9, ch->bc->port, "Sending :%d bytes to MISDN\n", frame->samples);
-       if (!ch->bc->nojitter && misdn_cap_is_speech(ch->bc->capability)) {
-               /* Buffered Transmit (triggered by read from isdn side)*/
-               if (misdn_jb_fill(ch->jb, frame->data.ptr, frame->samples) < 0) {
-                       if (ch->bc->active) {
-                               cb_log(0, ch->bc->port, "Misdn Jitterbuffer Overflow.\n");
-                       }
-               }
-
-       } else {
-               /* transmit without jitterbuffer */
-               misdn_lib_tx2misdn_frm(ch->bc, frame->data.ptr, frame->samples);
-       }
-
-       return 0;
-}
-
-#if defined(mISDN_NATIVE_BRIDGING)
-static enum ast_bridge_result misdn_bridge(struct ast_channel *c0,
-       struct ast_channel *c1, int flags,
-       struct ast_frame **fo,
-       struct ast_channel **rc,
-       int timeoutms)
-{
-       struct chan_list *ch1, *ch2;
-       struct ast_channel *carr[2], *who;
-       int to = -1;
-       struct ast_frame *f;
-       int p1_b, p2_b;
-       int bridging;
-
-       misdn_cfg_get(0, MISDN_GEN_BRIDGING, &bridging, sizeof(bridging));
-       if (!bridging) {
-               /* Native mISDN bridging globally disabled. */
-               return AST_BRIDGE_FAILED_NOWARN;
-       }
-
-       ch1 = get_chan_by_ast(c0);
-       if (!ch1) {
-               return AST_BRIDGE_FAILED;
-       }
-       ch2 = get_chan_by_ast(c1);
-       if (!ch2) {
-               chan_list_unref(ch1, "Failed to find ch2");
-               return AST_BRIDGE_FAILED;
-       }
-
-       carr[0] = c0;
-       carr[1] = c1;
-
-       misdn_cfg_get(ch1->bc->port, MISDN_CFG_BRIDGING, &p1_b, sizeof(p1_b));
-       misdn_cfg_get(ch2->bc->port, MISDN_CFG_BRIDGING, &p2_b, sizeof(p2_b));
-       if (!p1_b || !p2_b) {
-               ast_log(LOG_NOTICE, "Falling back to Asterisk bridging\n");
-               chan_list_unref(ch1, "Bridge fallback ch1");
-               chan_list_unref(ch2, "Bridge fallback ch2");
-               return AST_BRIDGE_FAILED_NOWARN;
-       }
-
-       /* make a mISDN_dsp conference */
-       chan_misdn_log(1, ch1->bc->port, "I SEND: Making conference with Number:%d\n", ch1->bc->pid + 1);
-       misdn_lib_bridge(ch1->bc, ch2->bc);
-
-       ast_verb(3, "Native bridging %s and %s\n", ast_channel_name(c0), ast_channel_name(c1));
-
-       chan_misdn_log(1, ch1->bc->port, "* Making Native Bridge between \"%s\" <%s> and \"%s\" <%s>\n",
-               ch1->bc->caller.name,
-               ch1->bc->caller.number,
-               ch2->bc->caller.name,
-               ch2->bc->caller.number);
-
-       if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0)) {
-               ch1->ignore_dtmf = 1;
-       }
-
-       if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1)) {
-               ch2->ignore_dtmf = 1;
-       }
-
-       for (;/*ever*/;) {
-               to = -1;
-               who = ast_waitfor_n(carr, 2, &to);
-
-               if (!who) {
-                       ast_log(LOG_NOTICE, "misdn_bridge: empty read, breaking out\n");
-                       break;
-               }
-               f = ast_read(who);
-
-               if (!f || (f->frametype == AST_FRAME_CONTROL && f->subclass.integer != AST_CONTROL_PVT_CAUSE_CODE)) {
-                       /* got hangup .. */
-
-                       if (!f) {
-                               chan_misdn_log(4, ch1->bc->port, "Read Null Frame\n");
-                       } else {
-                               chan_misdn_log(4, ch1->bc->port, "Read Frame Control class:%d\n", f->subclass.integer);
-                       }
-
-                       *fo = f;
-                       *rc = who;
-                       break;
-               }
-
-               if (f->frametype == AST_FRAME_DTMF) {
-                       chan_misdn_log(1, 0, "Read DTMF %d from %s\n", f->subclass.integer, ast_channel_exten(who));
-
-                       *fo = f;
-                       *rc = who;
-                       break;
-               }
-
-#if 0
-               if (f->frametype == AST_FRAME_VOICE) {
-                       chan_misdn_log(1, ch1->bc->port, "I SEND: Splitting conference with Number:%d\n", ch1->bc->pid +1);
-
-                       continue;
-               }
-#endif
-
-               if (f->frametype == AST_FRAME_CONTROL && f->subclass.integer == AST_CONTROL_PVT_CAUSE_CODE) {
-                       ast_channel_hangupcause_hash_set((who == c0) ? c1 : c0, f->data.ptr, f->datalen);
-               } else {
-                       ast_write((who == c0) ? c1 : c0, f);
-               }
-       }
-
-       chan_misdn_log(1, ch1->bc->port, "I SEND: Splitting conference with Number:%d\n", ch1->bc->pid + 1);
-
-       misdn_lib_split_bridge(ch1->bc, ch2->bc);
-
-       chan_list_unref(ch1, "Bridge complete ch1");
-       chan_list_unref(ch2, "Bridge complete ch2");
-       return AST_BRIDGE_COMPLETE;
-}
-#endif /* defined(mISDN_NATIVE_BRIDGING) */
-
-/** AST INDICATIONS END **/
-
-static int dialtone_indicate(struct chan_list *cl)
-{
-       struct ast_channel *ast = cl->ast;
-       int nd = 0;
-
-       if (!ast) {
-               chan_misdn_log(0, cl->bc->port, "No Ast in dialtone_indicate\n");
-               return -1;
-       }
-
-       misdn_cfg_get(cl->bc->port, MISDN_CFG_NODIALTONE, &nd, sizeof(nd));
-
-       if (nd) {
-               chan_misdn_log(1, cl->bc->port, "Not sending Dialtone, because config wants it\n");
-               return 0;
-       }
-
-       chan_misdn_log(3, cl->bc->port, " --> Dial\n");
-
-       cl->ts = ast_get_indication_tone(ast_channel_zone(ast), "dial");
-
-       if (cl->ts) {
-               cl->notxtone = 0;
-               cl->norxtone = 0;
-               /* This prods us in misdn_write */
-               ast_playtones_start(ast, 0, cl->ts->data, 0);
-       }
-
-       return 0;
-}
-
-static void hanguptone_indicate(struct chan_list *cl)
-{
-       misdn_lib_send_tone(cl->bc, TONE_HANGUP);
-}
-
-static int stop_indicate(struct chan_list *cl)
-{
-       struct ast_channel *ast = cl->ast;
-
-       if (!ast) {
-               chan_misdn_log(0, cl->bc->port, "No Ast in stop_indicate\n");
-               return -1;
-       }
-
-       chan_misdn_log(3, cl->bc->port, " --> None\n");
-       misdn_lib_tone_generator_stop(cl->bc);
-       ast_playtones_stop(ast);
-
-       if (cl->ts) {
-               cl->ts = ast_tone_zone_sound_unref(cl->ts);
-       }
-
-       return 0;
-}
-
-
-static int start_bc_tones(struct chan_list* cl)
-{
-       misdn_lib_tone_generator_stop(cl->bc);
-       cl->notxtone = 0;
-       cl->norxtone = 0;
-       return 0;
-}
-
-static int stop_bc_tones(struct chan_list *cl)
-{
-       if (!cl) {
-               return -1;
-       }
-
-       cl->notxtone = 1;
-       cl->norxtone = 1;
-
-       return 0;
-}
-
-/*!
- * \internal
- * \brief Destroy the chan_list object.
- *
- * \param obj chan_list object to destroy.
- *
- * \return Nothing
- */
-static void chan_list_destructor(void *obj)
-{
-       struct chan_list *ch = obj;
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-       if (ch->peer) {
-               ao2_ref(ch->peer, -1);
-               ch->peer = NULL;
-       }
-#endif /* AST_MISDN_ENHANCEMENTS */
-
-       if (ch->dsp) {
-               ast_dsp_free(ch->dsp);
-               ch->dsp = NULL;
-       }
-
-       /* releasing jitterbuffer */
-       if (ch->jb) {
-               misdn_jb_destroy(ch->jb);
-               ch->jb = NULL;
-       }
-
-       if (ch->overlap_dial) {
-               if (ch->overlap_dial_task != -1) {
-                       misdn_tasks_remove(ch->overlap_dial_task);
-                       ch->overlap_dial_task = -1;
-               }
-               ast_mutex_destroy(&ch->overlap_tv_lock);
-       }
-
-       if (-1 < ch->pipe[0]) {
-               close(ch->pipe[0]);
-       }
-       if (-1 < ch->pipe[1]) {
-               close(ch->pipe[1]);
-       }
-}
-
-/*! Returns a reference to the new chan_list. */
-static struct chan_list *chan_list_init(int orig)
-{
-       struct chan_list *cl;
-
-       cl = ao2_alloc(sizeof(*cl), chan_list_destructor);
-       if (!cl) {
-               chan_misdn_log(-1, 0, "misdn_request: malloc failed!");
-               return NULL;
-       }
-
-       cl->originator = orig;
-       cl->need_queue_hangup = 1;
-       cl->need_hangup = 1;
-       cl->need_busy = 1;
-       cl->overlap_dial_task = -1;
-#if defined(AST_MISDN_ENHANCEMENTS)
-       cl->record_id = -1;
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-       cl->pipe[0] = -1;
-       cl->pipe[1] = -1;
-
-       return cl;
-}
-
-static struct ast_channel *misdn_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
-{
-       struct ast_channel *ast;
-       char group[BUFFERSIZE + 1] = "";
-       char dial_str[128];
-       char *dest_cp;
-       char *p = NULL;
-       int channel = 0;
-       int port = 0;
-       struct misdn_bchannel *newbc = NULL;
-       int dec = 0;
-#if defined(AST_MISDN_ENHANCEMENTS)
-       int cc_retry_call = 0;  /* TRUE if this is a call completion retry call */
-       long record_id = -1;
-       struct misdn_cc_record *cc_record;
-       const char *err_msg;
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-       struct chan_list *cl;
-
-       AST_DECLARE_APP_ARGS(args,
-               AST_APP_ARG(intf);      /* interface token */
-               AST_APP_ARG(ext);       /* extension token */
-               AST_APP_ARG(opts);      /* options token */
-       );
-
-       snprintf(dial_str, sizeof(dial_str), "%s/%s", misdn_type, data);
-
-       /*
-        * data is ---v
-        * Dial(mISDN/g:group_name[/extension[/options]])
-        * Dial(mISDN/port[:preselected_channel][/extension[/options]])
-        * Dial(mISDN/cc/cc-record-id)
-        *
-        * The dial extension could be empty if you are using MISDN_KEYPAD
-        * to control ISDN provider features.
-        */
-       dest_cp = ast_strdupa(data);
-       AST_NONSTANDARD_APP_ARGS(args, dest_cp, '/');
-       if (!args.ext) {
-               args.ext = "";
-       }
-
-       if (!ast_strlen_zero(args.intf)) {
-               if (args.intf[0] == 'g' && args.intf[1] == ':') {
-                       /* We make a group call lets checkout which ports are in my group */
-                       args.intf += 2;
-                       ast_copy_string(group, args.intf, sizeof(group));
-                       chan_misdn_log(2, 0, " --> Group Call group: %s\n", group);
-#if defined(AST_MISDN_ENHANCEMENTS)
-               } else if (strcmp(args.intf, "cc") == 0) {
-                       cc_retry_call = 1;
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-               } else if ((p = strchr(args.intf, ':'))) {
-                       /* we have a preselected channel */
-                       *p++ = 0;
-                       channel = atoi(p);
-                       port = atoi(args.intf);
-                       chan_misdn_log(2, port, " --> Call on preselected Channel (%d).\n", channel);
-               } else {
-                       port = atoi(args.intf);
-               }
-       } else {
-               ast_log(LOG_WARNING, " --> ! IND : Dial(%s) WITHOUT Port or Group, check extensions.conf\n", dial_str);
-               return NULL;
-       }
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-       if (cc_retry_call) {
-               if (ast_strlen_zero(args.ext)) {
-                       ast_log(LOG_WARNING, " --> ! IND : Dial(%s) WITHOUT cc-record-id, check extensions.conf\n", dial_str);
-                       return NULL;
-               }
-               if (!isdigit(*args.ext)) {
-                       ast_log(LOG_WARNING, " --> ! IND : Dial(%s) cc-record-id must be a number.\n", dial_str);
-                       return NULL;
-               }
-               record_id = atol(args.ext);
-
-               AST_LIST_LOCK(&misdn_cc_records_db);
-               cc_record = misdn_cc_find_by_id(record_id);
-               if (!cc_record) {
-                       AST_LIST_UNLOCK(&misdn_cc_records_db);
-                       err_msg = misdn_cc_record_not_found;
-                       ast_log(LOG_WARNING, " --> ! IND : Dial(%s) %s.\n", dial_str, err_msg);
-                       return NULL;
-               }
-               if (!cc_record->activated) {
-                       AST_LIST_UNLOCK(&misdn_cc_records_db);
-                       err_msg = "Call completion has not been activated";
-                       ast_log(LOG_WARNING, " --> ! IND : Dial(%s) %s.\n", dial_str, err_msg);
-                       return NULL;
-               }
-               port = cc_record->port;
-               AST_LIST_UNLOCK(&misdn_cc_records_db);
-       }
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-       if (misdn_cfg_is_group_method(group, METHOD_STANDARD_DEC)) {
-               chan_misdn_log(4, port, " --> STARTING STANDARD DEC...\n");
-               dec = 1;
-       }
-
-       if (!ast_strlen_zero(group)) {
-               char cfg_group[BUFFERSIZE + 1];
-               struct robin_list *rr = NULL;
-
-               /* Group dial */
-
-               if (misdn_cfg_is_group_method(group, METHOD_ROUND_ROBIN)) {
-                       chan_misdn_log(4, port, " --> STARTING ROUND ROBIN...\n");
-                       rr = get_robin_position(group);
-               }
-
-               if (rr) {
-                       int port_start;
-                       int bchan_start;
-                       int port_up;
-                       int check;
-                       int maxbchans;
-                       int wraped = 0;
-
-                       if (!rr->port) {
-                               rr->port = misdn_cfg_get_next_port_spin(0);
-                       }
-
-                       if (!rr->channel) {
-                               rr->channel = 1;
-                       }
-
-                       bchan_start = rr->channel;
-                       port_start = rr->port;
-                       do {
-                               misdn_cfg_get(rr->port, MISDN_CFG_GROUPNAME, cfg_group, sizeof(cfg_group));
-                               if (strcasecmp(cfg_group, group)) {
-                                       wraped = 1;
-                                       rr->port = misdn_cfg_get_next_port_spin(rr->port);
-                                       rr->channel = 1;
-                                       continue;
-                               }
-
-                               misdn_cfg_get(rr->port, MISDN_CFG_PMP_L1_CHECK, &check, sizeof(check));
-                               port_up = misdn_lib_port_up(rr->port, check);
-
-                               if (!port_up) {
-                                       chan_misdn_log(1, rr->port, "L1 is not Up on this Port\n");
-                                       rr->port = misdn_cfg_get_next_port_spin(rr->port);
-                                       rr->channel = 1;
-                               } else if (port_up < 0) {
-                                       ast_log(LOG_WARNING, "This port (%d) is blocked\n", rr->port);
-                                       rr->port = misdn_cfg_get_next_port_spin(rr->port);
-                                       rr->channel = 1;
-                               } else {
-                                       chan_misdn_log(4, rr->port, "portup\n");
-                                       maxbchans = misdn_lib_get_maxchans(rr->port);
-
-                                       for (;rr->channel <= maxbchans;rr->channel++) {
-                                               /* ive come full circle and can stop now */
-                                               if (wraped && (rr->port == port_start) && (rr->channel == bchan_start)) {
-                                                       break;
-                                               }
-
-                                               chan_misdn_log(4, rr->port, "Checking channel %d\n",  rr->channel);
-
-                                               if ((newbc = misdn_lib_get_free_bc(rr->port, rr->channel, 0, 0))) {
-                                                       chan_misdn_log(4, rr->port, " Success! Found port:%d channel:%d\n", newbc->port, newbc->channel);
-                                                       rr->channel++;
-                                                       break;
-                                               }
-                                       }
-                                       if (wraped && (rr->port == port_start) && (rr->channel <= bchan_start)) {
-                                               break;
-                                       } else if (!newbc || (rr->channel == maxbchans)) {
-                                               rr->port = misdn_cfg_get_next_port_spin(rr->port);
-                                               rr->channel = 1;
-                                       }
-
-                               }
-                               wraped = 1;
-                       } while (!newbc && (rr->port > 0));
-               } else {
-                       for (port = misdn_cfg_get_next_port(0); port > 0;
-                               port = misdn_cfg_get_next_port(port)) {
-                               misdn_cfg_get(port, MISDN_CFG_GROUPNAME, cfg_group, sizeof(cfg_group));
-
-                               chan_misdn_log(3, port, "Group [%s] Port [%d]\n", group, port);
-                               if (!strcasecmp(cfg_group, group)) {
-                                       int port_up;
-                                       int check;
-
-                                       misdn_cfg_get(port, MISDN_CFG_PMP_L1_CHECK, &check, sizeof(check));
-                                       port_up = misdn_lib_port_up(port, check);
-
-                                       chan_misdn_log(4, port, "portup:%d\n", port_up);
-
-                                       if (port_up > 0) {
-                                               newbc = misdn_lib_get_free_bc(port, 0, 0, dec);
-                                               if (newbc) {
-                                                       break;
-                                               }
-                                       }
-                               }
-                       }
-               }
-
-               /* Group dial failed ?*/
-               if (!newbc) {
-                       ast_log(LOG_WARNING,
-                               "Could not Dial out on group '%s'.\n"
-                               "\tEither the L2 and L1 on all of these ports where DOWN (see 'show application misdn_check_l2l1')\n"
-                               "\tOr there was no free channel on none of the ports\n\n",
-                               group);
-                       return NULL;
-               }
-       } else {
-               /* 'Normal' Port dial * Port dial */
-               if (channel) {
-                       chan_misdn_log(1, port, " --> preselected_channel: %d\n", channel);
-               }
-               newbc = misdn_lib_get_free_bc(port, channel, 0, dec);
-               if (!newbc) {
-                       ast_log(LOG_WARNING, "Could not create channel on port:%d for Dial(%s)\n", port, dial_str);
-                       return NULL;
-               }
-       }
-
-       /* create ast_channel and link all the objects together */
-       cl = chan_list_init(ORG_AST);
-       if (!cl) {
-               misdn_lib_release(newbc);
-               ast_log(LOG_ERROR, "Could not create call record for Dial(%s)\n", dial_str);
-               return NULL;
-       }
-       cl->bc = newbc;
-
-       ast = misdn_new(cl, AST_STATE_RESERVED, args.ext, NULL, cap, assignedids, requestor, port, channel);
-       if (!ast) {
-               chan_list_unref(cl, "Failed to create a new channel");
-               misdn_lib_release(newbc);
-               ast_log(LOG_ERROR, "Could not create Asterisk channel for Dial(%s)\n", dial_str);
-               return NULL;
-       }
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-       cl->record_id = record_id;
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-       /* register chan in local list */
-       cl_queue_chan(cl);
-
-       /* fill in the config into the objects */
-       read_config(cl);
-
-       /* important */
-       cl->need_hangup = 0;
-
-       chan_list_unref(cl, "Successful misdn_request()");
-       return ast;
-}
-
-
-static int misdn_send_text(struct ast_channel *chan, const char *text)
-{
-       struct chan_list *tmp = MISDN_ASTERISK_TECH_PVT(chan);
-
-       if (tmp && tmp->bc) {
-               ast_copy_string(tmp->bc->display, text, sizeof(tmp->bc->display));
-               misdn_lib_send_event(tmp->bc, EVENT_INFORMATION);
-       } else {
-               ast_log(LOG_WARNING, "No chan_list but send_text request?\n");
-               return -1;
-       }
-
-       return 0;
-}
-
-static struct ast_channel_tech misdn_tech = {
-       .type = misdn_type,
-       .description = "Channel driver for mISDN Support (Bri/Pri)",
-       .requester = misdn_request,
-       .send_digit_begin = misdn_digit_begin,
-       .send_digit_end = misdn_digit_end,
-       .call = misdn_call,
-       .hangup = misdn_hangup,
-       .answer = misdn_answer,
-       .read = misdn_read,
-       .write = misdn_write,
-       .indicate = misdn_indication,
-       .fixup = misdn_fixup,
-       .send_text = misdn_send_text,
-       .properties = 0,
-};
-
-
-static int glob_channel = 0;
-
-static void update_name(struct ast_channel *tmp, int port, int c)
-{
-       int chan_offset = 0;
-       int tmp_port = misdn_cfg_get_next_port(0);
-       char newname[255];
-
-       for (; tmp_port > 0; tmp_port = misdn_cfg_get_next_port(tmp_port)) {
-               if (tmp_port == port) {
-                       break;
-               }
-               chan_offset += misdn_lib_port_is_pri(tmp_port) ? 30 : 2;
-       }
-       if (c < 0) {
-               c = 0;
-       }
-
-       snprintf(newname, sizeof(newname), "%s/%d-", misdn_type, chan_offset + c);
-       if (strncmp(ast_channel_name(tmp), newname, strlen(newname))) {
-               snprintf(newname, sizeof(newname), "%s/%d-u%d", misdn_type, chan_offset + c, glob_channel++);
-               ast_change_name(tmp, newname);
-               chan_misdn_log(3, port, " --> updating channel name to [%s]\n", ast_channel_name(tmp));
-       }
-}
-
-static struct ast_channel *misdn_new(struct chan_list *chlist, int state,  char *exten, char *callerid, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, int port, int c)
-{
-       struct ast_format_cap *native;
-       struct ast_channel *tmp;
-       char *cid_name = NULL;
-       char *cid_num = NULL;
-       int chan_offset = 0;
-       int tmp_port = misdn_cfg_get_next_port(0);
-       struct ast_format *tmpfmt;
-
-       native = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
-       if (!native) {
-               return NULL;
-       }
-
-       for (; tmp_port > 0; tmp_port = misdn_cfg_get_next_port(tmp_port)) {
-               if (tmp_port == port) {
-                       break;
-               }
-               chan_offset += misdn_lib_port_is_pri(tmp_port) ? 30 : 2;
-       }
-       if (c < 0) {
-               c = 0;
-       }
-
-       if (callerid) {
-               ast_callerid_parse(callerid, &cid_name, &cid_num);
-       }
-
-       tmp = ast_channel_alloc(1, state, cid_num, cid_name, "", exten, "", assignedids, requestor, 0, "%s/%s%d-u%d", misdn_type, c ? "" : "tmp", chan_offset + c, glob_channel++);
-       if (tmp) {
-               chan_misdn_log(2, port, " --> * NEW CHANNEL dialed:%s caller:%s\n", exten, callerid);
-
-               tmpfmt = ast_format_cap_get_format(cap, 0);
-               ast_format_cap_append(native, ast_format_alaw, 0);
-               ast_channel_nativeformats_set(tmp, native);
-               ast_channel_set_writeformat(tmp, tmpfmt);
-               ast_channel_set_rawwriteformat(tmp, tmpfmt);
-               ast_channel_set_readformat(tmp, tmpfmt);
-               ast_channel_set_rawreadformat(tmp, tmpfmt);
-
-               ao2_ref(tmpfmt, -1);
-
-               /* Link the channel and private together */
-               chan_list_ref(chlist, "Give a reference to ast_channel");
-               MISDN_ASTERISK_TECH_PVT_SET(tmp, chlist);
-               chlist->ast = tmp;
-
-               ast_channel_tech_set(tmp, &misdn_tech);
-
-               ast_channel_priority_set(tmp, 1);
-
-               if (exten) {
-                       ast_channel_exten_set(tmp, exten);
-               } else {
-                       chan_misdn_log(1, 0, "misdn_new: no exten given.\n");
-               }
-
-               if (!ast_strlen_zero(cid_num)) {
-                       /* Don't use ast_set_callerid() here because it will
-                        * generate a needless NewCallerID event */
-                       ast_channel_caller(tmp)->ani.number.valid = 1;
-                       ast_channel_caller(tmp)->ani.number.str = ast_strdup(cid_num);
-               }
-
-               if (pipe(chlist->pipe) < 0) {
-                       ast_log(LOG_ERROR, "Pipe failed\n");
-               }
-               ast_channel_set_fd(tmp, 0, chlist->pipe[0]);
-
-               ast_channel_rings_set(tmp, (state == AST_STATE_RING) ? 1 : 0);
-
-               ast_jb_configure(tmp, misdn_get_global_jbconf());
-
-               ast_channel_unlock(tmp);
-       } else {
-               chan_misdn_log(-1, 0, "Unable to allocate channel structure\n");
-       }
-
-       ao2_ref(native, -1);
-
-       return tmp;
-}
-
-/*! Returns a reference to the found chan_list. */
-static struct chan_list *find_chan_by_bc(struct misdn_bchannel *bc)
-{
-       struct chan_list *help;
-
-       ast_mutex_lock(&cl_te_lock);
-       for (help = cl_te; help; help = help->next) {
-               if (help->bc == bc) {
-                       chan_list_ref(help, "Found chan_list by bc");
-                       ast_mutex_unlock(&cl_te_lock);
-                       return help;
-               }
-       }
-       ast_mutex_unlock(&cl_te_lock);
-
-       chan_misdn_log(6, bc->port,
-               "$$$ find_chan_by_bc: No channel found for dialed:%s caller:\"%s\" <%s>\n",
-               bc->dialed.number,
-               bc->caller.name,
-               bc->caller.number);
-
-       return NULL;
-}
-
-/*! Returns a reference to the found chan_list. */
-static struct chan_list *find_hold_call(struct misdn_bchannel *bc)
-{
-       struct chan_list *help;
-
-       if (bc->pri) {
-               return NULL;
-       }
-
-       chan_misdn_log(6, bc->port, "$$$ find_hold_call: channel:%d dialed:%s caller:\"%s\" <%s>\n",
-               bc->channel,
-               bc->dialed.number,
-               bc->caller.name,
-               bc->caller.number);
-       ast_mutex_lock(&cl_te_lock);
-       for (help = cl_te; help; help = help->next) {
-               chan_misdn_log(4, bc->port, "$$$ find_hold_call: --> hold:%d channel:%d\n", help->hold.state, help->hold.channel);
-               if (help->hold.state == MISDN_HOLD_ACTIVE && help->hold.port == bc->port) {
-                       chan_list_ref(help, "Found chan_list hold call");
-                       ast_mutex_unlock(&cl_te_lock);
-                       return help;
-               }
-       }
-       ast_mutex_unlock(&cl_te_lock);
-       chan_misdn_log(6, bc->port,
-               "$$$ find_hold_call: No channel found for dialed:%s caller:\"%s\" <%s>\n",
-               bc->dialed.number,
-               bc->caller.name,
-               bc->caller.number);
-
-       return NULL;
-}
-
-
-/*! Returns a reference to the found chan_list. */
-static struct chan_list *find_hold_call_l3(unsigned long l3_id)
-{
-       struct chan_list *help;
-
-       ast_mutex_lock(&cl_te_lock);
-       for (help = cl_te; help; help = help->next) {
-               if (help->hold.state != MISDN_HOLD_IDLE && help->l3id == l3_id) {
-                       chan_list_ref(help, "Found chan_list hold call l3");
-                       ast_mutex_unlock(&cl_te_lock);
-                       return help;
-               }
-       }
-       ast_mutex_unlock(&cl_te_lock);
-
-       return NULL;
-}
-
-#define TRANSFER_ON_HELD_CALL_HANGUP 1
-#if defined(TRANSFER_ON_HELD_CALL_HANGUP)
-/*!
- * \internal
- * \brief Find a suitable active call to go with a held call so we could try a transfer.
- *
- * \param bc B channel record.
- *
- * \return Found call record or NULL.
- *
- * \note Returns a reference to the found chan_list.
- *
- * \note There could be a possibility where we find the wrong active call to transfer.
- * This concern is mitigated by the fact that there could be at most one other call
- * on a PTMP BRI link to another device.  Maybe the l3_id could help in locating an
- * active call on the same TEI?
- */
-static struct chan_list *find_hold_active_call(struct misdn_bchannel *bc)
-{
-       struct chan_list *list;
-
-       ast_mutex_lock(&cl_te_lock);
-       for (list = cl_te; list; list = list->next) {
-               if (list->hold.state == MISDN_HOLD_IDLE && list->bc && list->bc->port == bc->port
-                       && list->ast) {
-                       switch (list->state) {
-                       case MISDN_PROCEEDING:
-                       case MISDN_PROGRESS:
-                       case MISDN_ALERTING:
-                       case MISDN_CONNECTED:
-                               chan_list_ref(list, "Found chan_list hold active call");
-                               ast_mutex_unlock(&cl_te_lock);
-                               return list;
-                       default:
-                               break;
-                       }
-               }
-       }
-       ast_mutex_unlock(&cl_te_lock);
-       return NULL;
-}
-#endif /* defined(TRANSFER_ON_HELD_CALL_HANGUP) */
-
-static void cl_queue_chan(struct chan_list *chan)
-{
-       chan_misdn_log(4, chan->bc ? chan->bc->port : 0, "* Queuing chan %p\n", chan);
-
-       chan_list_ref(chan, "Adding chan_list to list");
-       ast_mutex_lock(&cl_te_lock);
-       chan->next = NULL;
-       if (!cl_te) {
-               /* List is empty, make head of list. */
-               cl_te = chan;
-       } else {
-               struct chan_list *help;
-
-               /* Put at end of list. */
-               for (help = cl_te; help->next; help = help->next) {
-               }
-               help->next = chan;
-       }
-       ast_mutex_unlock(&cl_te_lock);
-}
-
-static int cl_dequeue_chan(struct chan_list *chan)
-{
-       int found_it;
-       struct chan_list *help;
-
-       ast_mutex_lock(&cl_te_lock);
-       if (!cl_te) {
-               /* List is empty. */
-               ast_mutex_unlock(&cl_te_lock);
-               return 0;
-       }
-
-       if (cl_te == chan) {
-               /* What we want is the head of the list. */
-               cl_te = cl_te->next;
-               ast_mutex_unlock(&cl_te_lock);
-               chan_list_unref(chan, "Removed chan_list from list head");
-               return 1;
-       }
-
-       found_it = 0;
-       for (help = cl_te; help->next; help = help->next) {
-               if (help->next == chan) {
-                       /* Found it in the list. */
-                       help->next = help->next->next;
-                       found_it = 1;
-                       break;
-               }
-       }
-
-       ast_mutex_unlock(&cl_te_lock);
-       if (found_it) {
-               chan_list_unref(chan, "Removed chan_list from list");
-       }
-       return found_it;
-}
-
-/** Channel Queue End **/
-
-
-static int pbx_start_chan(struct chan_list *ch)
-{
-       int ret = ast_pbx_start(ch->ast);
-
-       ch->need_hangup = (ret >= 0) ? 0 : 1;
-
-       return ret;
-}
-
-static void hangup_chan(struct chan_list *ch, struct misdn_bchannel *bc)
-{
-       int port = bc->port;
-
-       if (!ch) {
-               cb_log(1, port, "Cannot hangup chan, no ch\n");
-               return;
-       }
-
-       cb_log(5, port, "hangup_chan called\n");
-
-       if (ch->need_hangup) {
-               cb_log(2, port, " --> hangup\n");
-               ch->need_hangup = 0;
-               ch->need_queue_hangup = 0;
-               if (ch->ast && send_cause2ast(ch->ast, bc, ch)) {
-                       ast_hangup(ch->ast);
-               }
-               return;
-       }
-
-       if (!ch->need_queue_hangup) {
-               cb_log(2, port, " --> No need to queue hangup\n");
-               return;
-       }
-
-       ch->need_queue_hangup = 0;
-       if (ch->ast) {
-               if (send_cause2ast(ch->ast, bc, ch)) {
-                       ast_queue_hangup_with_cause(ch->ast, bc->cause);
-                       cb_log(2, port, " --> queue_hangup\n");
-               }
-       } else {
-               cb_log(1, port, "Cannot hangup chan, no ast\n");
-       }
-}
-
-/*!
- * \internal
- * \brief ISDN asked us to release channel, pendant to misdn_hangup.
- *
- * \param ch Call channel record to release.
- * \param bc Current B channel record associated with ch.
- *
- * \return Nothing
- *
- * \note The only valid thing to do with ch after calling is to chan_list_unref(ch, "").
- */
-static void release_chan(struct chan_list *ch, struct misdn_bchannel *bc)
-{
-       struct ast_channel *ast;
-
-       chan_misdn_log(5, bc->port, "release_chan: bc with pid:%d l3id: %x\n", bc->pid, bc->l3_id);
-
-       ast_mutex_lock(&release_lock);
-       for (;;) {
-               ast = ch->ast;
-               if (!ast || !ast_channel_trylock(ast)) {
-                       break;
-               }
-               DEADLOCK_AVOIDANCE(&release_lock);
-       }
-       if (!cl_dequeue_chan(ch)) {
-               /* Someone already released it. */
-               if (ast) {
-                       ast_channel_unlock(ast);
-               }
-               ast_mutex_unlock(&release_lock);
-               return;
-       }
-       ch->state = MISDN_CLEANING;
-       ch->ast = NULL;
-       if (ast) {
-               struct chan_list *ast_ch;
-
-               ast_ch = MISDN_ASTERISK_TECH_PVT(ast);
-               MISDN_ASTERISK_TECH_PVT_SET(ast, NULL);
-               chan_misdn_log(1, bc->port,
-                       "* RELEASING CHANNEL pid:%d context:%s dialed:%s caller:\"%s\" <%s>\n",
-                       bc->pid,
-                       ast_channel_context(ast),
-                       ast_channel_exten(ast),
-                       S_COR(ast_channel_caller(ast)->id.name.valid, ast_channel_caller(ast)->id.name.str, ""),
-                       S_COR(ast_channel_caller(ast)->id.number.valid, ast_channel_caller(ast)->id.number.str, ""));
-
-               if (ast_channel_state(ast) != AST_STATE_RESERVED) {
-                       chan_misdn_log(3, bc->port, " --> Setting AST State to down\n");
-                       ast_setstate(ast, AST_STATE_DOWN);
-               }
-               ast_channel_unlock(ast);
-               if (ast_ch) {
-                       chan_list_unref(ast_ch, "Release ast_channel reference.");
-               }
-       }
-
-       if (ch->originator == ORG_AST) {
-               --misdn_out_calls[bc->port];
-       } else {
-               --misdn_in_calls[bc->port];
-       }
-
-       ast_mutex_unlock(&release_lock);
-}
-
-/*!
- * \internal
- * \brief Do everything in release_chan() that makes sense without a bc.
- *
- * \param ch Call channel record to release.
- *
- * \return Nothing
- *
- * \note The only valid thing to do with ch after calling is to chan_list_unref(ch, "").
- */
-static void release_chan_early(struct chan_list *ch)
-{
-       struct ast_channel *ast;
-
-       ast_mutex_lock(&release_lock);
-       for (;;) {
-               ast = ch->ast;
-               if (!ast || !ast_channel_trylock(ast)) {
-                       break;
-               }
-               DEADLOCK_AVOIDANCE(&release_lock);
-       }
-       if (!cl_dequeue_chan(ch)) {
-               /* Someone already released it. */
-               if (ast) {
-                       ast_channel_unlock(ast);
-               }
-               ast_mutex_unlock(&release_lock);
-               return;
-       }
-       ch->state = MISDN_CLEANING;
-       ch->ast = NULL;
-       if (ast) {
-               struct chan_list *ast_ch;
-
-               ast_ch = MISDN_ASTERISK_TECH_PVT(ast);
-               MISDN_ASTERISK_TECH_PVT_SET(ast, NULL);
-
-               if (ast_channel_state(ast) != AST_STATE_RESERVED) {
-                       ast_setstate(ast, AST_STATE_DOWN);
-               }
-               ast_channel_unlock(ast);
-               if (ast_ch) {
-                       chan_list_unref(ast_ch, "Release ast_channel reference.");
-               }
-       }
-
-       if (ch->hold.state != MISDN_HOLD_IDLE) {
-               if (ch->originator == ORG_AST) {
-                       --misdn_out_calls[ch->hold.port];
-               } else {
-                       --misdn_in_calls[ch->hold.port];
-               }
-       }
-
-       ast_mutex_unlock(&release_lock);
-}
-
-/*!
- * \internal
- * \brief Attempt to transfer the active channel party to the held channel party.
- *
- * \param active_ch Channel currently connected.
- * \param held_ch Channel currently on hold.
- *
- * \retval 0 on success.
- * \retval -1 on error.
- */
-static int misdn_attempt_transfer(struct chan_list *active_ch, struct chan_list *held_ch)
-{
-       int retval;
-       enum ast_transfer_result xfer_res;
-       struct ast_channel *to_target;
-       struct ast_channel *to_transferee;
-
-       switch (active_ch->state) {
-       case MISDN_PROCEEDING:
-       case MISDN_PROGRESS:
-       case MISDN_ALERTING:
-       case MISDN_CONNECTED:
-               break;
-       default:
-               return -1;
-       }
-
-       ast_channel_lock_both(held_ch->ast, active_ch->ast);
-       to_target = active_ch->ast;
-       to_transferee = held_ch->ast;
-       chan_misdn_log(1, held_ch->hold.port, "TRANSFERRING %s to %s\n",
-               ast_channel_name(to_transferee), ast_channel_name(to_target));
-       held_ch->hold.state = MISDN_HOLD_TRANSFER;
-       ast_channel_ref(to_target);
-       ast_channel_ref(to_transferee);
-       ast_channel_unlock(to_target);
-       ast_channel_unlock(to_transferee);
-
-       retval = 0;
-       xfer_res = ast_bridge_transfer_attended(to_transferee, to_target);
-       if (xfer_res != AST_BRIDGE_TRANSFER_SUCCESS) {
-               retval = -1;
-       }
-
-       ast_channel_unref(to_target);
-       ast_channel_unref(to_transferee);
-       return retval;
-}
-
-
-static void do_immediate_setup(struct misdn_bchannel *bc, struct chan_list *ch, struct ast_channel *ast)
-{
-       char *predial;
-       struct ast_frame fr;
-
-       predial = ast_strdupa(ast_channel_exten(ast));
-
-       ch->state = MISDN_DIALING;
-
-       if (!ch->noautorespond_on_setup) {
-               if (bc->nt) {
-                       misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE);
-               } else {
-                       if (misdn_lib_is_ptp(bc->port)) {
-                               misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE);
-                       } else {
-                               misdn_lib_send_event(bc, EVENT_PROCEEDING);
-                       }
-               }
-       } else {
-               ch->state = MISDN_INCOMING_SETUP;
-       }
-
-       chan_misdn_log(1, bc->port,
-               "* Starting Ast context:%s dialed:%s caller:\"%s\" <%s> with 's' extension\n",
-               ast_channel_context(ast),
-               ast_channel_exten(ast),
-               (ast_channel_caller(ast)->id.name.valid && ast_channel_caller(ast)->id.name.str)
-                       ? ast_channel_caller(ast)->id.name.str : "",
-               (ast_channel_caller(ast)->id.number.valid && ast_channel_caller(ast)->id.number.str)
-                       ? ast_channel_caller(ast)->id.number.str : "");
-
-       ast_channel_exten_set(ast, "s");
-
-       if (!ast_canmatch_extension(ast, ast_channel_context(ast), ast_channel_exten(ast), 1, bc->caller.number) || pbx_start_chan(ch) < 0) {
-               ast = NULL;
-               bc->out_cause = AST_CAUSE_UNALLOCATED;
-               hangup_chan(ch, bc);
-               hanguptone_indicate(ch);
-
-               misdn_lib_send_event(bc, bc->nt ? EVENT_RELEASE_COMPLETE : EVENT_DISCONNECT);
-       }
-
-
-       while (!ast_strlen_zero(predial)) {
-               fr.frametype = AST_FRAME_DTMF;
-               fr.subclass.integer = *predial;
-               fr.src = NULL;
-               fr.data.ptr = NULL;
-               fr.datalen = 0;
-               fr.samples = 0;
-               fr.mallocd = 0;
-               fr.offset = 0;
-               fr.delivery = ast_tv(0,0);
-
-               if (ch->ast && MISDN_ASTERISK_TECH_PVT(ch->ast)) {
-                       ast_queue_frame(ch->ast, &fr);
-               }
-               predial++;
-       }
-}
-
-/*!
- * \retval -1 if can hangup after calling.
- * \retval 0 if cannot hangup after calling.
- */
-static int send_cause2ast(struct ast_channel *ast, struct misdn_bchannel *bc, struct chan_list *ch)
-{
-       int can_hangup;
-
-       if (!ast) {
-               chan_misdn_log(1, 0, "send_cause2ast: No Ast\n");
-               return 0;
-       }
-       if (!bc) {
-               chan_misdn_log(1, 0, "send_cause2ast: No BC\n");
-               return 0;
-       }
-       if (!ch) {
-               chan_misdn_log(1, 0, "send_cause2ast: No Ch\n");
-               return 0;
-       }
-
-       ast_channel_hangupcause_set(ast, bc->cause);
-
-       can_hangup = -1;
-       switch (bc->cause) {
-       case AST_CAUSE_UNALLOCATED:
-       case AST_CAUSE_NO_ROUTE_TRANSIT_NET:
-       case AST_CAUSE_NO_ROUTE_DESTINATION:
-       case 4: /* Send special information tone */
-       case AST_CAUSE_NUMBER_CHANGED:
-       case AST_CAUSE_DESTINATION_OUT_OF_ORDER:
-               /* Congestion Cases */
-               /*
-                * Not Queueing the Congestion anymore, since we want to hear
-                * the inband message
-                *
-               chan_misdn_log(1, bc ? bc->port : 0, " --> * SEND: Queue Congestion pid:%d\n", bc ? bc->pid : -1);
-               ch->state = MISDN_BUSY;
-
-               ast_queue_control(ast, AST_CONTROL_CONGESTION);
-               */
-               break;
-
-       case AST_CAUSE_CALL_REJECTED:
-       case AST_CAUSE_USER_BUSY:
-               ch->state = MISDN_BUSY;
-
-               if (!ch->need_busy) {
-                       chan_misdn_log(1, bc ? bc->port : 0, "Queued busy already\n");
-                       break;
-               }
-               ch->need_busy = 0;
-
-               chan_misdn_log(1, bc ? bc->port : 0, " --> * SEND: Queue Busy pid:%d\n", bc ? bc->pid : -1);
-               ast_queue_control(ast, AST_CONTROL_BUSY);
-
-               /* The BUSY is likely to cause a hangup or the user needs to hear it. */
-               can_hangup = 0;
-               break;
-       }
-       return can_hangup;
-}
-
-
-/*! \brief Import parameters from the dialplan environment variables */
-void import_ch(struct ast_channel *chan, struct misdn_bchannel *bc, struct chan_list *ch)
-{
-       const char *tmp;
-
-       ast_channel_lock(chan);
-       tmp = pbx_builtin_getvar_helper(chan, "MISDN_ADDRESS_COMPLETE");
-       if (tmp && (atoi(tmp) == 1)) {
-               bc->sending_complete = 1;
-       }
-
-       tmp = pbx_builtin_getvar_helper(chan, "MISDN_USERUSER");
-       if (tmp) {
-               ast_log(LOG_NOTICE, "MISDN_USERUSER: %s\n", tmp);
-               ast_copy_string(bc->uu, tmp, sizeof(bc->uu));
-               bc->uulen = strlen(bc->uu);
-       }
-
-       tmp = pbx_builtin_getvar_helper(chan, "MISDN_KEYPAD");
-       if (tmp) {
-               ast_copy_string(bc->keypad, tmp, sizeof(bc->keypad));
-       }
-       ast_channel_unlock(chan);
-}
-
-/*! \brief Export parameters to the dialplan environment variables */
-void export_ch(struct ast_channel *chan, struct misdn_bchannel *bc, struct chan_list *ch)
-{
-       char tmp[32];
-
-       /*
-        * The only use for MISDN_PID is if there is a problem and you
-        * have to use the "misdn restart pid" CLI command.  Otherwise,
-        * the pid is not used by anyone.  The internal use of MISDN_PID
-        * has been deleted.
-        */
-       chan_misdn_log(3, bc->port, " --> EXPORT_PID: pid:%d\n", bc->pid);
-       snprintf(tmp, sizeof(tmp), "%d", bc->pid);
-       pbx_builtin_setvar_helper(chan, "_MISDN_PID", tmp);
-
-       if (bc->sending_complete) {
-               snprintf(tmp, sizeof(tmp), "%d", bc->sending_complete);
-               pbx_builtin_setvar_helper(chan, "MISDN_ADDRESS_COMPLETE", tmp);
-       }
-
-       if (bc->urate) {
-               snprintf(tmp, sizeof(tmp), "%d", bc->urate);
-               pbx_builtin_setvar_helper(chan, "MISDN_URATE", tmp);
-       }
-
-       if (bc->uulen) {
-               pbx_builtin_setvar_helper(chan, "MISDN_USERUSER", bc->uu);
-       }
-
-       if (!ast_strlen_zero(bc->keypad)) {
-               pbx_builtin_setvar_helper(chan, "MISDN_KEYPAD", bc->keypad);
-       }
-}
-
-int add_in_calls(int port)
-{
-       int max_in_calls;
-
-       misdn_cfg_get(port, MISDN_CFG_MAX_IN, &max_in_calls, sizeof(max_in_calls));
-       misdn_in_calls[port]++;
-
-       if (max_in_calls >= 0 && max_in_calls < misdn_in_calls[port]) {
-               ast_log(LOG_NOTICE, "Marking Incoming Call on port[%d]\n", port);
-               return misdn_in_calls[port] - max_in_calls;
-       }
-
-       return 0;
-}
-
-int add_out_calls(int port)
-{
-       int max_out_calls;
-
-       misdn_cfg_get(port, MISDN_CFG_MAX_OUT, &max_out_calls, sizeof(max_out_calls));
-
-       if (max_out_calls >= 0 && max_out_calls <= misdn_out_calls[port]) {
-               ast_log(LOG_NOTICE, "Rejecting Outgoing Call on port[%d]\n", port);
-               return (misdn_out_calls[port] + 1) - max_out_calls;
-       }
-
-       misdn_out_calls[port]++;
-
-       return 0;
-}
-
-static void start_pbx(struct chan_list *ch, struct misdn_bchannel *bc, struct ast_channel *chan)
-{
-       if (pbx_start_chan(ch) < 0) {
-               hangup_chan(ch, bc);
-               chan_misdn_log(-1, bc->port, "ast_pbx_start returned <0 in SETUP\n");
-               if (bc->nt) {
-                       hanguptone_indicate(ch);
-                       misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE);
-               } else {
-                       misdn_lib_send_event(bc, EVENT_RELEASE);
-               }
-       }
-}
-
-static void wait_for_digits(struct chan_list *ch, struct misdn_bchannel *bc, struct ast_channel *chan)
-{
-       ch->state = MISDN_WAITING4DIGS;
-       misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE);
-       if (bc->nt && !bc->dialed.number[0]) {
-               dialtone_indicate(ch);
-       }
-}
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-/*!
- * \internal
- * \brief Handle the FACILITY CCBSStatusRequest message.
- *
- * \param port Logical port number.
- * \param facility Facility ie contents.
- *
- * \return Nothing
- */
-static void misdn_cc_handle_ccbs_status_request(int port, const struct FacParm *facility)
-{
-       struct misdn_cc_record *cc_record;
-       struct misdn_bchannel dummy;
-
-       switch (facility->u.CCBSStatusRequest.ComponentType) {
-       case FacComponent_Invoke:
-               /* Build message */
-               misdn_make_dummy(&dummy, port, 0, misdn_lib_port_is_nt(port), 0);
-               dummy.fac_out.Function = Fac_CCBSStatusRequest;
-               dummy.fac_out.u.CCBSStatusRequest.InvokeID = facility->u.CCBSStatusRequest.InvokeID;
-               dummy.fac_out.u.CCBSStatusRequest.ComponentType = FacComponent_Result;
-
-               /* Answer User-A free question */
-               AST_LIST_LOCK(&misdn_cc_records_db);
-               cc_record = misdn_cc_find_by_reference(port, facility->u.CCBSStatusRequest.Component.Invoke.CCBSReference);
-               if (cc_record) {
-                       dummy.fac_out.u.CCBSStatusRequest.Component.Result.Free = cc_record->party_a_free;
-               } else {
-                       /* No record so say User-A is free */
-                       dummy.fac_out.u.CCBSStatusRequest.Component.Result.Free = 1;
-               }
-               AST_LIST_UNLOCK(&misdn_cc_records_db);
-
-               /* Send message */
-               print_facility(&dummy.fac_out, &dummy);
-               misdn_lib_send_event(&dummy, EVENT_FACILITY);
-               break;
-
-       default:
-               chan_misdn_log(0, port, " --> not yet handled: facility type:0x%04X\n", facility->Function);
-               break;
-       }
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-/*!
- * \internal
- * \brief Start a PBX to notify that User-B is available.
- *
- * \param record_id Call completion record ID
- * \param notify Dialplan location to start processing.
- *
- * \return Nothing
- */
-static void misdn_cc_pbx_notify(long record_id, const struct misdn_cc_notify *notify)
-{
-       struct ast_channel *chan;
-       char id_str[32];
-
-       static unsigned short sequence = 0;
-
-       /* Create a channel to notify with */
-       snprintf(id_str, sizeof(id_str), "%ld", record_id);
-       chan = ast_channel_alloc(0, AST_STATE_DOWN, id_str, NULL, NULL,
-               notify->exten, notify->context, NULL, 0,
-               "mISDN-CC/%ld-%X", record_id, (unsigned) ++sequence);
-       if (!chan) {
-               ast_log(LOG_ERROR, "Unable to allocate channel!\n");
-               return;
-       }
-       ast_channel_priority_set(chan, notify->priority);
-       ast_free(ast_channel_dialed(chan)->number.str);
-       ast_channel_dialed(chan)->number.str = ast_strdup(notify->exten);
-
-       ast_channel_unlock(chan);
-
-       if (ast_pbx_start(chan)) {
-               ast_log(LOG_WARNING, "Unable to start pbx channel %s!\n", ast_channel_name(chan));
-               ast_channel_release(chan);
-       } else {
-               ast_verb(1, "Started pbx for call completion notify channel %s\n", ast_channel_name(chan));
-       }
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-/*!
- * \internal
- * \brief Handle the FACILITY CCBS_T_RemoteUserFree message.
- *
- * \param bc B channel control structure message came in on
- *
- * \return Nothing
- */
-static void misdn_cc_handle_T_remote_user_free(struct misdn_bchannel *bc)
-{
-       struct misdn_cc_record *cc_record;
-       struct misdn_cc_notify notify;
-       long record_id;
-
-       AST_LIST_LOCK(&misdn_cc_records_db);
-       cc_record = misdn_cc_find_by_bc(bc);
-       if (cc_record) {
-               if (cc_record->party_a_free) {
-                       notify = cc_record->remote_user_free;
-               } else {
-                       /* Send CCBS_T_Suspend message */
-                       bc->fac_out.Function = Fac_CCBS_T_Suspend;
-                       bc->fac_out.u.CCBS_T_Suspend.InvokeID = ++misdn_invoke_id;
-                       print_facility(&bc->fac_out, bc);
-                       misdn_lib_send_event(bc, EVENT_FACILITY);
-
-                       notify = cc_record->b_free;
-               }
-               record_id = cc_record->record_id;
-               AST_LIST_UNLOCK(&misdn_cc_records_db);
-               if (notify.context[0]) {
-                       /* Party A is free or B-Free notify has been setup. */
-                       misdn_cc_pbx_notify(record_id, &notify);
-               }
-       } else {
-               AST_LIST_UNLOCK(&misdn_cc_records_db);
-       }
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-/*!
- * \internal
- * \brief Handle the FACILITY CCBSRemoteUserFree message.
- *
- * \param port Logical port number.
- * \param facility Facility ie contents.
- *
- * \return Nothing
- */
-static void misdn_cc_handle_remote_user_free(int port, const struct FacParm *facility)
-{
-       struct misdn_cc_record *cc_record;
-       struct misdn_cc_notify notify;
-       long record_id;
-
-       AST_LIST_LOCK(&misdn_cc_records_db);
-       cc_record = misdn_cc_find_by_reference(port, facility->u.CCBSRemoteUserFree.CCBSReference);
-       if (cc_record) {
-               notify = cc_record->remote_user_free;
-               record_id = cc_record->record_id;
-               AST_LIST_UNLOCK(&misdn_cc_records_db);
-               misdn_cc_pbx_notify(record_id, &notify);
-       } else {
-               AST_LIST_UNLOCK(&misdn_cc_records_db);
-       }
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-/*!
- * \internal
- * \brief Handle the FACILITY CCBSBFree message.
- *
- * \param port Logical port number.
- * \param facility Facility ie contents.
- *
- * \return Nothing
- */
-static void misdn_cc_handle_b_free(int port, const struct FacParm *facility)
-{
-       struct misdn_cc_record *cc_record;
-       struct misdn_cc_notify notify;
-       long record_id;
-
-       AST_LIST_LOCK(&misdn_cc_records_db);
-       cc_record = misdn_cc_find_by_reference(port, facility->u.CCBSBFree.CCBSReference);
-       if (cc_record && cc_record->b_free.context[0]) {
-               /* B-Free notify has been setup. */
-               notify = cc_record->b_free;
-               record_id = cc_record->record_id;
-               AST_LIST_UNLOCK(&misdn_cc_records_db);
-               misdn_cc_pbx_notify(record_id, &notify);
-       } else {
-               AST_LIST_UNLOCK(&misdn_cc_records_db);
-       }
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-/*!
- * \internal
- * \brief Handle the incoming facility ie contents
- *
- * \param event Message type facility ie came in on
- * \param bc B channel control structure message came in on
- * \param ch Associated channel call record
- *
- * \return Nothing
- */
-static void misdn_facility_ie_handler(enum event_e event, struct misdn_bchannel *bc, struct chan_list *ch)
-{
-#if defined(AST_MISDN_ENHANCEMENTS)
-       const char *diagnostic_msg;
-       struct misdn_cc_record *cc_record;
-       char buf[32];
-       struct misdn_party_id party_id;
-       long new_record_id;
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-       print_facility(&bc->fac_in, bc);
-       switch (bc->fac_in.Function) {
-#if defined(AST_MISDN_ENHANCEMENTS)
-       case Fac_ActivationDiversion:
-               switch (bc->fac_in.u.ActivationDiversion.ComponentType) {
-               case FacComponent_Result:
-                       /* Positive ACK to activation */
-                       /* We don't handle this yet */
-                       break;
-               default:
-                       chan_misdn_log(0, bc->port," --> not yet handled: facility type:0x%04X\n",
-                               bc->fac_in.Function);
-                       break;
-               }
-               break;
-       case Fac_DeactivationDiversion:
-               switch (bc->fac_in.u.DeactivationDiversion.ComponentType) {
-               case FacComponent_Result:
-                       /* Positive ACK to deactivation */
-                       /* We don't handle this yet */
-                       break;
-               default:
-                       chan_misdn_log(0, bc->port," --> not yet handled: facility type:0x%04X\n",
-                               bc->fac_in.Function);
-                       break;
-               }
-               break;
-       case Fac_ActivationStatusNotificationDiv:
-               /* Sent to other MSN numbers on the line when a user activates call forwarding. */
-               /* Sent in the first call control message of an outgoing call from the served user. */
-               /* We do not have anything to do for this message. */
-               break;
-       case Fac_DeactivationStatusNotificationDiv:
-               /* Sent to other MSN numbers on the line when a user deactivates call forwarding. */
-               /* We do not have anything to do for this message. */
-               break;
-#if 0  /* We don't handle this yet */
-       case Fac_InterrogationDiversion:
-               /* We don't handle this yet */
-               break;
-       case Fac_InterrogateServedUserNumbers:
-               /* We don't handle this yet */
-               break;
-#endif /* We don't handle this yet */
-       case Fac_DiversionInformation:
-               /* Sent to the served user when a call is forwarded. */
-               /* We do not have anything to do for this message. */
-               break;
-       case Fac_CallDeflection:
-               if (ch && ch->ast) {
-                       switch (bc->fac_in.u.CallDeflection.ComponentType) {
-                       case FacComponent_Invoke:
-                               ast_copy_string(bc->redirecting.from.number, bc->dialed.number,
-                                       sizeof(bc->redirecting.from.number));
-                               bc->redirecting.from.name[0] = 0;
-                               bc->redirecting.from.number_plan = bc->dialed.number_plan;
-                               bc->redirecting.from.number_type = bc->dialed.number_type;
-                               bc->redirecting.from.screening = 0;/* Unscreened */
-                               if (bc->fac_in.u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUserPresent) {
-                                       bc->redirecting.from.presentation =
-                                               bc->fac_in.u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUser
-                                               ? 0 /* Allowed */ : 1 /* Restricted */;
-                               } else {
-                                       bc->redirecting.from.presentation = 0;/* Allowed */
-                               }
-
-                               /* Add configured prefix to the call deflection number */
-                               memset(&party_id, 0, sizeof(party_id));
-                               misdn_PartyNumber_extract(&party_id,
-                                       &bc->fac_in.u.CallDeflection.Component.Invoke.Deflection.Party);
-                               misdn_add_number_prefix(bc->port, party_id.number_type,
-                                       party_id.number, sizeof(party_id.number));
-                               //party_id.presentation = 0;/* Allowed */
-                               //party_id.screening = 0;/* Unscreened */
-                               bc->redirecting.to = party_id;
-
-                               ++bc->redirecting.count;
-                               bc->redirecting.reason = mISDN_REDIRECTING_REASON_DEFLECTION;
-
-                               misdn_copy_redirecting_to_ast(ch->ast, &bc->redirecting, bc->incoming_cid_tag);
-                               ast_channel_call_forward_set(ch->ast, bc->redirecting.to.number);
-
-                               /* Send back positive ACK */
-#if 1
-                               /*
-                                * Since there are no return result arguments it must be a
-                                * generic result message.  ETSI 300-196
-                                */
-                               bc->fac_out.Function = Fac_RESULT;
-                               bc->fac_out.u.RESULT.InvokeID = bc->fac_in.u.CallDeflection.InvokeID;
-#else
-                               bc->fac_out.Function = Fac_CallDeflection;
-                               bc->fac_out.u.CallDeflection.InvokeID = bc->fac_in.u.CallDeflection.InvokeID;
-                               bc->fac_out.u.CallDeflection.ComponentType = FacComponent_Result;
-#endif
-                               print_facility(&bc->fac_out, bc);
-                               misdn_lib_send_event(bc, EVENT_DISCONNECT);
-
-                               /* This line is BUSY to further attempts by this dialing attempt. */
-                               ast_queue_control(ch->ast, AST_CONTROL_BUSY);
-                               break;
-
-                       case FacComponent_Result:
-                               /* Positive ACK to call deflection */
-                               /*
-                                * Sent in DISCONNECT or FACILITY message depending upon network option.
-                                * It is in the FACILITY message if the call is still offered to the user
-                                * while trying to alert the deflected to party.
-                                */
-                               /* Ignore the ACK */
-                               break;
-
-                       default:
-                               break;
-                       }
-               }
-               break;
-#if 0  /* We don't handle this yet */
-       case Fac_CallRerouteing:
-               /* Private-Public ISDN interworking message */
-               /* We don't handle this yet */
-               break;
-#endif /* We don't handle this yet */
-       case Fac_DivertingLegInformation1:
-               /* Private-Public ISDN interworking message */
-               bc->div_leg_3_rx_wanted = 0;
-               if (ch && ch->ast) {
-                       bc->redirecting.reason =
-                               diversion_reason_to_misdn(bc->fac_in.u.DivertingLegInformation1.DiversionReason);
-                       if (bc->fac_in.u.DivertingLegInformation1.DivertedToPresent) {
-                               misdn_PresentedNumberUnscreened_extract(&bc->redirecting.to,
-                                       &bc->fac_in.u.DivertingLegInformation1.DivertedTo);
-
-                               /* Add configured prefix to redirecting.to.number */
-                               misdn_add_number_prefix(bc->port, bc->redirecting.to.number_type,
-                                       bc->redirecting.to.number, sizeof(bc->redirecting.to.number));
-                       } else {
-                               bc->redirecting.to.number[0] = '\0';
-                               bc->redirecting.to.number_plan = NUMPLAN_ISDN;
-                               bc->redirecting.to.number_type = NUMTYPE_UNKNOWN;
-                               bc->redirecting.to.presentation = 1;/* restricted */
-                               bc->redirecting.to.screening = 0;/* unscreened */
-                       }
-                       misdn_copy_redirecting_to_ast(ch->ast, &bc->redirecting, bc->incoming_cid_tag);
-                       bc->div_leg_3_rx_wanted = 1;
-               }
-               break;
-       case Fac_DivertingLegInformation2:
-               /* Private-Public ISDN interworking message */
-               switch (event) {
-               case EVENT_SETUP:
-                       /* Comes in on a SETUP with redirecting.from information */
-                       bc->div_leg_3_tx_pending = 1;
-                       if (ch && ch->ast) {
-                               /*
-                                * Setup the redirecting.to informtion so we can identify
-                                * if the user wants to manually supply the COLR for this
-                                * redirected to number if further redirects could happen.
-                                *
-                                * All the user needs to do is set the REDIRECTING(to-pres)
-                                * to the COLR and REDIRECTING(to-num) = ${EXTEN} to be safe
-                                * after determining that the incoming call was redirected by
-                                * checking if there is a REDIRECTING(from-num).
-                                */
-                               ast_copy_string(bc->redirecting.to.number, bc->dialed.number,
-                                       sizeof(bc->redirecting.to.number));
-                               bc->redirecting.to.number_plan = bc->dialed.number_plan;
-                               bc->redirecting.to.number_type = bc->dialed.number_type;
-                               bc->redirecting.to.presentation = 1;/* restricted */
-                               bc->redirecting.to.screening = 0;/* unscreened */
-
-                               bc->redirecting.reason =
-                                       diversion_reason_to_misdn(bc->fac_in.u.DivertingLegInformation2.DiversionReason);
-                               bc->redirecting.count = bc->fac_in.u.DivertingLegInformation2.DiversionCounter;
-                               if (bc->fac_in.u.DivertingLegInformation2.DivertingPresent) {
-                                       /* This information is redundant if there was a redirecting ie in the SETUP. */
-                                       misdn_PresentedNumberUnscreened_extract(&bc->redirecting.from,
-                                               &bc->fac_in.u.DivertingLegInformation2.Diverting);
-
-                                       /* Add configured prefix to redirecting.from.number */
-                                       misdn_add_number_prefix(bc->port, bc->redirecting.from.number_type,
-                                               bc->redirecting.from.number, sizeof(bc->redirecting.from.number));
-                               }
-#if 0
-                               if (bc->fac_in.u.DivertingLegInformation2.OriginalCalledPresent) {
-                                       /* We have no place to put the OriginalCalled number */
-                               }
-#endif
-                               misdn_copy_redirecting_to_ast(ch->ast, &bc->redirecting, bc->incoming_cid_tag);
-                       }
-                       break;
-               default:
-                       chan_misdn_log(0, bc->port," --> Expected in a SETUP message: facility type:0x%04X\n",
-                               bc->fac_in.Function);
-                       break;
-               }
-               break;
-       case Fac_DivertingLegInformation3:
-               /* Private-Public ISDN interworking message */
-               if (bc->div_leg_3_rx_wanted) {
-                       bc->div_leg_3_rx_wanted = 0;
-
-                       if (ch && ch->ast) {
-                               struct ast_party_redirecting redirecting;
-
-                               ast_channel_redirecting(ch->ast)->to.number.presentation =
-                                       bc->fac_in.u.DivertingLegInformation3.PresentationAllowedIndicator
-                                       ? AST_PRES_ALLOWED | AST_PRES_USER_NUMBER_UNSCREENED
-                                       : AST_PRES_RESTRICTED | AST_PRES_USER_NUMBER_UNSCREENED;
-                               ast_party_redirecting_init(&redirecting);
-                               ast_party_redirecting_copy(&redirecting, ast_channel_redirecting(ch->ast));
-
-                               /*
-                                * Reset any earlier private redirecting id representations and
-                                * make sure that it is invalidated at the remote end.
-                                */
-                               ast_party_id_reset(&redirecting.priv_orig);
-                               ast_party_id_reset(&redirecting.priv_from);
-                               ast_party_id_reset(&redirecting.priv_to);
-
-                               ast_channel_queue_redirecting_update(ch->ast, &redirecting, NULL);
-                               ast_party_redirecting_free(&redirecting);
-                       }
-               }
-               break;
-
-#else  /* !defined(AST_MISDN_ENHANCEMENTS) */
-
-       case Fac_CD:
-               if (ch && ch->ast) {
-                       ast_copy_string(bc->redirecting.from.number, bc->dialed.number,
-                               sizeof(bc->redirecting.from.number));
-                       bc->redirecting.from.name[0] = 0;
-                       bc->redirecting.from.number_plan = bc->dialed.number_plan;
-                       bc->redirecting.from.number_type = bc->dialed.number_type;
-                       bc->redirecting.from.screening = 0;/* Unscreened */
-                       bc->redirecting.from.presentation =
-                               bc->fac_in.u.CDeflection.PresentationAllowed
-                               ? 0 /* Allowed */ : 1 /* Restricted */;
-
-                       ast_copy_string(bc->redirecting.to.number,
-                               (char *) bc->fac_in.u.CDeflection.DeflectedToNumber,
-                               sizeof(bc->redirecting.to.number));
-                       bc->redirecting.to.name[0] = 0;
-                       bc->redirecting.to.number_plan = NUMPLAN_UNKNOWN;
-                       bc->redirecting.to.number_type = NUMTYPE_UNKNOWN;
-                       bc->redirecting.to.presentation = 0;/* Allowed */
-                       bc->redirecting.to.screening = 0;/* Unscreened */
-
-                       ++bc->redirecting.count;
-                       bc->redirecting.reason = mISDN_REDIRECTING_REASON_DEFLECTION;
-
-                       misdn_copy_redirecting_to_ast(ch->ast, &bc->redirecting, bc->incoming_cid_tag);
-                       ast_channel_call_forward_set(ch->ast, bc->redirecting.to.number);
-
-                       misdn_lib_send_event(bc, EVENT_DISCONNECT);
-
-                       /* This line is BUSY to further attempts by this dialing attempt. */
-                       ast_queue_control(ch->ast, AST_CONTROL_BUSY);
-               }
-               break;
-#endif /* !defined(AST_MISDN_ENHANCEMENTS) */
-       case Fac_AOCDCurrency:
-               if (ch && ch->ast) {
-                       bc->AOCDtype = Fac_AOCDCurrency;
-                       memcpy(&bc->AOCD.currency, &bc->fac_in.u.AOCDcur, sizeof(bc->AOCD.currency));
-                       bc->AOCD_need_export = 1;
-                       export_aoc_vars(ch->originator, ch->ast, bc);
-               }
-               break;
-       case Fac_AOCDChargingUnit:
-               if (ch && ch->ast) {
-                       bc->AOCDtype = Fac_AOCDChargingUnit;
-                       memcpy(&bc->AOCD.chargingUnit, &bc->fac_in.u.AOCDchu, sizeof(bc->AOCD.chargingUnit));
-                       bc->AOCD_need_export = 1;
-                       export_aoc_vars(ch->originator, ch->ast, bc);
-               }
-               break;
-#if defined(AST_MISDN_ENHANCEMENTS)
-       case Fac_ERROR:
-               diagnostic_msg = misdn_to_str_error_code(bc->fac_in.u.ERROR.errorValue);
-               chan_misdn_log(1, bc->port, " --> Facility error code: %s\n", diagnostic_msg);
-               switch (event) {
-               case EVENT_DISCONNECT:
-               case EVENT_RELEASE:
-               case EVENT_RELEASE_COMPLETE:
-                       /* Possible call failure as a result of Fac_CCBSCall/Fac_CCBS_T_Call */
-                       if (ch && ch->peer) {
-                               misdn_cc_set_peer_var(ch->peer, MISDN_ERROR_MSG, diagnostic_msg);
-                       }
-                       break;
-               default:
-                       break;
-               }
-               AST_LIST_LOCK(&misdn_cc_records_db);
-               cc_record = misdn_cc_find_by_invoke(bc->port, bc->fac_in.u.ERROR.invokeId);
-               if (cc_record) {
-                       cc_record->outstanding_message = 0;
-                       cc_record->error_code = bc->fac_in.u.ERROR.errorValue;
-               }
-               AST_LIST_UNLOCK(&misdn_cc_records_db);
-               break;
-       case Fac_REJECT:
-               diagnostic_msg = misdn_to_str_reject_code(bc->fac_in.u.REJECT.Code);
-               chan_misdn_log(1, bc->port, " --> Facility reject code: %s\n", diagnostic_msg);
-               switch (event) {
-               case EVENT_DISCONNECT:
-               case EVENT_RELEASE:
-               case EVENT_RELEASE_COMPLETE:
-                       /* Possible call failure as a result of Fac_CCBSCall/Fac_CCBS_T_Call */
-                       if (ch && ch->peer) {
-                               misdn_cc_set_peer_var(ch->peer, MISDN_ERROR_MSG, diagnostic_msg);
-                       }
-                       break;
-               default:
-                       break;
-               }
-               if (bc->fac_in.u.REJECT.InvokeIDPresent) {
-                       AST_LIST_LOCK(&misdn_cc_records_db);
-                       cc_record = misdn_cc_find_by_invoke(bc->port, bc->fac_in.u.REJECT.InvokeID);
-                       if (cc_record) {
-                               cc_record->outstanding_message = 0;
-                               cc_record->reject_code = bc->fac_in.u.REJECT.Code;
-                       }
-                       AST_LIST_UNLOCK(&misdn_cc_records_db);
-               }
-               break;
-       case Fac_RESULT:
-               AST_LIST_LOCK(&misdn_cc_records_db);
-               cc_record = misdn_cc_find_by_invoke(bc->port, bc->fac_in.u.RESULT.InvokeID);
-               if (cc_record) {
-                       cc_record->outstanding_message = 0;
-               }
-               AST_LIST_UNLOCK(&misdn_cc_records_db);
-               break;
-#if 0  /* We don't handle this yet */
-       case Fac_EctExecute:
-               /* We don't handle this yet */
-               break;
-       case Fac_ExplicitEctExecute:
-               /* We don't handle this yet */
-               break;
-       case Fac_EctLinkIdRequest:
-               /* We don't handle this yet */
-               break;
-#endif /* We don't handle this yet */
-       case Fac_SubaddressTransfer:
-               /* We do not have anything to do for this message since we do not handle subaddresses. */
-               break;
-       case Fac_RequestSubaddress:
-               /*
-                * We do not have anything to do for this message since we do not handle subaddresses.
-                * However, we do care about some other ie's that should be present.
-                */
-               if (bc->redirecting.to_changed) {
-                       /* Add configured prefix to redirecting.to.number */
-                       misdn_add_number_prefix(bc->port, bc->redirecting.to.number_type,
-                               bc->redirecting.to.number, sizeof(bc->redirecting.to.number));
-               }
-               switch (bc->notify_description_code) {
-               case mISDN_NOTIFY_CODE_INVALID:
-                       /* Notify ie was not present. */
-                       bc->redirecting.to_changed = 0;
-                       break;
-               case mISDN_NOTIFY_CODE_CALL_TRANSFER_ALERTING:
-                       /*
-                        * It would be preferable to update the connected line information
-                        * only when the message callStatus is active.  However, the
-                        * optional redirection number may not be present in the active
-                        * message if an alerting message were received earlier.
-                        *
-                        * The consequences if we wind up sending two updates is benign.
-                        * The other end will think that it got transferred twice.
-                        */
-                       if (!bc->redirecting.to_changed) {
-                               break;
-                       }
-                       bc->redirecting.to_changed = 0;
-                       if (!ch || !ch->ast) {
-                               break;
-                       }
-                       misdn_update_remote_party(ch->ast, &bc->redirecting.to,
-                               AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER_ALERTING,
-                               bc->incoming_cid_tag);
-                       break;
-               case mISDN_NOTIFY_CODE_CALL_TRANSFER_ACTIVE:
-                       if (!bc->redirecting.to_changed) {
-                               break;
-                       }
-                       bc->redirecting.to_changed = 0;
-                       if (!ch || !ch->ast) {
-                               break;
-                       }
-                       misdn_update_remote_party(ch->ast, &bc->redirecting.to,
-                               AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER, bc->incoming_cid_tag);
-                       break;
-               default:
-                       bc->redirecting.to_changed = 0;
-                       chan_misdn_log(0, bc->port," --> not yet handled: notify code:0x%02X\n",
-                               bc->notify_description_code);
-                       break;
-               }
-               bc->notify_description_code = mISDN_NOTIFY_CODE_INVALID;
-               break;
-       case Fac_EctInform:
-               /* Private-Public ISDN interworking message */
-               if (ch && ch->ast && bc->fac_in.u.EctInform.RedirectionPresent) {
-                       /* Add configured prefix to the redirection number */
-                       memset(&party_id, 0, sizeof(party_id));
-                       misdn_PresentedNumberUnscreened_extract(&party_id,
-                               &bc->fac_in.u.EctInform.Redirection);
-                       misdn_add_number_prefix(bc->port, party_id.number_type,
-                               party_id.number, sizeof(party_id.number));
-
-                       /*
-                        * It would be preferable to update the connected line information
-                        * only when the message callStatus is active.  However, the
-                        * optional redirection number may not be present in the active
-                        * message if an alerting message were received earlier.
-                        *
-                        * The consequences if we wind up sending two updates is benign.
-                        * The other end will think that it got transferred twice.
-                        */
-                       misdn_update_remote_party(ch->ast, &party_id,
-                               (bc->fac_in.u.EctInform.Status == 0 /* alerting */)
-                                       ? AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER_ALERTING
-                                       : AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER,
-                                       bc->incoming_cid_tag);
-               }
-               break;
-#if 0  /* We don't handle this yet */
-       case Fac_EctLoopTest:
-               /* The use of this message is unclear on how it works to detect loops. */
-               /* We don't handle this yet */
-               break;
-#endif /* We don't handle this yet */
-       case Fac_CallInfoRetain:
-               switch (event) {
-               case EVENT_ALERTING:
-               case EVENT_DISCONNECT:
-                       /* CCBS/CCNR is available */
-                       if (ch && ch->peer) {
-                               AST_LIST_LOCK(&misdn_cc_records_db);
-                               if (ch->record_id == -1) {
-                                       cc_record = misdn_cc_new();
-                               } else {
-                                       /*
-                                        * We are doing a call-completion attempt
-                                        * or the switch is sending us extra call-completion
-                                        * availability indications (erroneously?).
-                                        *
-                                        * Assume that the network request retention option
-                                        * is not on and that the current call-completion
-                                        * request is disabled.
-                                        */
-                                       cc_record = misdn_cc_find_by_id(ch->record_id);
-                                       if (cc_record) {
-                                               if (cc_record->ptp && cc_record->mode.ptp.bc) {
-                                                       /*
-                                                        * What?  We are getting mixed messages from the
-                                                        * switch.  We are currently setup for
-                                                        * point-to-point.  Now we are switching to
-                                                        * point-to-multipoint.
-                                                        *
-                                                        * Close the call-completion signaling link
-                                                        */
-                                                       cc_record->mode.ptp.bc->fac_out.Function = Fac_None;
-                                                       cc_record->mode.ptp.bc->out_cause = AST_CAUSE_NORMAL_CLEARING;
-                                                       misdn_lib_send_event(cc_record->mode.ptp.bc, EVENT_RELEASE_COMPLETE);
-                                               }
-
-                                               /*
-                                                * Resetup the existing record for a possible new
-                                                * call-completion request.
-                                                */
-                                               new_record_id = misdn_cc_record_id_new();
-                                               if (new_record_id < 0) {
-                                                       /* Looks like we must keep the old id anyway. */
-                                               } else {
-                                                       cc_record->record_id = new_record_id;
-                                                       ch->record_id = new_record_id;
-                                               }
-                                               cc_record->ptp = 0;
-                                               cc_record->port = bc->port;
-                                               memset(&cc_record->mode, 0, sizeof(cc_record->mode));
-                                               cc_record->mode.ptmp.linkage_id = bc->fac_in.u.CallInfoRetain.CallLinkageID;
-                                               cc_record->invoke_id = ++misdn_invoke_id;
-                                               cc_record->activated = 0;
-                                               cc_record->outstanding_message = 0;
-                                               cc_record->activation_requested = 0;
-                                               cc_record->error_code = FacError_None;
-                                               cc_record->reject_code = FacReject_None;
-                                               memset(&cc_record->remote_user_free, 0, sizeof(cc_record->remote_user_free));
-                                               memset(&cc_record->b_free, 0, sizeof(cc_record->b_free));
-                                               cc_record->time_created = time(NULL);
-
-                                               cc_record = NULL;
-                                       } else {
-                                               /*
-                                                * Where did the record go?  We will have to recapture
-                                                * the call setup information.  Unfortunately, some
-                                                * setup information may have been changed.
-                                                */
-                                               ch->record_id = -1;
-                                               cc_record = misdn_cc_new();
-                                       }
-                               }
-                               if (cc_record) {
-                                       ch->record_id = cc_record->record_id;
-                                       cc_record->ptp = 0;
-                                       cc_record->port = bc->port;
-                                       cc_record->mode.ptmp.linkage_id = bc->fac_in.u.CallInfoRetain.CallLinkageID;
-
-                                       /* Record call information for possible call-completion attempt. */
-                                       cc_record->redial.caller = bc->caller;
-                                       cc_record->redial.dialed = bc->dialed;
-                                       cc_record->redial.setup_bc_hlc_llc = bc->setup_bc_hlc_llc;
-                                       cc_record->redial.capability = bc->capability;
-                                       cc_record->redial.hdlc = bc->hdlc;
-                               }
-                               AST_LIST_UNLOCK(&misdn_cc_records_db);
-
-                               /* Set MISDN_CC_RECORD_ID in original channel */
-                               if (ch->record_id != -1) {
-                                       snprintf(buf, sizeof(buf), "%ld", ch->record_id);
-                               } else {
-                                       buf[0] = 0;
-                               }
-                               misdn_cc_set_peer_var(ch->peer, MISDN_CC_RECORD_ID, buf);
-                       }
-                       break;
-               default:
-                       chan_misdn_log(0, bc->port,
-                               " --> Expected in a DISCONNECT or ALERTING message: facility type:0x%04X\n",
-                               bc->fac_in.Function);
-                       break;
-               }
-               break;
-       case Fac_CCBS_T_Call:
-       case Fac_CCBSCall:
-               switch (event) {
-               case EVENT_SETUP:
-                       /*
-                        * This is a call completion retry call.
-                        * If we had anything to do we would do it here.
-                        */
-                       break;
-               default:
-                       chan_misdn_log(0, bc->port, " --> Expected in a SETUP message: facility type:0x%04X\n",
-                               bc->fac_in.Function);
-                       break;
-               }
-               break;
-       case Fac_CCBSDeactivate:
-               switch (bc->fac_in.u.CCBSDeactivate.ComponentType) {
-               case FacComponent_Result:
-                       AST_LIST_LOCK(&misdn_cc_records_db);
-                       cc_record = misdn_cc_find_by_invoke(bc->port, bc->fac_in.u.CCBSDeactivate.InvokeID);
-                       if (cc_record) {
-                               cc_record->outstanding_message = 0;
-                       }
-                       AST_LIST_UNLOCK(&misdn_cc_records_db);
-                       break;
-
-               default:
-                       chan_misdn_log(0, bc->port, " --> not yet handled: facility type:0x%04X\n",
-                               bc->fac_in.Function);
-                       break;
-               }
-               break;
-       case Fac_CCBSErase:
-               AST_LIST_LOCK(&misdn_cc_records_db);
-               cc_record = misdn_cc_find_by_reference(bc->port, bc->fac_in.u.CCBSErase.CCBSReference);
-               if (cc_record) {
-                       misdn_cc_delete(cc_record);
-               }
-               AST_LIST_UNLOCK(&misdn_cc_records_db);
-               break;
-       case Fac_CCBSRemoteUserFree:
-               misdn_cc_handle_remote_user_free(bc->port, &bc->fac_in);
-               break;
-       case Fac_CCBSBFree:
-               misdn_cc_handle_b_free(bc->port, &bc->fac_in);
-               break;
-       case Fac_CCBSStatusRequest:
-               misdn_cc_handle_ccbs_status_request(bc->port, &bc->fac_in);
-               break;
-       case Fac_EraseCallLinkageID:
-               AST_LIST_LOCK(&misdn_cc_records_db);
-               cc_record = misdn_cc_find_by_linkage(bc->port,
-                       bc->fac_in.u.EraseCallLinkageID.CallLinkageID);
-               if (cc_record && !cc_record->activation_requested) {
-                       /*
-                        * The T-RETENTION timer expired before we requested
-                        * call completion activation.  Call completion is no
-                        * longer available.
-                        */
-                       misdn_cc_delete(cc_record);
-               }
-               AST_LIST_UNLOCK(&misdn_cc_records_db);
-               break;
-       case Fac_CCBSStopAlerting:
-               /* We do not have anything to do for this message. */
-               break;
-       case Fac_CCBSRequest:
-       case Fac_CCNRRequest:
-               switch (bc->fac_in.u.CCBSRequest.ComponentType) {
-               case FacComponent_Result:
-                       AST_LIST_LOCK(&misdn_cc_records_db);
-                       cc_record = misdn_cc_find_by_invoke(bc->port, bc->fac_in.u.CCBSRequest.InvokeID);
-                       if (cc_record && !cc_record->ptp) {
-                               cc_record->outstanding_message = 0;
-                               cc_record->activated = 1;
-                               cc_record->mode.ptmp.recall_mode = bc->fac_in.u.CCBSRequest.Component.Result.RecallMode;
-                               cc_record->mode.ptmp.reference_id = bc->fac_in.u.CCBSRequest.Component.Result.CCBSReference;
-                       }
-                       AST_LIST_UNLOCK(&misdn_cc_records_db);
-                       break;
-
-               default:
-                       chan_misdn_log(0, bc->port, " --> not yet handled: facility type:0x%04X\n",
-                               bc->fac_in.Function);
-                       break;
-               }
-               break;
-#if 0  /* We don't handle this yet */
-       case Fac_CCBSInterrogate:
-       case Fac_CCNRInterrogate:
-               /* We don't handle this yet */
-               break;
-       case Fac_StatusRequest:
-               /* We don't handle this yet */
-               break;
-#endif /* We don't handle this yet */
-#if 0  /* We don't handle this yet */
-       case Fac_CCBS_T_Suspend:
-       case Fac_CCBS_T_Resume:
-               /* We don't handle this yet */
-               break;
-#endif /* We don't handle this yet */
-       case Fac_CCBS_T_RemoteUserFree:
-               misdn_cc_handle_T_remote_user_free(bc);
-               break;
-       case Fac_CCBS_T_Available:
-               switch (event) {
-               case EVENT_ALERTING:
-               case EVENT_DISCONNECT:
-                       /* CCBS-T/CCNR-T is available */
-                       if (ch && ch->peer) {
-                               int set_id = 1;
-
-                               AST_LIST_LOCK(&misdn_cc_records_db);
-                               if (ch->record_id == -1) {
-                                       cc_record = misdn_cc_new();
-                               } else {
-                                       /*
-                                        * We are doing a call-completion attempt
-                                        * or the switch is sending us extra call-completion
-                                        * availability indications (erroneously?).
-                                        */
-                                       cc_record = misdn_cc_find_by_id(ch->record_id);
-                                       if (cc_record) {
-                                               if (cc_record->ptp && cc_record->mode.ptp.retention_enabled) {
-                                                       /*
-                                                        * Call-completion is still activated.
-                                                        * The user does not have to request it again.
-                                                        */
-                                                       chan_misdn_log(1, bc->port, " --> Call-completion request retention option is enabled\n");
-
-                                                       set_id = 0;
-                                               } else {
-                                                       if (cc_record->ptp && cc_record->mode.ptp.bc) {
-                                                               /*
-                                                                * The network request retention option
-                                                                * is not on and the current call-completion
-                                                                * request is to be disabled.
-                                                                *
-                                                                * We should get here only if EVENT_DISCONNECT
-                                                                *
-                                                                * Close the call-completion signaling link
-                                                                */
-                                                               cc_record->mode.ptp.bc->fac_out.Function = Fac_None;
-                                                               cc_record->mode.ptp.bc->out_cause = AST_CAUSE_NORMAL_CLEARING;
-                                                               misdn_lib_send_event(cc_record->mode.ptp.bc, EVENT_RELEASE_COMPLETE);
-                                                       }
-
-                                                       /*
-                                                        * Resetup the existing record for a possible new
-                                                        * call-completion request.
-                                                        */
-                                                       new_record_id = misdn_cc_record_id_new();
-                                                       if (new_record_id < 0) {
-                                                               /* Looks like we must keep the old id anyway. */
-                                                       } else {
-                                                               cc_record->record_id = new_record_id;
-                                                               ch->record_id = new_record_id;
-                                                       }
-                                                       cc_record->ptp = 1;
-                                                       cc_record->port = bc->port;
-                                                       memset(&cc_record->mode, 0, sizeof(cc_record->mode));
-                                                       cc_record->invoke_id = ++misdn_invoke_id;
-                                                       cc_record->activated = 0;
-                                                       cc_record->outstanding_message = 0;
-                                                       cc_record->activation_requested = 0;
-                                                       cc_record->error_code = FacError_None;
-                                                       cc_record->reject_code = FacReject_None;
-                                                       memset(&cc_record->remote_user_free, 0, sizeof(cc_record->remote_user_free));
-                                                       memset(&cc_record->b_free, 0, sizeof(cc_record->b_free));
-                                                       cc_record->time_created = time(NULL);
-                                               }
-                                               cc_record = NULL;
-                                       } else {
-                                               /*
-                                                * Where did the record go?  We will have to recapture
-                                                * the call setup information.  Unfortunately, some
-                                                * setup information may have been changed.
-                                                */
-                                               ch->record_id = -1;
-                                               cc_record = misdn_cc_new();
-                                       }
-                               }
-                               if (cc_record) {
-                                       ch->record_id = cc_record->record_id;
-                                       cc_record->ptp = 1;
-                                       cc_record->port = bc->port;
-
-                                       /* Record call information for possible call-completion attempt. */
-                                       cc_record->redial.caller = bc->caller;
-                                       cc_record->redial.dialed = bc->dialed;
-                                       cc_record->redial.setup_bc_hlc_llc = bc->setup_bc_hlc_llc;
-                                       cc_record->redial.capability = bc->capability;
-                                       cc_record->redial.hdlc = bc->hdlc;
-                               }
-                               AST_LIST_UNLOCK(&misdn_cc_records_db);
-
-                               /* Set MISDN_CC_RECORD_ID in original channel */
-                               if (ch->record_id != -1 && set_id) {
-                                       snprintf(buf, sizeof(buf), "%ld", ch->record_id);
-                               } else {
-                                       buf[0] = 0;
-                               }
-                               misdn_cc_set_peer_var(ch->peer, MISDN_CC_RECORD_ID, buf);
-                       }
-                       break;
-               default:
-                       chan_misdn_log(0, bc->port,
-                               " --> Expected in a DISCONNECT or ALERTING message: facility type:0x%04X\n",
-                               bc->fac_in.Function);
-                       break;
-               }
-               break;
-       case Fac_CCBS_T_Request:
-       case Fac_CCNR_T_Request:
-               switch (bc->fac_in.u.CCBS_T_Request.ComponentType) {
-               case FacComponent_Result:
-                       AST_LIST_LOCK(&misdn_cc_records_db);
-                       cc_record = misdn_cc_find_by_invoke(bc->port, bc->fac_in.u.CCBS_T_Request.InvokeID);
-                       if (cc_record && cc_record->ptp) {
-                               cc_record->outstanding_message = 0;
-                               cc_record->activated = 1;
-                               cc_record->mode.ptp.retention_enabled =
-                                       cc_record->mode.ptp.requested_retention
-                                       ? bc->fac_in.u.CCBS_T_Request.Component.Result.RetentionSupported
-                                       ? 1 : 0
-                                       : 0;
-                       }
-                       AST_LIST_UNLOCK(&misdn_cc_records_db);
-                       break;
-
-               case FacComponent_Invoke:
-                       /* We cannot be User-B in ptp mode. */
-               default:
-                       chan_misdn_log(0, bc->port, " --> not yet handled: facility type:0x%04X\n",
-                               bc->fac_in.Function);
-                       break;
-               }
-               break;
-
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-       case Fac_None:
-               break;
-       default:
-               chan_misdn_log(0, bc->port, " --> not yet handled: facility type:0x%04X\n",
-                       bc->fac_in.Function);
-               break;
-       }
-}
-
-/*!
- * \internal
- * \brief Determine if the given dialed party matches our MSN.
- * \since 1.8
- *
- * \param port ISDN port
- * \param dialed Dialed party information of incoming call.
- *
- * \retval non-zero if MSN is valid.
- * \retval 0 if MSN invalid.
- */
-static int misdn_is_msn_valid(int port, const struct misdn_party_dialing *dialed)
-{
-       char number[sizeof(dialed->number)];
-
-       ast_copy_string(number, dialed->number, sizeof(number));
-       misdn_add_number_prefix(port, dialed->number_type, number, sizeof(number));
-       return misdn_cfg_is_msn_valid(port, number);
-}
-
-/************************************************************/
-/*  Receive Events from isdn_lib  here                     */
-/************************************************************/
-static enum event_response_e
-cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
-{
-#if defined(AST_MISDN_ENHANCEMENTS)
-       struct misdn_cc_record *cc_record;
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-       struct chan_list *held_ch;
-       struct chan_list *ch = find_chan_by_bc(bc);
-
-       if (event != EVENT_BCHAN_DATA && event != EVENT_TONE_GENERATE) {
-               int debuglevel = 1;
-
-               /*  Debug Only Non-Bchan */
-               if (event == EVENT_CLEANUP && !user_data) {
-                       debuglevel = 5;
-               }
-
-               chan_misdn_log(debuglevel, bc->port,
-                       "I IND :%s caller:\"%s\" <%s> dialed:%s pid:%d state:%s\n",
-                       manager_isdn_get_info(event),
-                       bc->caller.name,
-                       bc->caller.number,
-                       bc->dialed.number,
-                       bc->pid,
-                       ch ? misdn_get_ch_state(ch) : "none");
-               if (debuglevel == 1) {
-                       misdn_lib_log_ies(bc);
-                       chan_misdn_log(4, bc->port, " --> bc_state:%s\n", bc_state2str(bc->bc_state));
-               }
-       }
-
-       if (!ch) {
-               switch(event) {
-               case EVENT_SETUP:
-               case EVENT_DISCONNECT:
-               case EVENT_RELEASE:
-               case EVENT_RELEASE_COMPLETE:
-               case EVENT_PORT_ALARM:
-               case EVENT_RETRIEVE:
-               case EVENT_NEW_BC:
-               case EVENT_FACILITY:
-               case EVENT_REGISTER:
-                       break;
-               case EVENT_CLEANUP:
-               case EVENT_TONE_GENERATE:
-               case EVENT_BCHAN_DATA:
-                       return -1;
-               default:
-                       chan_misdn_log(1, bc->port, "Chan not existing at the moment bc->l3id:%x bc:%p event:%s port:%d channel:%d\n", bc->l3_id, bc, manager_isdn_get_info(event), bc->port, bc->channel);
-                       return -1;
-               }
-       } else {
-               switch (event) {
-               case EVENT_TONE_GENERATE:
-                       break;
-               case EVENT_DISCONNECT:
-               case EVENT_RELEASE:
-               case EVENT_RELEASE_COMPLETE:
-               case EVENT_CLEANUP:
-               case EVENT_TIMEOUT:
-                       if (!ch->ast) {
-                               chan_misdn_log(3, bc->port, "ast_hangup already called, so we have no ast ptr anymore in event(%s)\n", manager_isdn_get_info(event));
-                       }
-                       break;
-               default:
-                       if (!ch->ast || !MISDN_ASTERISK_TECH_PVT(ch->ast)) {
-                               if (event != EVENT_BCHAN_DATA) {
-                                       ast_log(LOG_NOTICE, "No Ast or No private Pointer in Event (%d:%s)\n", event, manager_isdn_get_info(event));
-                               }
-                               chan_list_unref(ch, "No Ast or Ast private pointer");
-                               return -1;
-                       }
-                       break;
-               }
-       }
-
-
-       switch (event) {
-       case EVENT_PORT_ALARM:
-               {
-                       int boa = 0;
-                       misdn_cfg_get(bc->port, MISDN_CFG_ALARM_BLOCK, &boa, sizeof(boa));
-                       if (boa) {
-                               cb_log(1, bc->port, " --> blocking\n");
-                               misdn_lib_port_block(bc->port);
-                       }
-               }
-               break;
-       case EVENT_BCHAN_ACTIVATED:
-               break;
-
-       case EVENT_NEW_CHANNEL:
-               update_name(ch->ast,bc->port,bc->channel);
-               break;
-
-       case EVENT_NEW_L3ID:
-               ch->l3id=bc->l3_id;
-               ch->addr=bc->addr;
-               break;
-
-       case EVENT_NEW_BC:
-               if (!ch) {
-                       ch = find_hold_call(bc);
-               }
-
-               if (!ch) {
-                       ast_log(LOG_WARNING, "NEW_BC without chan_list?\n");
-                       break;
-               }
-
-               if (bc) {
-                       ch->bc = (struct misdn_bchannel *) user_data;
-               }
-               break;
-
-       case EVENT_DTMF_TONE:
-       {
-               /*  sending INFOS as DTMF-Frames :) */
-               struct ast_frame fr;
-
-               memset(&fr, 0, sizeof(fr));
-               fr.frametype = AST_FRAME_DTMF;
-               fr.subclass.integer = bc->dtmf ;
-               fr.src = NULL;
-               fr.data.ptr = NULL;
-               fr.datalen = 0;
-               fr.samples = 0;
-               fr.mallocd = 0;
-               fr.offset = 0;
-               fr.delivery = ast_tv(0,0);
-
-               if (!ch->ignore_dtmf) {
-                       chan_misdn_log(2, bc->port, " --> DTMF:%c\n", bc->dtmf);
-                       ast_queue_frame(ch->ast, &fr);
-               } else {
-                       chan_misdn_log(2, bc->port, " --> Ignoring DTMF:%c due to bridge flags\n", bc->dtmf);
-               }
-               break;
-       }
-       case EVENT_STATUS:
-               break;
-
-       case EVENT_INFORMATION:
-               if (ch->state != MISDN_CONNECTED) {
-                       stop_indicate(ch);
-               }
-
-               if (!ch->ast) {
-                       break;
-               }
-
-               if (ch->state == MISDN_WAITING4DIGS) {
-                       RAII_VAR(struct ast_features_pickup_config *, pickup_cfg, NULL, ao2_cleanup);
-                       const char *pickupexten;
-
-                       /*  Ok, incomplete Setup, waiting till extension exists */
-                       if (ast_strlen_zero(bc->info_dad) && ! ast_strlen_zero(bc->keypad)) {
-                               chan_misdn_log(1, bc->port, " --> using keypad as info\n");
-                               ast_copy_string(bc->info_dad, bc->keypad, sizeof(bc->info_dad));
-                       }
-
-                       strncat(bc->dialed.number, bc->info_dad, sizeof(bc->dialed.number) - strlen(bc->dialed.number) - 1);
-                       ast_channel_exten_set(ch->ast, bc->dialed.number);
-
-                       ast_channel_lock(ch->ast);
-                       pickup_cfg = ast_get_chan_features_pickup_config(ch->ast);
-                       if (!pickup_cfg) {
-                               ast_log(LOG_ERROR, "Unable to retrieve pickup configuration options. Unable to detect call pickup extension\n");
-                               pickupexten = "";
-                       } else {
-                               pickupexten = ast_strdupa(pickup_cfg->pickupexten);
-                       }
-                       ast_channel_unlock(ch->ast);
-
-                       /* Check for Pickup Request first */
-                       if (!strcmp(ast_channel_exten(ch->ast), pickupexten)) {
-                               if (ast_pickup_call(ch->ast)) {
-                                       hangup_chan(ch, bc);
-                               } else {
-                                       ch->state = MISDN_CALLING_ACKNOWLEDGE;
-                                       hangup_chan(ch, bc);
-                                       ch->ast = NULL;
-                                       break;
-                               }
-                       }
-
-                       if (!ast_canmatch_extension(ch->ast, ch->context, bc->dialed.number, 1, bc->caller.number)) {
-                               if (ast_exists_extension(ch->ast, ch->context, "i", 1, bc->caller.number)) {
-                                       ast_log(LOG_WARNING,
-                                               "Extension '%s@%s' can never match. Jumping to 'i' extension. port:%d\n",
-                                               bc->dialed.number, ch->context, bc->port);
-                                       pbx_builtin_setvar_helper(ch->ast, "INVALID_EXTEN", bc->dialed.number);
-                                       ast_channel_exten_set(ch->ast, "i");
-                                       ch->state = MISDN_DIALING;
-                                       start_pbx(ch, bc, ch->ast);
-                                       break;
-                               }
-
-                               ast_log(LOG_WARNING,
-                                       "Extension '%s@%s' can never match. Disconnecting. port:%d\n"
-                                       "\tMaybe you want to add an 'i' extension to catch this case.\n",
-                                       bc->dialed.number, ch->context, bc->port);
-
-                               if (bc->nt) {
-                                       hanguptone_indicate(ch);
-                               }
-                               ch->state = MISDN_EXTCANTMATCH;
-                               bc->out_cause = AST_CAUSE_UNALLOCATED;
-
-                               misdn_lib_send_event(bc, EVENT_DISCONNECT);
-                               break;
-                       }
-
-                       if (ch->overlap_dial) {
-                               ast_mutex_lock(&ch->overlap_tv_lock);
-                               ch->overlap_tv = ast_tvnow();
-                               ast_mutex_unlock(&ch->overlap_tv_lock);
-                               if (ch->overlap_dial_task == -1) {
-                                       ch->overlap_dial_task =
-                                               misdn_tasks_add_variable(ch->overlap_dial, misdn_overlap_dial_task, ch);
-                               }
-                               break;
-                       }
-
-                       if (ast_exists_extension(ch->ast, ch->context, bc->dialed.number, 1, bc->caller.number))  {
-                               ch->state = MISDN_DIALING;
-                               start_pbx(ch, bc, ch->ast);
-                       }
-               } else {
-                       /*  sending INFOS as DTMF-Frames :) */
-                       struct ast_frame fr;
-                       int digits;
-
-                       memset(&fr, 0, sizeof(fr));
-                       fr.frametype = AST_FRAME_DTMF;
-                       fr.subclass.integer = bc->info_dad[0] ;
-                       fr.src = NULL;
-                       fr.data.ptr = NULL;
-                       fr.datalen = 0;
-                       fr.samples = 0;
-                       fr.mallocd = 0;
-                       fr.offset = 0;
-                       fr.delivery = ast_tv(0,0);
-
-                       misdn_cfg_get(0, MISDN_GEN_APPEND_DIGITS2EXTEN, &digits, sizeof(digits));
-                       if (ch->state != MISDN_CONNECTED) {
-                               if (digits) {
-                                       strncat(bc->dialed.number, bc->info_dad, sizeof(bc->dialed.number) - strlen(bc->dialed.number) - 1);
-                                       ast_channel_exten_set(ch->ast, bc->dialed.number);
-                               }
-
-                               ast_queue_frame(ch->ast, &fr);
-                       }
-               }
-               break;
-       case EVENT_SETUP:
-       {
-               struct ast_channel *chan;
-               int exceed;
-               int ai;
-               int im;
-               int append_msn = 0;
-               RAII_VAR(struct ast_features_pickup_config *, pickup_cfg, NULL, ao2_cleanup);
-               const char *pickupexten;
-
-               if (ch) {
-                       switch (ch->state) {
-                       case MISDN_NOTHING:
-                               chan_list_unref(ch, "Ignore found ch.  Is it for an outgoing call?");
-                               ch = NULL;
-                               break;
-                       default:
-                               chan_list_unref(ch, "Already have a call.");
-                               chan_misdn_log(1, bc->port, " --> Ignoring Call we have already one\n");
-                               return RESPONSE_IGNORE_SETUP_WITHOUT_CLOSE; /*  Ignore MSNs which are not in our List */
-                       }
-               }
-
-               if (!bc->nt && !misdn_is_msn_valid(bc->port, &bc->dialed)) {
-                       chan_misdn_log(1, bc->port, " --> Ignoring Call, its not in our MSN List\n");
-                       return RESPONSE_IGNORE_SETUP; /*  Ignore MSNs which are not in our List */
-               }
-
-               if (bc->cw) {
-                       int cause;
-                       chan_misdn_log(0, bc->port, " --> Call Waiting on PMP sending RELEASE_COMPLETE\n");
-                       misdn_cfg_get(bc->port, MISDN_CFG_REJECT_CAUSE, &cause, sizeof(cause));
-                       bc->out_cause = cause ? cause : AST_CAUSE_NORMAL_CLEARING;
-                       return RESPONSE_RELEASE_SETUP;
-               }
-
-               print_bearer(bc);
-
-               ch = chan_list_init(ORG_MISDN);
-               if (!ch) {
-                       chan_misdn_log(-1, bc->port, "cb_events: malloc for chan_list failed!\n");
-                       return RESPONSE_RELEASE_SETUP;
-               }
-
-               ch->bc = bc;
-               ch->l3id = bc->l3_id;
-               ch->addr = bc->addr;
-
-               {
-                       struct ast_format_cap *cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
-                       if (!(cap)) {
-                               return RESPONSE_ERR;
-                       }
-                       ast_format_cap_append(cap, ast_format_alaw, 0);
-                       chan = misdn_new(ch, AST_STATE_RESERVED, bc->dialed.number, bc->caller.number, cap, NULL, NULL, bc->port, bc->channel);
-                       ao2_ref(cap, -1);
-               }
-               if (!chan) {
-                       chan_list_unref(ch, "Failed to create a new channel");
-                       ast_log(LOG_ERROR, "cb_events: misdn_new failed!\n");
-                       return RESPONSE_RELEASE_SETUP;
-               }
-
-               ast_channel_lock(chan);
-               pickup_cfg = ast_get_chan_features_pickup_config(chan);
-               if (!pickup_cfg) {
-                       ast_log(LOG_ERROR, "Unable to retrieve pickup configuration options. Unable to detect call pickup extension\n");
-                       pickupexten = "";
-               } else {
-                       pickupexten = ast_strdupa(pickup_cfg->pickupexten);
-               }
-               ast_channel_unlock(chan);
-
-               if ((exceed = add_in_calls(bc->port))) {
-                       char tmp[16];
-                       snprintf(tmp, sizeof(tmp), "%d", exceed);
-                       pbx_builtin_setvar_helper(chan, "MAX_OVERFLOW", tmp);
-               }
-
-               read_config(ch);
-
-               export_ch(chan, bc, ch);
-
-               ast_channel_lock(ch->ast);
-               ast_channel_rings_set(ch->ast, 1);
-               ast_setstate(ch->ast, AST_STATE_RINGING);
-               ast_channel_unlock(ch->ast);
-
-               /* Update asterisk channel caller information */
-               chan_misdn_log(2, bc->port, " --> TON: %s(%d)\n", misdn_to_str_ton(bc->caller.number_type), bc->caller.number_type);
-               chan_misdn_log(2, bc->port, " --> PLAN: %s(%d)\n", misdn_to_str_plan(bc->caller.number_plan), bc->caller.number_plan);
-               ast_channel_caller(chan)->id.number.plan = misdn_to_ast_ton(bc->caller.number_type)
-                       | misdn_to_ast_plan(bc->caller.number_plan);
-
-               chan_misdn_log(2, bc->port, " --> PRES: %s(%d)\n", misdn_to_str_pres(bc->caller.presentation), bc->caller.presentation);
-               chan_misdn_log(2, bc->port, " --> SCREEN: %s(%d)\n", misdn_to_str_screen(bc->caller.screening), bc->caller.screening);
-               ast_channel_caller(chan)->id.number.presentation = misdn_to_ast_pres(bc->caller.presentation)
-                       | misdn_to_ast_screen(bc->caller.screening);
-
-               ast_set_callerid(chan, bc->caller.number, NULL, bc->caller.number);
-
-               misdn_cfg_get(bc->port, MISDN_CFG_APPEND_MSN_TO_CALLERID_TAG, &append_msn, sizeof(append_msn));
-               if (append_msn) {
-                       strncat(bc->incoming_cid_tag, "_", sizeof(bc->incoming_cid_tag) - strlen(bc->incoming_cid_tag) - 1);
-                       strncat(bc->incoming_cid_tag, bc->dialed.number, sizeof(bc->incoming_cid_tag) - strlen(bc->incoming_cid_tag) - 1);
-               }
-
-               ast_channel_lock(chan);
-               ast_channel_caller(chan)->id.tag = ast_strdup(bc->incoming_cid_tag);
-               ast_channel_unlock(chan);
-
-               if (!ast_strlen_zero(bc->redirecting.from.number)) {
-                       /* Add configured prefix to redirecting.from.number */
-                       misdn_add_number_prefix(bc->port, bc->redirecting.from.number_type, bc->redirecting.from.number, sizeof(bc->redirecting.from.number));
-
-                       /* Update asterisk channel redirecting information */
-                       misdn_copy_redirecting_to_ast(chan, &bc->redirecting, bc->incoming_cid_tag);
-               }
-
-               pbx_builtin_setvar_helper(chan, "TRANSFERCAPABILITY", ast_transfercapability2str(bc->capability));
-               ast_channel_transfercapability_set(chan, bc->capability);
-
-               switch (bc->capability) {
-               case INFO_CAPABILITY_DIGITAL_UNRESTRICTED:
-                       pbx_builtin_setvar_helper(chan, "CALLTYPE", "DIGITAL");
-                       break;
-               default:
-                       pbx_builtin_setvar_helper(chan, "CALLTYPE", "SPEECH");
-                       break;
-               }
-
-               if (!strstr(ch->allowed_bearers, "all")) {
-                       int i;
-
-                       for (i = 0; i < ARRAY_LEN(allowed_bearers_array); ++i) {
-                               if (allowed_bearers_array[i].cap == bc->capability) {
-                                       if (strstr(ch->allowed_bearers, allowed_bearers_array[i].name)) {
-                                               /* The bearer capability is allowed */
-                                               if (allowed_bearers_array[i].deprecated) {
-                                                       chan_misdn_log(0, bc->port, "%s in allowed_bearers list is deprecated\n",
-                                                               allowed_bearers_array[i].name);
-                                               }
-                                               break;
-                                       }
-                               }
-                       }
-                       if (i == ARRAY_LEN(allowed_bearers_array)) {
-                               /* We did not find the bearer capability */
-                               chan_misdn_log(0, bc->port, "Bearer capability not allowed: %s(%d)\n",
-                                       bearer2str(bc->capability), bc->capability);
-
-                               ch->state = MISDN_EXTCANTMATCH;
-                               chan_list_unref(ch, "BC not allowed, releasing call");
-                               bc->out_cause = AST_CAUSE_INCOMPATIBLE_DESTINATION;
-                               return RESPONSE_RELEASE_SETUP;
-                       }
-               }
-
-               /** queue new chan **/
-               cl_queue_chan(ch);
-
-               if (bc->fac_in.Function != Fac_None) {
-                       misdn_facility_ie_handler(event, bc, ch);
-               }
-
-               /* Check for Pickup Request first */
-               if (!strcmp(ast_channel_exten(chan), pickupexten)) {
-                       if (!ch->noautorespond_on_setup) {
-                               /* Sending SETUP_ACK */
-                               misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE);
-                       } else {
-                               ch->state = MISDN_INCOMING_SETUP;
-                       }
-                       if (ast_pickup_call(chan)) {
-                               hangup_chan(ch, bc);
-                       } else {
-                               ch->state = MISDN_CALLING_ACKNOWLEDGE;
-                               hangup_chan(ch, bc);
-                               ch->ast = NULL;
-                               break;
-                       }
-               }
-
-               /*
-                * added support for s extension hope it will help those poor cretains
-                * which haven't overlap dial.
-                */
-               misdn_cfg_get(bc->port, MISDN_CFG_ALWAYS_IMMEDIATE, &ai, sizeof(ai));
-               if (ai) {
-                       do_immediate_setup(bc, ch, chan);
-                       break;
-               }
-
-               /* check if we should jump into s when we have no dialed.number */
-               misdn_cfg_get(bc->port, MISDN_CFG_IMMEDIATE, &im, sizeof(im));
-               if (im && ast_strlen_zero(bc->dialed.number)) {
-                       do_immediate_setup(bc, ch, chan);
-                       break;
-               }
-
-               chan_misdn_log(5, bc->port, "CONTEXT:%s\n", ch->context);
-               if (!ast_canmatch_extension(ch->ast, ch->context, bc->dialed.number, 1, bc->caller.number)) {
-                       if (ast_exists_extension(ch->ast, ch->context, "i", 1, bc->caller.number)) {
-                               ast_log(LOG_WARNING,
-                                       "Extension '%s@%s' can never match. Jumping to 'i' extension. port:%d\n",
-                                       bc->dialed.number, ch->context, bc->port);
-                               pbx_builtin_setvar_helper(ch->ast, "INVALID_EXTEN", bc->dialed.number);
-                               ast_channel_exten_set(ch->ast, "i");
-                               misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE);
-                               ch->state = MISDN_DIALING;
-                               start_pbx(ch, bc, chan);
-                               break;
-                       }
-
-                       ast_log(LOG_WARNING,
-                               "Extension '%s@%s' can never match. Disconnecting. port:%d\n"
-                               "\tMaybe you want to add an 'i' extension to catch this case.\n",
-                               bc->dialed.number, ch->context, bc->port);
-                       if (bc->nt) {
-                               hanguptone_indicate(ch);
-                       }
-
-                       ch->state = MISDN_EXTCANTMATCH;
-                       bc->out_cause = AST_CAUSE_UNALLOCATED;
-
-                       misdn_lib_send_event(bc, bc->nt ? EVENT_RELEASE_COMPLETE : EVENT_RELEASE);
-                       break;
-               }
-
-               /* Whatever happens, when sending_complete is set or we are PTMP TE, we will definitely
-                * jump into the dialplan, when the dialed extension does not exist, the 's' extension
-                * will be used by Asterisk automatically. */
-               if (bc->sending_complete || (!bc->nt && !misdn_lib_is_ptp(bc->port))) {
-                       if (!ch->noautorespond_on_setup) {
-                               ch->state=MISDN_DIALING;
-                               misdn_lib_send_event(bc, EVENT_PROCEEDING);
-                       } else {
-                               ch->state = MISDN_INCOMING_SETUP;
-                       }
-                       start_pbx(ch, bc, chan);
-                       break;
-               }
-
-
-               /*
-                * When we are NT and overlapdial is set and if
-                * the number is empty, we wait for the ISDN timeout
-                * instead of our own timer.
-                */
-               if (ch->overlap_dial && bc->nt && !bc->dialed.number[0]) {
-                       wait_for_digits(ch, bc, chan);
-                       break;
-               }
-
-               /*
-                * If overlapdial we will definitely send a SETUP_ACKNOWLEDGE and wait for more
-                * Infos with a Interdigit Timeout.
-                * */
-               if (ch->overlap_dial) {
-                       ast_mutex_lock(&ch->overlap_tv_lock);
-                       ch->overlap_tv = ast_tvnow();
-                       ast_mutex_unlock(&ch->overlap_tv_lock);
-
-                       wait_for_digits(ch, bc, chan);
-                       if (ch->overlap_dial_task == -1) {
-                               ch->overlap_dial_task =
-                                       misdn_tasks_add_variable(ch->overlap_dial, misdn_overlap_dial_task, ch);
-                       }
-                       break;
-               }
-
-               /* If the extension does not exist and we're not TE_PTMP we wait for more digits
-                * without interdigit timeout.
-                * */
-               if (!ast_exists_extension(ch->ast, ch->context, bc->dialed.number, 1, bc->caller.number))  {
-                       wait_for_digits(ch, bc, chan);
-                       break;
-               }
-
-               /*
-                * If the extension exists let's just jump into it.
-                * */
-               if (ast_exists_extension(ch->ast, ch->context, bc->dialed.number, 1, bc->caller.number)) {
-                       misdn_lib_send_event(bc, bc->need_more_infos ? EVENT_SETUP_ACKNOWLEDGE : EVENT_PROCEEDING);
-                       ch->state = MISDN_DIALING;
-                       start_pbx(ch, bc, chan);
-                       break;
-               }
-               break;
-       }
-#if defined(AST_MISDN_ENHANCEMENTS)
-       case EVENT_REGISTER:
-               if (bc->fac_in.Function != Fac_None) {
-                       misdn_facility_ie_handler(event, bc, ch);
-               }
-               /*
-                * Shut down this connection immediately.
-                * The current design of chan_misdn data structures
-                * does not allow the proper handling of inbound call records
-                * without an assigned B channel.  Therefore, we cannot
-                * be the CCBS User-B party in a point-to-point setup.
-                */
-               bc->fac_out.Function = Fac_None;
-               bc->out_cause = AST_CAUSE_NORMAL_CLEARING;
-               misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE);
-               break;
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-       case EVENT_SETUP_ACKNOWLEDGE:
-               ch->state = MISDN_CALLING_ACKNOWLEDGE;
-
-               if (bc->channel) {
-                       update_name(ch->ast,bc->port,bc->channel);
-               }
-
-               if (bc->fac_in.Function != Fac_None) {
-                       misdn_facility_ie_handler(event, bc, ch);
-               }
-
-               if (!ast_strlen_zero(bc->infos_pending)) {
-                       /* TX Pending Infos */
-                       strncat(bc->dialed.number, bc->infos_pending, sizeof(bc->dialed.number) - strlen(bc->dialed.number) - 1);
-
-                       if (!ch->ast) {
-                               break;
-                       }
-                       ast_channel_exten_set(ch->ast, bc->dialed.number);
-                       ast_copy_string(bc->info_dad, bc->infos_pending, sizeof(bc->info_dad));
-                       ast_copy_string(bc->infos_pending, "", sizeof(bc->infos_pending));
-
-                       misdn_lib_send_event(bc, EVENT_INFORMATION);
-               }
-               break;
-       case EVENT_PROCEEDING:
-               if (misdn_cap_is_speech(bc->capability) &&
-                       misdn_inband_avail(bc)) {
-                       start_bc_tones(ch);
-               }
-
-               ch->state = MISDN_PROCEEDING;
-
-               if (bc->fac_in.Function != Fac_None) {
-                       misdn_facility_ie_handler(event, bc, ch);
-               }
-
-               if (!ch->ast) {
-                       break;
-               }
-
-               ast_queue_control(ch->ast, AST_CONTROL_PROCEEDING);
-               break;
-       case EVENT_PROGRESS:
-               if (bc->channel) {
-                       update_name(ch->ast, bc->port, bc->channel);
-               }
-
-               if (bc->fac_in.Function != Fac_None) {
-                       misdn_facility_ie_handler(event, bc, ch);
-               }
-
-               if (!bc->nt) {
-                       if (misdn_cap_is_speech(bc->capability) &&
-                               misdn_inband_avail(bc)) {
-                               start_bc_tones(ch);
-                       }
-
-                       ch->state = MISDN_PROGRESS;
-
-                       if (!ch->ast) {
-                               break;
-                       }
-                       ast_queue_control(ch->ast, AST_CONTROL_PROGRESS);
-               }
-               break;
-       case EVENT_ALERTING:
-               ch->state = MISDN_ALERTING;
-
-               if (!ch->ast) {
-                       break;
-               }
-
-               if (bc->fac_in.Function != Fac_None) {
-                       misdn_facility_ie_handler(event, bc, ch);
-               }
-
-               ast_queue_control(ch->ast, AST_CONTROL_RINGING);
-               ast_channel_lock(ch->ast);
-               ast_setstate(ch->ast, AST_STATE_RINGING);
-               ast_channel_unlock(ch->ast);
-
-               cb_log(7, bc->port, " --> Set State Ringing\n");
-
-               if (misdn_cap_is_speech(bc->capability) && misdn_inband_avail(bc)) {
-                       cb_log(1, bc->port, "Starting Tones, we have inband Data\n");
-                       start_bc_tones(ch);
-               } else {
-                       cb_log(3, bc->port, " --> We have no inband Data, the other end must create ringing\n");
-                       if (ch->far_alerting) {
-                               cb_log(1, bc->port, " --> The other end can not do ringing eh ?.. we must do all ourself..");
-                               start_bc_tones(ch);
-                               /*tone_indicate(ch, TONE_FAR_ALERTING);*/
-                       }
-               }
-               break;
-       case EVENT_CONNECT:
-               if (bc->fac_in.Function != Fac_None) {
-                       misdn_facility_ie_handler(event, bc, ch);
-               }
-#if defined(AST_MISDN_ENHANCEMENTS)
-               if (bc->div_leg_3_rx_wanted) {
-                       bc->div_leg_3_rx_wanted = 0;
-
-                       if (ch->ast) {
-                               struct ast_party_redirecting redirecting;
-
-                               ast_channel_redirecting(ch->ast)->to.number.presentation =
-                                       AST_PRES_RESTRICTED | AST_PRES_USER_NUMBER_UNSCREENED;
-                               ast_party_redirecting_init(&redirecting);
-                               ast_party_redirecting_copy(&redirecting, ast_channel_redirecting(ch->ast));
-
-                               /*
-                                * Reset any earlier private redirecting id representations and
-                                * make sure that it is invalidated at the remote end.
-                                */
-                               ast_party_id_reset(&redirecting.priv_orig);
-                               ast_party_id_reset(&redirecting.priv_from);
-                               ast_party_id_reset(&redirecting.priv_to);
-
-                               ast_channel_queue_redirecting_update(ch->ast, &redirecting, NULL);
-                               ast_party_redirecting_free(&redirecting);
-                       }
-               }
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-               /* we answer when we've got our very new L3 ID from the NT stack */
-               misdn_lib_send_event(bc, EVENT_CONNECT_ACKNOWLEDGE);
-
-               if (!ch->ast) {
-                       break;
-               }
-
-               stop_indicate(ch);
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-               if (ch->record_id != -1) {
-                       /*
-                        * We will delete the associated call completion
-                        * record since we now have a completed call.
-                        * We will not wait/depend on the network to tell
-                        * us to delete it.
-                        */
-                       AST_LIST_LOCK(&misdn_cc_records_db);
-                       cc_record = misdn_cc_find_by_id(ch->record_id);
-                       if (cc_record) {
-                               if (cc_record->ptp && cc_record->mode.ptp.bc) {
-                                       /* Close the call-completion signaling link */
-                                       cc_record->mode.ptp.bc->fac_out.Function = Fac_None;
-                                       cc_record->mode.ptp.bc->out_cause = AST_CAUSE_NORMAL_CLEARING;
-                                       misdn_lib_send_event(cc_record->mode.ptp.bc, EVENT_RELEASE_COMPLETE);
-                               }
-                               misdn_cc_delete(cc_record);
-                       }
-                       AST_LIST_UNLOCK(&misdn_cc_records_db);
-                       ch->record_id = -1;
-                       if (ch->peer) {
-                               misdn_cc_set_peer_var(ch->peer, MISDN_CC_RECORD_ID, "");
-
-                               ao2_ref(ch->peer, -1);
-                               ch->peer = NULL;
-                       }
-               }
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-               if (!ast_strlen_zero(bc->connected.number)) {
-                       /* Add configured prefix to connected.number */
-                       misdn_add_number_prefix(bc->port, bc->connected.number_type, bc->connected.number, sizeof(bc->connected.number));
-
-                       /* Update the connected line information on the other channel */
-                       misdn_update_remote_party(ch->ast, &bc->connected, AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER, bc->incoming_cid_tag);
-               }
-
-               ch->l3id = bc->l3_id;
-               ch->addr = bc->addr;
-
-               start_bc_tones(ch);
-
-               ch->state = MISDN_CONNECTED;
-
-               ast_queue_control(ch->ast, AST_CONTROL_ANSWER);
-               break;
-       case EVENT_CONNECT_ACKNOWLEDGE:
-               ch->l3id = bc->l3_id;
-               ch->addr = bc->addr;
-
-               start_bc_tones(ch);
-
-               ch->state = MISDN_CONNECTED;
-               break;
-       case EVENT_DISCONNECT:
-               /* we might not have an ch->ast ptr here anymore */
-               if (ch) {
-                       if (bc->fac_in.Function != Fac_None) {
-                               misdn_facility_ie_handler(event, bc, ch);
-                       }
-
-                       chan_misdn_log(3, bc->port, " --> org:%d nt:%d, inbandavail:%d state:%d\n", ch->originator, bc->nt, misdn_inband_avail(bc), ch->state);
-                       if (ch->originator == ORG_AST && !bc->nt && misdn_inband_avail(bc) && ch->state != MISDN_CONNECTED) {
-                               /* If there's inband information available (e.g. a
-                                  recorded message saying what was wrong with the
-                                  dialled number, or perhaps even giving an
-                                  alternative number, then play it instead of
-                                  immediately releasing the call */
-                               chan_misdn_log(1, bc->port, " --> Inband Info Avail, not sending RELEASE\n");
-
-                               ch->state = MISDN_DISCONNECTED;
-                               start_bc_tones(ch);
-
-                               if (ch->ast) {
-                                       ast_channel_hangupcause_set(ch->ast, bc->cause);
-                                       if (bc->cause == AST_CAUSE_USER_BUSY) {
-                                               ast_queue_control(ch->ast, AST_CONTROL_BUSY);
-                                       }
-                               }
-                               ch->need_busy = 0;
-                               break;
-                       }
-
-                       bc->need_disconnect = 0;
-                       stop_bc_tones(ch);
-
-                       /* Check for held channel, to implement transfer */
-                       held_ch = find_hold_call(bc);
-                       if (!held_ch || !ch->ast || misdn_attempt_transfer(ch, held_ch)) {
-                               hangup_chan(ch, bc);
-                       }
-               } else {
-                       held_ch = find_hold_call_l3(bc->l3_id);
-                       if (held_ch) {
-                               if (bc->fac_in.Function != Fac_None) {
-                                       misdn_facility_ie_handler(event, bc, held_ch);
-                               }
-
-                               if (held_ch->hold.state == MISDN_HOLD_ACTIVE) {
-                                       bc->need_disconnect = 0;
-
-#if defined(TRANSFER_ON_HELD_CALL_HANGUP)
-                                       /*
-                                        * Some phones disconnect the held call and the active call at the
-                                        * same time to do the transfer.  Unfortunately, either call could
-                                        * be disconnected first.
-                                        */
-                                       ch = find_hold_active_call(bc);
-                                       if (!ch || misdn_attempt_transfer(ch, held_ch)) {
-                                               held_ch->hold.state = MISDN_HOLD_DISCONNECT;
-                                               hangup_chan(held_ch, bc);
-                                       }
-#else
-                                       hangup_chan(held_ch, bc);
-#endif /* defined(TRANSFER_ON_HELD_CALL_HANGUP) */
-                               }
-                       }
-               }
-               if (held_ch) {
-                       chan_list_unref(held_ch, "Done with held call");
-               }
-               bc->out_cause = -1;
-               if (bc->need_release) {
-                       misdn_lib_send_event(bc, EVENT_RELEASE);
-               }
-               break;
-       case EVENT_RELEASE:
-               if (!ch) {
-                       ch = find_hold_call_l3(bc->l3_id);
-                       if (!ch) {
-                               chan_misdn_log(1, bc->port,
-                                       " --> no Ch, so we've already released. (%s)\n",
-                                       manager_isdn_get_info(event));
-                               return -1;
-                       }
-               }
-               if (bc->fac_in.Function != Fac_None) {
-                       misdn_facility_ie_handler(event, bc, ch);
-               }
-
-               bc->need_disconnect = 0;
-               bc->need_release = 0;
-
-               hangup_chan(ch, bc);
-               release_chan(ch, bc);
-               break;
-       case EVENT_RELEASE_COMPLETE:
-               if (!ch) {
-                       ch = find_hold_call_l3(bc->l3_id);
-               }
-
-               bc->need_disconnect = 0;
-               bc->need_release = 0;
-               bc->need_release_complete = 0;
-
-               if (ch) {
-                       if (bc->fac_in.Function != Fac_None) {
-                               misdn_facility_ie_handler(event, bc, ch);
-                       }
-
-                       stop_bc_tones(ch);
-                       hangup_chan(ch, bc);
-                       release_chan(ch, bc);
-               } else {
-#if defined(AST_MISDN_ENHANCEMENTS)
-                       /*
-                        * A call-completion signaling link established with
-                        * REGISTER does not have a struct chan_list record
-                        * associated with it.
-                        */
-                       AST_LIST_LOCK(&misdn_cc_records_db);
-                       cc_record = misdn_cc_find_by_bc(bc);
-                       if (cc_record) {
-                               /* The call-completion signaling link is closed. */
-                               misdn_cc_delete(cc_record);
-                       }
-                       AST_LIST_UNLOCK(&misdn_cc_records_db);
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-                       chan_misdn_log(1, bc->port,
-                               " --> no Ch, so we've already released. (%s)\n",
-                               manager_isdn_get_info(event));
-               }
-               break;
-       case EVENT_BCHAN_ERROR:
-       case EVENT_CLEANUP:
-               stop_bc_tones(ch);
-
-               switch (ch->state) {
-               case MISDN_CALLING:
-                       bc->cause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
-                       break;
-               default:
-                       break;
-               }
-
-               hangup_chan(ch, bc);
-               release_chan(ch, bc);
-               break;
-       case EVENT_TONE_GENERATE:
-       {
-               int tone_len = bc->tone_cnt;
-               struct ast_channel *ast = ch->ast;
-               void *tmp;
-               int res;
-               int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples);
-
-               chan_misdn_log(9, bc->port, "TONE_GEN: len:%d\n", tone_len);
-
-               if (!ast) {
-                       break;
-               }
-
-               if (!ast_channel_generator(ast)) {
-                       break;
-               }
-
-               tmp = ast_channel_generatordata(ast);
-               ast_channel_generatordata_set(ast, NULL);
-               generate = ast_channel_generator(ast)->generate;
-
-               if (tone_len < 0 || tone_len > 512) {
-                       ast_log(LOG_NOTICE, "TONE_GEN: len was %d, set to 128\n", tone_len);
-                       tone_len = 128;
-               }
-
-               res = generate(ast, tmp, tone_len, tone_len);
-               ast_channel_generatordata_set(ast, tmp);
-
-               if (res) {
-                       ast_log(LOG_WARNING, "Auto-deactivating generator\n");
-                       ast_deactivate_generator(ast);
-               } else {
-                       bc->tone_cnt = 0;
-               }
-               break;
-       }
-       case EVENT_BCHAN_DATA:
-               if (ch->bc->AOCD_need_export) {
-                       export_aoc_vars(ch->originator, ch->ast, ch->bc);
-               }
-               if (!misdn_cap_is_speech(ch->bc->capability)) {
-                       struct ast_frame frame;
-
-                       /* In Data Modes we queue frames */
-                       memset(&frame, 0, sizeof(frame));
-                       frame.frametype = AST_FRAME_VOICE; /* we have no data frames yet */
-                       frame.subclass.format = ast_format_alaw;
-                       frame.datalen = bc->bframe_len;
-                       frame.samples = bc->bframe_len;
-                       frame.mallocd = 0;
-                       frame.offset = 0;
-                       frame.delivery = ast_tv(0, 0);
-                       frame.src = NULL;
-                       frame.data.ptr = bc->bframe;
-
-                       if (ch->ast) {
-                               ast_queue_frame(ch->ast, &frame);
-                       }
-               } else {
-                       struct pollfd pfd = { .fd = ch->pipe[1], .events = POLLOUT };
-                       int t;
-
-                       t = ast_poll(&pfd, 1, 0);
-
-                       if (t < 0) {
-                               chan_misdn_log(-1, bc->port, "poll() error (err=%s)\n", strerror(errno));
-                               break;
-                       }
-                       if (!t) {
-                               chan_misdn_log(9, bc->port, "poll() timed out\n");
-                               break;
-                       }
-
-                       if (pfd.revents & POLLOUT) {
-                               chan_misdn_log(9, bc->port, "writing %d bytes to asterisk\n", bc->bframe_len);
-                               if (write(ch->pipe[1], bc->bframe, bc->bframe_len) <= 0) {
-                                       chan_misdn_log(0, bc->port, "Write returned <=0 (err=%s) --> hanging up channel\n", strerror(errno));
-
-                                       stop_bc_tones(ch);
-                                       hangup_chan(ch, bc);
-                                       release_chan(ch, bc);
-                               }
-                       } else {
-                               chan_misdn_log(1, bc->port, "Write Pipe full!\n");
-                       }
-               }
-               break;
-       case EVENT_TIMEOUT:
-               if (ch && bc) {
-                       chan_misdn_log(1, bc->port, "--> state: %s\n", misdn_get_ch_state(ch));
-               }
-
-               switch (ch->state) {
-               case MISDN_DIALING:
-               case MISDN_PROGRESS:
-                       if (bc->nt && !ch->nttimeout) {
-                               break;
-                       }
-                       /* fall-through */
-               case MISDN_CALLING:
-               case MISDN_ALERTING:
-               case MISDN_PROCEEDING:
-               case MISDN_CALLING_ACKNOWLEDGE:
-                       if (bc->nt) {
-                               bc->progress_indicator = INFO_PI_INBAND_AVAILABLE;
-                               hanguptone_indicate(ch);
-                       }
-
-                       bc->out_cause = AST_CAUSE_UNALLOCATED;
-                       misdn_lib_send_event(bc, EVENT_DISCONNECT);
-                       break;
-               case MISDN_WAITING4DIGS:
-                       if (bc->nt) {
-                               bc->progress_indicator = INFO_PI_INBAND_AVAILABLE;
-                               bc->out_cause = AST_CAUSE_UNALLOCATED;
-                               hanguptone_indicate(ch);
-                               misdn_lib_send_event(bc, EVENT_DISCONNECT);
-                       } else {
-                               bc->out_cause = AST_CAUSE_NORMAL_CLEARING;
-                               misdn_lib_send_event(bc, EVENT_RELEASE);
-                       }
-                       break;
-               case MISDN_CLEANING:
-                       chan_misdn_log(1, bc->port, " --> in state cleaning .. so ignoring, the stack should clean it for us\n");
-                       break;
-               default:
-                       misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE);
-                       break;
-               }
-               break;
-
-       /****************************/
-       /** Supplementary Services **/
-       /****************************/
-       case EVENT_RETRIEVE:
-               if (!ch) {
-                       chan_misdn_log(4, bc->port, " --> no CH, searching for held call\n");
-                       ch = find_hold_call_l3(bc->l3_id);
-                       if (!ch || ch->hold.state != MISDN_HOLD_ACTIVE) {
-                               ast_log(LOG_WARNING, "No held call found, cannot Retrieve\n");
-                               misdn_lib_send_event(bc, EVENT_RETRIEVE_REJECT);
-                               break;
-                       }
-               }
-
-               /* remember the channel again */
-               ch->bc = bc;
-
-               ch->hold.state = MISDN_HOLD_IDLE;
-               ch->hold.port = 0;
-               ch->hold.channel = 0;
-
-               ast_queue_unhold(ch->ast);
-
-               if (misdn_lib_send_event(bc, EVENT_RETRIEVE_ACKNOWLEDGE) < 0) {
-                       chan_misdn_log(4, bc->port, " --> RETRIEVE_ACK failed\n");
-                       misdn_lib_send_event(bc, EVENT_RETRIEVE_REJECT);
-               }
-               break;
-       case EVENT_HOLD:
-       {
-               int hold_allowed;
-               RAII_VAR(struct ast_channel *, bridged, NULL, ast_channel_cleanup);
-
-               misdn_cfg_get(bc->port, MISDN_CFG_HOLD_ALLOWED, &hold_allowed, sizeof(hold_allowed));
-               if (!hold_allowed) {
-                       chan_misdn_log(-1, bc->port, "Hold not allowed this port.\n");
-                       misdn_lib_send_event(bc, EVENT_HOLD_REJECT);
-                       break;
-               }
-
-               bridged = ast_channel_bridge_peer(ch->ast);
-               if (bridged) {
-                       chan_misdn_log(2, bc->port, "Bridge Partner is of type: %s\n", ast_channel_tech(bridged)->type);
-                       ch->l3id = bc->l3_id;
-
-                       /* forget the channel now */
-                       ch->bc = NULL;
-                       ch->hold.state = MISDN_HOLD_ACTIVE;
-                       ch->hold.port = bc->port;
-                       ch->hold.channel = bc->channel;
-
-                       ast_queue_hold(ch->ast, NULL);
-
-                       misdn_lib_send_event(bc, EVENT_HOLD_ACKNOWLEDGE);
-               } else {
-                       misdn_lib_send_event(bc, EVENT_HOLD_REJECT);
-                       chan_misdn_log(0, bc->port, "We aren't bridged to anybody\n");
-               }
-               break;
-       }
-       case EVENT_NOTIFY:
-               if (bc->redirecting.to_changed) {
-                       /* Add configured prefix to redirecting.to.number */
-                       misdn_add_number_prefix(bc->port, bc->redirecting.to.number_type,
-                               bc->redirecting.to.number, sizeof(bc->redirecting.to.number));
-               }
-               switch (bc->notify_description_code) {
-               case mISDN_NOTIFY_CODE_DIVERSION_ACTIVATED:
-                       /* Ignore for now. */
-                       bc->redirecting.to_changed = 0;
-                       break;
-               case mISDN_NOTIFY_CODE_CALL_IS_DIVERTING:
-               {
-                       struct ast_party_redirecting redirecting;
-
-                       if (!bc->redirecting.to_changed) {
-                               break;
-                       }
-                       bc->redirecting.to_changed = 0;
-                       if (!ch || !ch->ast) {
-                               break;
-                       }
-                       switch (ch->state) {
-                       case MISDN_ALERTING:
-                               /* Call is deflecting after we have seen an ALERTING message */
-                               bc->redirecting.reason = mISDN_REDIRECTING_REASON_NO_REPLY;
-                               break;
-                       default:
-                               /* Call is deflecting for call forwarding unconditional or busy reason. */
-                               bc->redirecting.reason = mISDN_REDIRECTING_REASON_UNKNOWN;
-                               break;
-                       }
-                       misdn_copy_redirecting_to_ast(ch->ast, &bc->redirecting, bc->incoming_cid_tag);
-                       ast_party_redirecting_init(&redirecting);
-                       ast_party_redirecting_copy(&redirecting, ast_channel_redirecting(ch->ast));
-
-                       /*
-                        * Reset any earlier private redirecting id representations and
-                        * make sure that it is invalidated at the remote end.
-                        */
-                       ast_party_id_reset(&redirecting.priv_orig);
-                       ast_party_id_reset(&redirecting.priv_from);
-                       ast_party_id_reset(&redirecting.priv_to);
-
-                       ast_channel_queue_redirecting_update(ch->ast, &redirecting, NULL);
-                       ast_party_redirecting_free(&redirecting);
-                       break;
-               }
-               case mISDN_NOTIFY_CODE_CALL_TRANSFER_ALERTING:
-                       /*
-                        * It would be preferable to update the connected line information
-                        * only when the message callStatus is active.  However, the
-                        * optional redirection number may not be present in the active
-                        * message if an alerting message were received earlier.
-                        *
-                        * The consequences if we wind up sending two updates is benign.
-                        * The other end will think that it got transferred twice.
-                        */
-                       if (!bc->redirecting.to_changed) {
-                               break;
-                       }
-                       bc->redirecting.to_changed = 0;
-                       if (!ch || !ch->ast) {
-                               break;
-                       }
-                       misdn_update_remote_party(ch->ast, &bc->redirecting.to,
-                               AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER_ALERTING,
-                               bc->incoming_cid_tag);
-                       break;
-               case mISDN_NOTIFY_CODE_CALL_TRANSFER_ACTIVE:
-                       if (!bc->redirecting.to_changed) {
-                               break;
-                       }
-                       bc->redirecting.to_changed = 0;
-                       if (!ch || !ch->ast) {
-                               break;
-                       }
-                       misdn_update_remote_party(ch->ast, &bc->redirecting.to,
-                               AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER, bc->incoming_cid_tag);
-                       break;
-               default:
-                       bc->redirecting.to_changed = 0;
-                       chan_misdn_log(0, bc->port," --> not yet handled: notify code:0x%02X\n",
-                               bc->notify_description_code);
-                       break;
-               }
-               bc->notify_description_code = mISDN_NOTIFY_CODE_INVALID;
-               break;
-       case EVENT_FACILITY:
-               if (bc->fac_in.Function == Fac_None) {
-                       /* This is a FACILITY message so we MUST have a facility ie */
-                       chan_misdn_log(0, bc->port," --> Missing facility ie or unknown facility ie contents.\n");
-               } else {
-                       misdn_facility_ie_handler(event, bc, ch);
-               }
-
-               /* In case it came in on a FACILITY message and we did not handle it. */
-               bc->redirecting.to_changed = 0;
-               bc->notify_description_code = mISDN_NOTIFY_CODE_INVALID;
-               break;
-       case EVENT_RESTART:
-               if (!bc->dummy) {
-                       stop_bc_tones(ch);
-                       release_chan(ch, bc);
-               }
-               break;
-       default:
-               chan_misdn_log(1, 0, "Got Unknown Event\n");
-               break;
-       }
-
-       if (ch) {
-               chan_list_unref(ch, "cb_event complete OK");
-       }
-       return RESPONSE_OK;
-}
-
-/** TE STUFF END **/
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-/*!
- * \internal
- * \brief Get call completion record information.
- *
- * \param chan Asterisk channel to operate upon. (Not used)
- * \param function_name Name of the function that called us.
- * \param function_args Argument string passed to function (Could be NULL)
- * \param buf Buffer to put returned string.
- * \param size Size of the supplied buffer including the null terminator.
- *
- * \retval 0 on success.
- * \retval -1 on error.
- */
-static int misdn_cc_read(struct ast_channel *chan, const char *function_name,
-       char *function_args, char *buf, size_t size)
-{
-       char *parse;
-       struct misdn_cc_record *cc_record;
-
-       AST_DECLARE_APP_ARGS(args,
-               AST_APP_ARG(cc_id);             /* Call completion record ID value. */
-               AST_APP_ARG(get_name);  /* Name of what to get */
-               AST_APP_ARG(other);             /* Any extraneous garbage arguments */
-       );
-
-       /* Ensure that the buffer is empty */
-       *buf = 0;
-
-       if (ast_strlen_zero(function_args)) {
-               ast_log(LOG_ERROR, "Function '%s' requires arguments.\n", function_name);
-               return -1;
-       }
-
-       parse = ast_strdupa(function_args);
-       AST_STANDARD_APP_ARGS(args, parse);
-
-       if (!args.argc || ast_strlen_zero(args.cc_id)) {
-               ast_log(LOG_ERROR, "Function '%s' missing call completion record ID.\n",
-                       function_name);
-               return -1;
-       }
-       if (!isdigit(*args.cc_id)) {
-               ast_log(LOG_ERROR, "Function '%s' call completion record ID must be numeric.\n",
-                       function_name);
-               return -1;
-       }
-
-       if (ast_strlen_zero(args.get_name)) {
-               ast_log(LOG_ERROR, "Function '%s' missing what-to-get parameter.\n",
-                       function_name);
-               return -1;
-       }
-
-       AST_LIST_LOCK(&misdn_cc_records_db);
-       cc_record = misdn_cc_find_by_id(atoi(args.cc_id));
-       if (cc_record) {
-               if (!strcasecmp("a-all", args.get_name)) {
-                       snprintf(buf, size, "\"%s\" <%s>", cc_record->redial.caller.name,
-                               cc_record->redial.caller.number);
-               } else if (!strcasecmp("a-name", args.get_name)) {
-                       ast_copy_string(buf, cc_record->redial.caller.name, size);
-               } else if (!strncasecmp("a-num", args.get_name, 5)) {
-                       ast_copy_string(buf, cc_record->redial.caller.number, size);
-               } else if (!strcasecmp("a-ton", args.get_name)) {
-                       snprintf(buf, size, "%d",
-                               misdn_to_ast_plan(cc_record->redial.caller.number_plan)
-                               | misdn_to_ast_ton(cc_record->redial.caller.number_type));
-               } else if (!strncasecmp("a-pres", args.get_name, 6)) {
-                       ast_copy_string(buf, ast_named_caller_presentation(
-                               misdn_to_ast_pres(cc_record->redial.caller.presentation)
-                               | misdn_to_ast_screen(cc_record->redial.caller.screening)), size);
-               } else if (!strcasecmp("a-busy", args.get_name)) {
-                       ast_copy_string(buf, cc_record->party_a_free ? "no" : "yes", size);
-               } else if (!strncasecmp("b-num", args.get_name, 5)) {
-                       ast_copy_string(buf, cc_record->redial.dialed.number, size);
-               } else if (!strcasecmp("b-ton", args.get_name)) {
-                       snprintf(buf, size, "%d",
-                               misdn_to_ast_plan(cc_record->redial.dialed.number_plan)
-                               | misdn_to_ast_ton(cc_record->redial.dialed.number_type));
-               } else if (!strcasecmp("port", args.get_name)) {
-                       snprintf(buf, size, "%d", cc_record->port);
-               } else if (!strcasecmp("available-notify-priority", args.get_name)) {
-                       snprintf(buf, size, "%d", cc_record->remote_user_free.priority);
-               } else if (!strcasecmp("available-notify-exten", args.get_name)) {
-                       ast_copy_string(buf, cc_record->remote_user_free.exten, size);
-               } else if (!strcasecmp("available-notify-context", args.get_name)) {
-                       ast_copy_string(buf, cc_record->remote_user_free.context, size);
-               } else if (!strcasecmp("busy-notify-priority", args.get_name)) {
-                       snprintf(buf, size, "%d", cc_record->b_free.priority);
-               } else if (!strcasecmp("busy-notify-exten", args.get_name)) {
-                       ast_copy_string(buf, cc_record->b_free.exten, size);
-               } else if (!strcasecmp("busy-notify-context", args.get_name)) {
-                       ast_copy_string(buf, cc_record->b_free.context, size);
-               } else {
-                       AST_LIST_UNLOCK(&misdn_cc_records_db);
-                       ast_log(LOG_ERROR, "Function '%s': Unknown what-to-get '%s'.\n", function_name, args.get_name);
-                       return -1;
-               }
-       }
-       AST_LIST_UNLOCK(&misdn_cc_records_db);
-
-       return 0;
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-static struct ast_custom_function misdn_cc_function = {
-       .name = "mISDN_CC",
-       .synopsis = "Get call completion record information.",
-       .syntax = "mISDN_CC(${MISDN_CC_RECORD_ID},<what-to-get>)",
-       .desc =
-               "mISDN_CC(${MISDN_CC_RECORD_ID},<what-to-get>)\n"
-               "The following can be retrieved:\n"
-               "\"a-num\", \"a-name\", \"a-all\", \"a-ton\", \"a-pres\", \"a-busy\",\n"
-               "\"b-num\", \"b-ton\", \"port\",\n"
-               "  User-A is available for call completion:\n"
-               "    \"available-notify-priority\",\n"
-               "    \"available-notify-exten\",\n"
-               "    \"available-notify-context\",\n"
-               "  User-A is busy:\n"
-               "    \"busy-notify-priority\",\n"
-               "    \"busy-notify-exten\",\n"
-               "    \"busy-notify-context\"\n",
-       .read = misdn_cc_read,
-};
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-/******************************************
- *
- *   Asterisk Channel Endpoint END
- *
- *
- *******************************************/
-
-
-
-static int unload_module(void)
-{
-       /* First, take us out of the channel loop */
-       ast_verb(0, "-- Unregistering mISDN Channel Driver --\n");
-
-       misdn_tasks_destroy();
-
-       if (!g_config_initialized) {
-               return 0;
-       }
-
-       ast_cli_unregister_multiple(chan_misdn_clis, sizeof(chan_misdn_clis) / sizeof(struct ast_cli_entry));
-
-       /* ast_unregister_application("misdn_crypt"); */
-       ast_unregister_application("misdn_set_opt");
-       ast_unregister_application("misdn_facility");
-       ast_unregister_application("misdn_check_l2l1");
-#if defined(AST_MISDN_ENHANCEMENTS)
-       ast_unregister_application(misdn_command_name);
-       ast_custom_function_unregister(&misdn_cc_function);
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-       ast_channel_unregister(&misdn_tech);
-
-       free_robin_list();
-       misdn_cfg_destroy();
-       misdn_lib_destroy();
-
-       ast_free(misdn_out_calls);
-       ast_free(misdn_in_calls);
-       ast_free(misdn_debug_only);
-       ast_free(misdn_ports);
-       ast_free(misdn_debug);
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-       misdn_cc_destroy();
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-       ao2_cleanup(misdn_tech.capabilities);
-       misdn_tech.capabilities = NULL;
-
-       return 0;
-}
-
-/*!
- * \brief Load the module
- *
- * Module loading including tests for configuration or dependencies.
- * This function can return AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_DECLINE,
- * or AST_MODULE_LOAD_SUCCESS. If a dependency or environment variable fails
- * tests return AST_MODULE_LOAD_FAILURE. If the module can not load the
- * configuration file or other non-critical problem return
- * AST_MODULE_LOAD_DECLINE. On success return AST_MODULE_LOAD_SUCCESS.
- */
-static int load_module(void)
-{
-       int i, port;
-       int ntflags = 0, ntkc = 0;
-       char ports[256] = "";
-       char tempbuf[BUFFERSIZE + 1];
-       char ntfile[BUFFERSIZE + 1];
-       struct misdn_lib_iface iface = {
-               .cb_event = cb_events,
-               .cb_log = chan_misdn_log,
-               .cb_jb_empty = chan_misdn_jb_empty,
-       };
-
-
-       if (!(misdn_tech.capabilities = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
-               return AST_MODULE_LOAD_DECLINE;
-       }
-       ast_format_cap_append(misdn_tech.capabilities, ast_format_alaw, 0);
-
-       max_ports = misdn_lib_maxports_get();
-
-       if (max_ports <= 0) {
-               ast_log(LOG_ERROR, "Unable to initialize mISDN\n");
-               return AST_MODULE_LOAD_DECLINE;
-       }
-
-       if (misdn_cfg_init(max_ports, 0)) {
-               ast_log(LOG_ERROR, "Unable to initialize misdn_config.\n");
-               return AST_MODULE_LOAD_DECLINE;
-       }
-       g_config_initialized = 1;
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-       misdn_cc_init();
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-       misdn_debug = ast_malloc(sizeof(int) * (max_ports + 1));
-       if (!misdn_debug) {
-               ast_log(LOG_ERROR, "Out of memory for misdn_debug\n");
-               return AST_MODULE_LOAD_DECLINE;
-       }
-       misdn_ports = ast_malloc(sizeof(int) * (max_ports + 1));
-       if (!misdn_ports) {
-               ast_free(misdn_debug);
-               ast_log(LOG_ERROR, "Out of memory for misdn_ports\n");
-               return AST_MODULE_LOAD_DECLINE;
-       }
-       misdn_cfg_get(0, MISDN_GEN_DEBUG, &misdn_debug[0], sizeof(misdn_debug[0]));
-       for (i = 1; i <= max_ports; i++) {
-               misdn_debug[i] = misdn_debug[0];
-               misdn_ports[i] = i;
-       }
-       *misdn_ports = 0;
-       misdn_debug_only = ast_calloc(max_ports + 1, sizeof(int));
-       if (!misdn_debug_only) {
-               ast_free(misdn_ports);
-               ast_free(misdn_debug);
-               ast_log(LOG_ERROR, "Out of memory for misdn_debug_only\n");
-               return AST_MODULE_LOAD_DECLINE;
-       }
-
-       misdn_cfg_get(0, MISDN_GEN_TRACEFILE, tempbuf, sizeof(tempbuf));
-       if (!ast_strlen_zero(tempbuf)) {
-               tracing = 1;
-       }
-
-       misdn_in_calls = ast_malloc(sizeof(int) * (max_ports + 1));
-       if (!misdn_in_calls) {
-               ast_free(misdn_debug_only);
-               ast_free(misdn_ports);
-               ast_free(misdn_debug);
-               ast_log(LOG_ERROR, "Out of memory for misdn_in_calls\n");
-               return AST_MODULE_LOAD_DECLINE;
-       }
-       misdn_out_calls = ast_malloc(sizeof(int) * (max_ports + 1));
-       if (!misdn_out_calls) {
-               ast_free(misdn_in_calls);
-               ast_free(misdn_debug_only);
-               ast_free(misdn_ports);
-               ast_free(misdn_debug);
-               ast_log(LOG_ERROR, "Out of memory for misdn_out_calls\n");
-               return AST_MODULE_LOAD_DECLINE;
-       }
-
-       for (i = 1; i <= max_ports; i++) {
-               misdn_in_calls[i] = 0;
-               misdn_out_calls[i] = 0;
-       }
-
-       ast_mutex_init(&cl_te_lock);
-       ast_mutex_init(&release_lock);
-
-       misdn_cfg_update_ptp();
-       misdn_cfg_get_ports_string(ports);
-
-       if (!ast_strlen_zero(ports)) {
-               chan_misdn_log(0, 0, "Got: %s from get_ports\n", ports);
-       }
-       if (misdn_lib_init(ports, &iface, NULL)) {
-               chan_misdn_log(0, 0, "No te ports initialized\n");
-       }
-
-       misdn_cfg_get(0, MISDN_GEN_NTDEBUGFLAGS, &ntflags, sizeof(ntflags));
-       misdn_cfg_get(0, MISDN_GEN_NTDEBUGFILE, &ntfile, sizeof(ntfile));
-       misdn_cfg_get(0, MISDN_GEN_NTKEEPCALLS, &ntkc, sizeof(ntkc));
-
-       misdn_lib_nt_keepcalls(ntkc);
-       misdn_lib_nt_debug_init(ntflags, ntfile);
-
-       if (ast_channel_register(&misdn_tech)) {
-               ast_log(LOG_ERROR, "Unable to register channel class %s\n", misdn_type);
-               unload_module();
-               return AST_MODULE_LOAD_DECLINE;
-       }
-
-       ast_cli_register_multiple(chan_misdn_clis, sizeof(chan_misdn_clis) / sizeof(struct ast_cli_entry));
-
-       ast_register_application("misdn_set_opt", misdn_set_opt_exec, "misdn_set_opt",
-               "misdn_set_opt(:<opt><optarg>:<opt><optarg>...):\n"
-               "Sets mISDN opts. and optargs\n"
-               "\n"
-               "The available options are:\n"
-               "    a - Have Asterisk detect DTMF tones on called channel\n"
-               "    c - Make crypted outgoing call, optarg is keyindex\n"
-               "    d - Send display text to called phone, text is the optarg\n"
-               "    e - Perform echo cancellation on this channel,\n"
-               "        takes taps as optarg (32,64,128,256)\n"
-               "   e! - Disable echo cancellation on this channel\n"
-               "    f - Enable fax detection\n"
-               "    h - Make digital outgoing call\n"
-               "   h1 - Make HDLC mode digital outgoing call\n"
-               "    i - Ignore detected DTMF tones, don't signal them to Asterisk,\n"
-               "        they will be transported inband.\n"
-               "   jb - Set jitter buffer length, optarg is length\n"
-               "   jt - Set jitter buffer upper threshold, optarg is threshold\n"
-               "   jn - Disable jitter buffer\n"
-               "    n - Disable mISDN DSP on channel.\n"
-               "        Disables: echo cancel, DTMF detection, and volume control.\n"
-               "    p - Caller ID presentation,\n"
-               "        optarg is either 'allowed' or 'restricted'\n"
-               "    s - Send Non-inband DTMF as inband\n"
-               "   vr - Rx gain control, optarg is gain\n"
-               "   vt - Tx gain control, optarg is gain\n"
-               );
-
-
-       ast_register_application("misdn_facility", misdn_facility_exec, "misdn_facility",
-               "misdn_facility(<FACILITY_TYPE>|<ARG1>|..)\n"
-               "Sends the Facility Message FACILITY_TYPE with \n"
-               "the given Arguments to the current ISDN Channel\n"
-               "Supported Facilities are:\n"
-               "\n"
-               "type=calldeflect args=Nr where to deflect\n"
-#if defined(AST_MISDN_ENHANCEMENTS)
-               "type=callrerouting args=Nr where to deflect\n"
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-               );
-
-
-       ast_register_application("misdn_check_l2l1", misdn_check_l2l1, "misdn_check_l2l1",
-               "misdn_check_l2l1(<port>||g:<groupname>,timeout)\n"
-               "Checks if the L2 and L1 are up on either the given <port> or\n"
-               "on the ports in the group with <groupname>\n"
-               "If the L1/L2 are down, check_l2l1 gets up the L1/L2 and waits\n"
-               "for <timeout> seconds that this happens. Otherwise, nothing happens\n"
-               "\n"
-               "This application, ensures the L1/L2 state of the Ports in a group\n"
-               "it is intended to make the pmp_l1_check option redundant and to\n"
-               "fix a buggy switch config from your provider\n"
-               "\n"
-               "a sample dialplan would look like:\n\n"
-               "exten => _X.,1,misdn_check_l2l1(g:out|2)\n"
-               "exten => _X.,n,dial(mISDN/g:out/${EXTEN})\n"
-               );
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-       ast_register_application(misdn_command_name, misdn_command_exec, misdn_command_name,
-               "misdn_command(<command>[,<options>])\n"
-               "The following commands are defined:\n"
-               "cc-initialize\n"
-               "  Setup mISDN support for call completion\n"
-               "  Must call before doing any Dial() involving call completion.\n"
-               "ccnr-request,${MISDN_CC_RECORD_ID},<notify-context>,<user-a-extension>,<priority>\n"
-               "  Request Call Completion No Reply activation\n"
-               "ccbs-request,${MISDN_CC_RECORD_ID},<notify-context>,<user-a-extension>,<priority>\n"
-               "  Request Call Completion Busy Subscriber activation\n"
-               "cc-b-free,${MISDN_CC_RECORD_ID},<notify-context>,<user-a-extension>,<priority>\n"
-               "  Set the dialplan location to notify when User-B is available but User-A is busy.\n"
-               "  Setting this dialplan location is optional.\n"
-               "cc-a-busy,${MISDN_CC_RECORD_ID},<yes/no>\n"
-               "  Set the busy status of call completion User-A\n"
-               "cc-deactivate,${MISDN_CC_RECORD_ID}\n"
-               "  Deactivate the identified call completion request\n"
-               "\n"
-               "MISDN_CC_RECORD_ID is set when Dial() returns and call completion is possible\n"
-               "MISDN_CC_STATUS is set to ACTIVATED or ERROR after the call completion\n"
-               "activation request.\n"
-               "MISDN_ERROR_MSG is set to a descriptive message on error.\n"
-               );
-
-       ast_custom_function_register(&misdn_cc_function);
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-       misdn_cfg_get(0, MISDN_GEN_TRACEFILE, global_tracefile, sizeof(global_tracefile));
-
-       /* start the l1 watchers */
-
-       for (port = misdn_cfg_get_next_port(0); port >= 0; port = misdn_cfg_get_next_port(port)) {
-               int l1timeout;
-               misdn_cfg_get(port, MISDN_CFG_L1_TIMEOUT, &l1timeout, sizeof(l1timeout));
-               if (l1timeout) {
-                       chan_misdn_log(4, 0, "Adding L1watcher task: port:%d timeout:%ds\n", port, l1timeout);
-                       misdn_tasks_add(l1timeout * 1000, misdn_l1_task, &misdn_ports[port]);
-               }
-       }
-
-       chan_misdn_log(0, 0, "-- mISDN Channel Driver Registered --\n");
-
-       return 0;
-}
-
-
-
-static int reload(void)
-{
-       reload_config();
-
-       return 0;
-}
-
-/*** SOME APPS ;)***/
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-/*!
-* \brief misdn_command arguments container.
-*/
-AST_DEFINE_APP_ARGS_TYPE(misdn_command_args,
-       AST_APP_ARG(name);                      /* Subcommand name */
-       AST_APP_ARG(arg)[10 + 1];       /* Subcommand arguments */
-);
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-static void misdn_cc_caller_destroy(void *obj)
-{
-       /* oh snap! */
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-static struct misdn_cc_caller *misdn_cc_caller_alloc(struct ast_channel *chan)
-{
-       struct misdn_cc_caller *cc_caller;
-
-       if (!(cc_caller = ao2_alloc(sizeof(*cc_caller), misdn_cc_caller_destroy))) {
-               return NULL;
-       }
-
-       cc_caller->chan = chan;
-
-       return cc_caller;
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-/*!
- * \internal
- * \brief misdn_command(cc-initialize) subcommand handler
- *
- * \param chan Asterisk channel to operate upon.
- * \param subcommand Arguments for the subcommand
- *
- * \retval 0 on success.
- * \retval -1 on error.
- */
-static int misdn_command_cc_initialize(struct ast_channel *chan, struct misdn_command_args *subcommand)
-{
-       struct misdn_cc_caller *cc_caller;
-       struct ast_datastore *datastore;
-
-       if (!(cc_caller = misdn_cc_caller_alloc(chan))) {
-               return -1;
-       }
-
-       if (!(datastore = ast_datastore_alloc(&misdn_cc_ds_info, NULL))) {
-               ao2_ref(cc_caller, -1);
-               return -1;
-       }
-
-       ast_channel_lock(chan);
-
-       /* Inherit reference */
-       datastore->data = cc_caller;
-       cc_caller = NULL;
-
-       datastore->inheritance = DATASTORE_INHERIT_FOREVER;
-
-       ast_channel_datastore_add(chan, datastore);
-
-       ast_channel_unlock(chan);
-
-       return 0;
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-/*!
- * \internal
- * \brief misdn_command(cc-deactivate) subcommand handler
- *
- * \details
- * misdn_command(cc-deactivate,${MISDN_CC_RECORD_ID})
- * Deactivate a call completion service instance.
- *
- * \param chan Asterisk channel to operate upon.
- * \param subcommand Arguments for the subcommand
- *
- * \retval 0 on success.
- * \retval -1 on error.
- */
-static int misdn_command_cc_deactivate(struct ast_channel *chan, struct misdn_command_args *subcommand)
-{
-       long record_id;
-       const char *error_str;
-       struct misdn_cc_record *cc_record;
-       struct misdn_bchannel *bc;
-       struct misdn_bchannel dummy;
-
-       static const char cmd_help[] = "%s(%s,${MISDN_CC_RECORD_ID})\n";
-
-       if (ast_strlen_zero(subcommand->arg[0]) || !isdigit(*subcommand->arg[0])) {
-               ast_log(LOG_WARNING, cmd_help, misdn_command_name, subcommand->name);
-               return -1;
-       }
-       record_id = atol(subcommand->arg[0]);
-
-       AST_LIST_LOCK(&misdn_cc_records_db);
-       cc_record = misdn_cc_find_by_id(record_id);
-       if (cc_record && 0 <= cc_record->port) {
-               if (cc_record->ptp) {
-                       if (cc_record->mode.ptp.bc) {
-                               /* Close the call-completion signaling link */
-                               bc = cc_record->mode.ptp.bc;
-                               bc->fac_out.Function = Fac_None;
-                               bc->out_cause = AST_CAUSE_NORMAL_CLEARING;
-                               misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE);
-                       }
-                       misdn_cc_delete(cc_record);
-               } else if (cc_record->activated) {
-                       cc_record->error_code = FacError_None;
-                       cc_record->reject_code = FacReject_None;
-                       cc_record->invoke_id = ++misdn_invoke_id;
-                       cc_record->outstanding_message = 1;
-
-                       /* Build message */
-                       misdn_make_dummy(&dummy, cc_record->port, 0, misdn_lib_port_is_nt(cc_record->port), 0);
-                       dummy.fac_out.Function = Fac_CCBSDeactivate;
-                       dummy.fac_out.u.CCBSDeactivate.InvokeID = cc_record->invoke_id;
-                       dummy.fac_out.u.CCBSDeactivate.ComponentType = FacComponent_Invoke;
-                       dummy.fac_out.u.CCBSDeactivate.Component.Invoke.CCBSReference = cc_record->mode.ptmp.reference_id;
-
-                       /* Send message */
-                       print_facility(&dummy.fac_out, &dummy);
-                       misdn_lib_send_event(&dummy, EVENT_FACILITY);
-               }
-       }
-       AST_LIST_UNLOCK(&misdn_cc_records_db);
-
-       /* Wait for the response to the call completion deactivation request. */
-       misdn_cc_response_wait(chan, MISDN_CC_REQUEST_WAIT_MAX, record_id);
-
-       AST_LIST_LOCK(&misdn_cc_records_db);
-       cc_record = misdn_cc_find_by_id(record_id);
-       if (cc_record) {
-               if (cc_record->port < 0) {
-                       /* The network did not tell us that call completion was available. */
-                       error_str = NULL;
-               } else if (cc_record->outstanding_message) {
-                       cc_record->outstanding_message = 0;
-                       error_str = misdn_no_response_from_network;
-               } else if (cc_record->reject_code != FacReject_None) {
-                       error_str = misdn_to_str_reject_code(cc_record->reject_code);
-               } else if (cc_record->error_code != FacError_None) {
-                       error_str = misdn_to_str_error_code(cc_record->error_code);
-               } else {
-                       error_str = NULL;
-               }
-
-               misdn_cc_delete(cc_record);
-       } else {
-               error_str = NULL;
-       }
-       AST_LIST_UNLOCK(&misdn_cc_records_db);
-       if (error_str) {
-               ast_verb(1, "%s(%s) diagnostic '%s' on channel %s\n",
-                       misdn_command_name, subcommand->name, error_str, ast_channel_name(chan));
-               pbx_builtin_setvar_helper(chan, MISDN_ERROR_MSG, error_str);
-       }
-
-       return 0;
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-/*!
- * \internal
- * \brief misdn_command(cc-a-busy) subcommand handler
- *
- * \details
- * misdn_command(cc-a-busy,${MISDN_CC_RECORD_ID},<yes/no>)
- * Set the status of User-A for a call completion service instance.
- *
- * \param chan Asterisk channel to operate upon.
- * \param subcommand Arguments for the subcommand
- *
- * \retval 0 on success.
- * \retval -1 on error.
- */
-static int misdn_command_cc_a_busy(struct ast_channel *chan, struct misdn_command_args *subcommand)
-{
-       long record_id;
-       int party_a_free;
-       struct misdn_cc_record *cc_record;
-       struct misdn_bchannel *bc;
-
-       static const char cmd_help[] = "%s(%s,${MISDN_CC_RECORD_ID},<yes/no>)\n";
-
-       if (ast_strlen_zero(subcommand->arg[0]) || !isdigit(*subcommand->arg[0])) {
-               ast_log(LOG_WARNING, cmd_help, misdn_command_name, subcommand->name);
-               return -1;
-       }
-       record_id = atol(subcommand->arg[0]);
-
-       if (ast_true(subcommand->arg[1])) {
-               party_a_free = 0;
-       } else if (ast_false(subcommand->arg[1])) {
-               party_a_free = 1;
-       } else {
-               ast_log(LOG_WARNING, cmd_help, misdn_command_name, subcommand->name);
-               return -1;
-       }
-
-       AST_LIST_LOCK(&misdn_cc_records_db);
-       cc_record = misdn_cc_find_by_id(record_id);
-       if (cc_record && cc_record->party_a_free != party_a_free) {
-               /* User-A's status has changed */
-               cc_record->party_a_free = party_a_free;
-
-               if (cc_record->ptp && cc_record->mode.ptp.bc) {
-                       cc_record->error_code = FacError_None;
-                       cc_record->reject_code = FacReject_None;
-
-                       /* Build message */
-                       bc = cc_record->mode.ptp.bc;
-                       if (cc_record->party_a_free) {
-                               bc->fac_out.Function = Fac_CCBS_T_Resume;
-                               bc->fac_out.u.CCBS_T_Resume.InvokeID = ++misdn_invoke_id;
-                       } else {
-                               bc->fac_out.Function = Fac_CCBS_T_Suspend;
-                               bc->fac_out.u.CCBS_T_Suspend.InvokeID = ++misdn_invoke_id;
-                       }
-
-                       /* Send message */
-                       print_facility(&bc->fac_out, bc);
-                       misdn_lib_send_event(bc, EVENT_FACILITY);
-               }
-       }
-       AST_LIST_UNLOCK(&misdn_cc_records_db);
-
-       return 0;
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-/*!
- * \internal
- * \brief misdn_command(cc-b-free) subcommand handler
- *
- * \details
- * misdn_command(cc-b-free,${MISDN_CC_RECORD_ID},<notify-context>,<user-a-extension>,<priority>)
- * Set the dialplan location to notify when User-B is free and User-A is busy.
- *
- * \param chan Asterisk channel to operate upon.
- * \param subcommand Arguments for the subcommand
- *
- * \retval 0 on success.
- * \retval -1 on error.
- */
-static int misdn_command_cc_b_free(struct ast_channel *chan, struct misdn_command_args *subcommand)
-{
-       unsigned index;
-       long record_id;
-       int priority;
-       char *context;
-       char *exten;
-       struct misdn_cc_record *cc_record;
-
-       static const char cmd_help[] = "%s(%s,${MISDN_CC_RECORD_ID},<notify-context>,<user-a-extension>,<priority>)\n";
-
-       /* Check that all arguments are present */
-       for (index = 0; index < 4; ++index) {
-               if (ast_strlen_zero(subcommand->arg[index])) {
-                       ast_log(LOG_WARNING, cmd_help, misdn_command_name, subcommand->name);
-                       return -1;
-               }
-       }
-
-       /* These must be numeric */
-       if (!isdigit(*subcommand->arg[0]) || !isdigit(*subcommand->arg[3])) {
-               ast_log(LOG_WARNING, cmd_help, misdn_command_name, subcommand->name);
-               return -1;
-       }
-
-       record_id = atol(subcommand->arg[0]);
-       context = subcommand->arg[1];
-       exten = subcommand->arg[2];
-       priority = atoi(subcommand->arg[3]);
-
-       AST_LIST_LOCK(&misdn_cc_records_db);
-       cc_record = misdn_cc_find_by_id(record_id);
-       if (cc_record) {
-               /* Save User-B free information */
-               ast_copy_string(cc_record->b_free.context, context, sizeof(cc_record->b_free.context));
-               ast_copy_string(cc_record->b_free.exten, exten, sizeof(cc_record->b_free.exten));
-               cc_record->b_free.priority = priority;
-       }
-       AST_LIST_UNLOCK(&misdn_cc_records_db);
-
-       return 0;
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-struct misdn_cc_request {
-       enum FacFunction ptmp;
-       enum FacFunction ptp;
-};
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-/*!
- * \internal
- * \brief misdn_command(ccbs-request/ccnr-request) subcommand handler helper
- *
- * \details
- * misdn_command(ccbs-request,${MISDN_CC_RECORD_ID},<notify-context>,<user-a-extension>,<priority>)
- * misdn_command(ccnr-request,${MISDN_CC_RECORD_ID},<notify-context>,<user-a-extension>,<priority>)
- * Set the dialplan location to notify when User-B is free and User-A is free.
- *
- * \param chan Asterisk channel to operate upon.
- * \param subcommand Arguments for the subcommand
- * \param request Which call-completion request message to generate.
- *
- * \retval 0 on success.
- * \retval -1 on error.
- */
-static int misdn_command_cc_request(struct ast_channel *chan, struct misdn_command_args *subcommand, const struct misdn_cc_request *request)
-{
-       unsigned index;
-       int request_retention;
-       long record_id;
-       int priority;
-       char *context;
-       char *exten;
-       const char *error_str;
-       struct misdn_cc_record *cc_record;
-       struct misdn_bchannel *bc;
-       struct misdn_bchannel dummy;
-       struct misdn_party_id id;
-
-       static const char cmd_help[] = "%s(%s,${MISDN_CC_RECORD_ID},<notify-context>,<user-a-extension>,<priority>)\n";
-
-       /* Check that all arguments are present */
-       for (index = 0; index < 4; ++index) {
-               if (ast_strlen_zero(subcommand->arg[index])) {
-                       ast_log(LOG_WARNING, cmd_help, misdn_command_name, subcommand->name);
-                       return -1;
-               }
-       }
-
-       /* These must be numeric */
-       if (!isdigit(*subcommand->arg[0]) || !isdigit(*subcommand->arg[3])) {
-               ast_log(LOG_WARNING, cmd_help, misdn_command_name, subcommand->name);
-               return -1;
-       }
-
-       record_id = atol(subcommand->arg[0]);
-       context = subcommand->arg[1];
-       exten = subcommand->arg[2];
-       priority = atoi(subcommand->arg[3]);
-
-       AST_LIST_LOCK(&misdn_cc_records_db);
-       cc_record = misdn_cc_find_by_id(record_id);
-       if (cc_record) {
-               /* Save User-B free information */
-               ast_copy_string(cc_record->remote_user_free.context, context,
-                       sizeof(cc_record->remote_user_free.context));
-               ast_copy_string(cc_record->remote_user_free.exten, exten,
-                       sizeof(cc_record->remote_user_free.exten));
-               cc_record->remote_user_free.priority = priority;
-
-               if (0 <= cc_record->port) {
-                       if (cc_record->ptp) {
-                               if (!cc_record->mode.ptp.bc) {
-                                       bc = misdn_lib_get_register_bc(cc_record->port);
-                                       if (bc) {
-                                               cc_record->mode.ptp.bc = bc;
-                                               cc_record->error_code = FacError_None;
-                                               cc_record->reject_code = FacReject_None;
-                                               cc_record->invoke_id = ++misdn_invoke_id;
-                                               cc_record->outstanding_message = 1;
-                                               cc_record->activation_requested = 1;
-
-                                               misdn_cfg_get(bc->port, MISDN_CFG_CC_REQUEST_RETENTION,
-                                                       &request_retention, sizeof(request_retention));
-                                               cc_record->mode.ptp.requested_retention = request_retention ? 1 : 0;
-
-                                               /* Build message */
-                                               bc->fac_out.Function = request->ptp;
-                                               bc->fac_out.u.CCBS_T_Request.InvokeID = cc_record->invoke_id;
-                                               bc->fac_out.u.CCBS_T_Request.ComponentType = FacComponent_Invoke;
-                                               bc->fac_out.u.CCBS_T_Request.Component.Invoke.Q931ie =
-                                                       cc_record->redial.setup_bc_hlc_llc;
-                                               memset(&id, 0, sizeof(id));
-                                               id.number_plan = cc_record->redial.dialed.number_plan;
-                                               id.number_type = cc_record->redial.dialed.number_type;
-                                               ast_copy_string(id.number, cc_record->redial.dialed.number,
-                                                       sizeof(id.number));
-                                               misdn_Address_fill(
-                                                       &bc->fac_out.u.CCBS_T_Request.Component.Invoke.Destination,
-                                                       &id);
-                                               misdn_Address_fill(
-                                                       &bc->fac_out.u.CCBS_T_Request.Component.Invoke.Originating,
-                                                       &cc_record->redial.caller);
-                                               bc->fac_out.u.CCBS_T_Request.Component.Invoke.PresentationAllowedIndicatorPresent = 1;
-                                               bc->fac_out.u.CCBS_T_Request.Component.Invoke.PresentationAllowedIndicator =
-                                                       (cc_record->redial.caller.presentation != 0) ? 0 : 1;
-                                               bc->fac_out.u.CCBS_T_Request.Component.Invoke.RetentionSupported =
-                                                       request_retention ? 1 : 0;
-
-                                               /* Send message */
-                                               print_facility(&bc->fac_out, bc);
-                                               misdn_lib_send_event(bc, EVENT_REGISTER);
-                                       }
-                               }
-                       } else {
-                               cc_record->error_code = FacError_None;
-                               cc_record->reject_code = FacReject_None;
-                               cc_record->invoke_id = ++misdn_invoke_id;
-                               cc_record->outstanding_message = 1;
-                               cc_record->activation_requested = 1;
-
-                               /* Build message */
-                               misdn_make_dummy(&dummy, cc_record->port, 0,
-                                       misdn_lib_port_is_nt(cc_record->port), 0);
-                               dummy.fac_out.Function = request->ptmp;
-                               dummy.fac_out.u.CCBSRequest.InvokeID = cc_record->invoke_id;
-                               dummy.fac_out.u.CCBSRequest.ComponentType = FacComponent_Invoke;
-                               dummy.fac_out.u.CCBSRequest.Component.Invoke.CallLinkageID =
-                                       cc_record->mode.ptmp.linkage_id;
-
-                               /* Send message */
-                               print_facility(&dummy.fac_out, &dummy);
-                               misdn_lib_send_event(&dummy, EVENT_FACILITY);
-                       }
-               }
-       }
-       AST_LIST_UNLOCK(&misdn_cc_records_db);
-
-       /* Wait for the response to the call completion request. */
-       misdn_cc_response_wait(chan, MISDN_CC_REQUEST_WAIT_MAX, record_id);
-
-       AST_LIST_LOCK(&misdn_cc_records_db);
-       cc_record = misdn_cc_find_by_id(record_id);
-       if (cc_record) {
-               if (!cc_record->activated) {
-                       if (cc_record->port < 0) {
-                               /* The network did not tell us that call completion was available. */
-                               error_str = "No port number";
-                       } else if (cc_record->outstanding_message) {
-                               cc_record->outstanding_message = 0;
-                               error_str = misdn_no_response_from_network;
-                       } else if (cc_record->reject_code != FacReject_None) {
-                               error_str = misdn_to_str_reject_code(cc_record->reject_code);
-                       } else if (cc_record->error_code != FacError_None) {
-                               error_str = misdn_to_str_error_code(cc_record->error_code);
-                       } else if (cc_record->ptp) {
-                               if (cc_record->mode.ptp.bc) {
-                                       error_str = "Call-completion already requested";
-                               } else {
-                                       error_str = "Could not allocate call-completion signaling link";
-                               }
-                       } else {
-                               /* Should never happen. */
-                               error_str = "Unexpected error";
-                       }
-
-                       /* No need to keep the call completion record. */
-                       if (cc_record->ptp && cc_record->mode.ptp.bc) {
-                               /* Close the call-completion signaling link */
-                               bc = cc_record->mode.ptp.bc;
-                               bc->fac_out.Function = Fac_None;
-                               bc->out_cause = AST_CAUSE_NORMAL_CLEARING;
-                               misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE);
-                       }
-                       misdn_cc_delete(cc_record);
-               } else {
-                       error_str = NULL;
-               }
-       } else {
-               error_str = misdn_cc_record_not_found;
-       }
-       AST_LIST_UNLOCK(&misdn_cc_records_db);
-       if (error_str) {
-               ast_verb(1, "%s(%s) diagnostic '%s' on channel %s\n",
-                       misdn_command_name, subcommand->name, error_str, ast_channel_name(chan));
-               pbx_builtin_setvar_helper(chan, MISDN_ERROR_MSG, error_str);
-               pbx_builtin_setvar_helper(chan, MISDN_CC_STATUS, "ERROR");
-       } else {
-               pbx_builtin_setvar_helper(chan, MISDN_CC_STATUS, "ACTIVATED");
-       }
-
-       return 0;
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-/*!
- * \internal
- * \brief misdn_command(ccbs-request) subcommand handler
- *
- * \details
- * misdn_command(ccbs-request,${MISDN_CC_RECORD_ID},<notify-context>,<user-a-extension>,<priority>)
- * Set the dialplan location to notify when User-B is free and User-A is free.
- *
- * \param chan Asterisk channel to operate upon.
- * \param subcommand Arguments for the subcommand
- *
- * \retval 0 on success.
- * \retval -1 on error.
- */
-static int misdn_command_ccbs_request(struct ast_channel *chan, struct misdn_command_args *subcommand)
-{
-       static const struct misdn_cc_request request = {
-               .ptmp = Fac_CCBSRequest,
-               .ptp = Fac_CCBS_T_Request
-       };
-
-       return misdn_command_cc_request(chan, subcommand, &request);
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-/*!
- * \internal
- * \brief misdn_command(ccnr-request) subcommand handler
- *
- * \details
- * misdn_command(ccnr-request,${MISDN_CC_RECORD_ID},<notify-context>,<user-a-extension>,<priority>)
- * Set the dialplan location to notify when User-B is free and User-A is free.
- *
- * \param chan Asterisk channel to operate upon.
- * \param subcommand Arguments for the subcommand
- *
- * \retval 0 on success.
- * \retval -1 on error.
- */
-static int misdn_command_ccnr_request(struct ast_channel *chan, struct misdn_command_args *subcommand)
-{
-       static const struct misdn_cc_request request = {
-               .ptmp = Fac_CCNRRequest,
-               .ptp = Fac_CCNR_T_Request
-       };
-
-       return misdn_command_cc_request(chan, subcommand, &request);
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-struct misdn_command_table {
-       /*! \brief subcommand name */
-       const char *name;
-
-       /*! \brief subcommand handler */
-       int (*func)(struct ast_channel *chan, struct misdn_command_args *subcommand);
-
-       /*! \brief TRUE if the subcommand can only be executed on mISDN channels */
-       int misdn_only;
-};
-static const struct misdn_command_table misdn_commands[] = {
-/* *INDENT-OFF* */
-       /* subcommand-name  subcommand-handler              mISDN only */
-       { "cc-initialize",  misdn_command_cc_initialize,    0 },
-       { "cc-deactivate",  misdn_command_cc_deactivate,    0 },
-       { "cc-a-busy",      misdn_command_cc_a_busy,        0 },
-       { "cc-b-free",      misdn_command_cc_b_free,        0 },
-       { "ccbs-request",   misdn_command_ccbs_request,     0 },
-       { "ccnr-request",   misdn_command_ccnr_request,     0 },
-/* *INDENT-ON* */
-};
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-/*!
- * \internal
- * \brief misdn_command() dialplan application.
- *
- * \param chan Asterisk channel to operate upon.
- * \param data Application options string.
- *
- * \retval 0 on success.
- * \retval -1 on error.
- */
-static int misdn_command_exec(struct ast_channel *chan, const char *data)
-{
-       char *parse;
-       unsigned index;
-       struct misdn_command_args subcommand;
-
-       if (ast_strlen_zero((char *) data)) {
-               ast_log(LOG_ERROR, "%s requires arguments\n", misdn_command_name);
-               return -1;
-       }
-
-       ast_debug(1, "%s(%s)\n", misdn_command_name, (char *) data);
-
-       parse = ast_strdupa(data);
-       AST_STANDARD_APP_ARGS(subcommand, parse);
-       if (!subcommand.argc || ast_strlen_zero(subcommand.name)) {
-               ast_log(LOG_ERROR, "%s requires a subcommand\n", misdn_command_name);
-               return -1;
-       }
-
-       for (index = 0; index < ARRAY_LEN(misdn_commands); ++index) {
-               if (strcasecmp(misdn_commands[index].name, subcommand.name) == 0) {
-                       strcpy(subcommand.name, misdn_commands[index].name);
-                       if (misdn_commands[index].misdn_only
-                               && strcasecmp(ast_channel_tech(chan)->type, misdn_type) != 0) {
-                               ast_log(LOG_WARNING,
-                                       "%s(%s) only makes sense with %s channels!\n",
-                                       misdn_command_name, subcommand.name, misdn_type);
-                               return -1;
-                       }
-                       return misdn_commands[index].func(chan, &subcommand);
-               }
-       }
-
-       ast_log(LOG_WARNING, "%s(%s) subcommand is unknown\n", misdn_command_name,
-               subcommand.name);
-       return -1;
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-static int misdn_facility_exec(struct ast_channel *chan, const char *data)
-{
-       struct chan_list *ch = MISDN_ASTERISK_TECH_PVT(chan);
-       char *parse;
-       unsigned max_len;
-
-       AST_DECLARE_APP_ARGS(args,
-               AST_APP_ARG(facility_type);
-               AST_APP_ARG(arg)[99];
-       );
-
-       chan_misdn_log(0, 0, "TYPE: %s\n", ast_channel_tech(chan)->type);
-
-       if (strcasecmp(ast_channel_tech(chan)->type, misdn_type)) {
-               ast_log(LOG_WARNING, "misdn_facility only makes sense with %s channels!\n", misdn_type);
-               return -1;
-       }
-
-       if (ast_strlen_zero((char *) data)) {
-               ast_log(LOG_WARNING, "misdn_facility requires arguments: facility_type[,<args>]\n");
-               return -1;
-       }
-
-       parse = ast_strdupa(data);
-       AST_STANDARD_APP_ARGS(args, parse);
-
-       if (ast_strlen_zero(args.facility_type)) {
-               ast_log(LOG_WARNING, "misdn_facility requires arguments: facility_type[,<args>]\n");
-               return -1;
-       }
-
-       if (!strcasecmp(args.facility_type, "calldeflect")) {
-               if (ast_strlen_zero(args.arg[0])) {
-                       ast_log(LOG_WARNING, "Facility: Call Deflection requires an argument: Number\n");
-               }
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-               max_len = sizeof(ch->bc->fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.Number) - 1;
-               if (max_len < strlen(args.arg[0])) {
-                       ast_log(LOG_WARNING,
-                               "Facility: Number argument too long (up to %u digits are allowed). Ignoring.\n",
-                               max_len);
-                       return 0;
-               }
-               ch->bc->fac_out.Function = Fac_CallDeflection;
-               ch->bc->fac_out.u.CallDeflection.InvokeID = ++misdn_invoke_id;
-               ch->bc->fac_out.u.CallDeflection.ComponentType = FacComponent_Invoke;
-               ch->bc->fac_out.u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUserPresent = 1;
-               ch->bc->fac_out.u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUser = 0;
-               ch->bc->fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.Type = 0;/* unknown */
-               ch->bc->fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.LengthOfNumber = strlen(args.arg[0]);
-               strcpy((char *) ch->bc->fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.Number, args.arg[0]);
-               ch->bc->fac_out.u.CallDeflection.Component.Invoke.Deflection.Subaddress.Length = 0;
-
-#else  /* !defined(AST_MISDN_ENHANCEMENTS) */
-
-               max_len = sizeof(ch->bc->fac_out.u.CDeflection.DeflectedToNumber) - 1;
-               if (max_len < strlen(args.arg[0])) {
-                       ast_log(LOG_WARNING,
-                               "Facility: Number argument too long (up to %u digits are allowed). Ignoring.\n",
-                               max_len);
-                       return 0;
-               }
-               ch->bc->fac_out.Function = Fac_CD;
-               ch->bc->fac_out.u.CDeflection.PresentationAllowed = 0;
-               //ch->bc->fac_out.u.CDeflection.DeflectedToSubaddress[0] = 0;
-               strcpy((char *) ch->bc->fac_out.u.CDeflection.DeflectedToNumber, args.arg[0]);
-#endif /* !defined(AST_MISDN_ENHANCEMENTS) */
-
-               /* Send message */
-               print_facility(&ch->bc->fac_out, ch->bc);
-               misdn_lib_send_event(ch->bc, EVENT_FACILITY);
-#if defined(AST_MISDN_ENHANCEMENTS)
-       } else if (!strcasecmp(args.facility_type, "callrerouteing")
-               || !strcasecmp(args.facility_type, "callrerouting")) {
-               if (ast_strlen_zero(args.arg[0])) {
-                       ast_log(LOG_WARNING, "Facility: Call rerouting requires an argument: Number\n");
-               }
-
-               max_len = sizeof(ch->bc->fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.Number) - 1;
-               if (max_len < strlen(args.arg[0])) {
-                       ast_log(LOG_WARNING,
-                               "Facility: Number argument too long (up to %u digits are allowed). Ignoring.\n",
-                               max_len);
-                       return 0;
-               }
-               ch->bc->fac_out.Function = Fac_CallRerouteing;
-               ch->bc->fac_out.u.CallRerouteing.InvokeID = ++misdn_invoke_id;
-               ch->bc->fac_out.u.CallRerouteing.ComponentType = FacComponent_Invoke;
-
-               ch->bc->fac_out.u.CallRerouteing.Component.Invoke.ReroutingReason = 0;/* unknown */
-               ch->bc->fac_out.u.CallRerouteing.Component.Invoke.ReroutingCounter = 1;
-
-               ch->bc->fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.Type = 0;/* unknown */
-               ch->bc->fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.LengthOfNumber = strlen(args.arg[0]);
-               strcpy((char *) ch->bc->fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.Number, args.arg[0]);
-               ch->bc->fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Subaddress.Length = 0;
-
-               ch->bc->fac_out.u.CallRerouteing.Component.Invoke.CallingPartySubaddress.Length = 0;
-
-               /* 0x90 0x90 0xa3 3.1 kHz audio, circuit mode, 64kbit/sec, level1/a-Law */
-               ch->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Length = 3;
-               ch->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Contents[0] = 0x90;
-               ch->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Contents[1] = 0x90;
-               ch->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Contents[2] = 0xa3;
-               ch->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Hlc.Length = 0;
-               ch->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Llc.Length = 0;
-               ch->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.UserInfo.Length = 0;
-
-               ch->bc->fac_out.u.CallRerouteing.Component.Invoke.LastRerouting.Type = 1;/* presentationRestricted */
-               ch->bc->fac_out.u.CallRerouteing.Component.Invoke.SubscriptionOption = 0;/* no notification to caller */
-
-               /* Send message */
-               print_facility(&ch->bc->fac_out, ch->bc);
-               misdn_lib_send_event(ch->bc, EVENT_FACILITY);
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-       } else {
-               chan_misdn_log(1, ch->bc->port, "Unknown Facility: %s\n", args.facility_type);
-       }
-
-       return 0;
-}
-
-static int misdn_check_l2l1(struct ast_channel *chan, const char *data)
-{
-       char *parse;
-       char group[BUFFERSIZE + 1];
-       char *port_str;
-       int port = 0;
-       int timeout;
-       int dowait = 0;
-       int port_up;
-
-       AST_DECLARE_APP_ARGS(args,
-               AST_APP_ARG(grouppar);
-               AST_APP_ARG(timeout);
-       );
-
-       if (ast_strlen_zero((char *) data)) {
-               ast_log(LOG_WARNING, "misdn_check_l2l1 Requires arguments\n");
-               return -1;
-       }
-
-       parse = ast_strdupa(data);
-       AST_STANDARD_APP_ARGS(args, parse);
-
-       if (args.argc != 2) {
-               ast_log(LOG_WARNING, "Wrong argument count\n");
-               return 0;
-       }
-
-       /*ast_log(LOG_NOTICE, "Arguments: group/port '%s' timeout '%s'\n", args.grouppar, args.timeout);*/
-       timeout = atoi(args.timeout);
-       port_str = args.grouppar;
-
-       if (port_str[0] == 'g' && port_str[1] == ':') {
-               /* We make a group call lets checkout which ports are in my group */
-               port_str += 2;
-               ast_copy_string(group, port_str, sizeof(group));
-               chan_misdn_log(2, 0, "Checking Ports in group: %s\n", group);
-
-               for (port = misdn_cfg_get_next_port(port);
-                       port > 0;
-                       port = misdn_cfg_get_next_port(port)) {
-                       char cfg_group[BUFFERSIZE + 1];
-
-                       chan_misdn_log(2, 0, "trying port %d\n", port);
-
-                       misdn_cfg_get(port, MISDN_CFG_GROUPNAME, cfg_group, sizeof(cfg_group));
-
-                       if (!strcasecmp(cfg_group, group)) {
-                               port_up = misdn_lib_port_up(port, 1);
-                               if (!port_up) {
-                                       chan_misdn_log(2, 0, " --> port '%d'\n", port);
-                                       misdn_lib_get_port_up(port);
-                                       dowait = 1;
-                               }
-                       }
-               }
-       } else {
-               port = atoi(port_str);
-               chan_misdn_log(2, 0, "Checking Port: %d\n", port);
-               port_up = misdn_lib_port_up(port, 1);
-               if (!port_up) {
-                       misdn_lib_get_port_up(port);
-                       dowait = 1;
-               }
-       }
-
-       if (dowait) {
-               chan_misdn_log(2, 0, "Waiting for '%d' seconds\n", timeout);
-               ast_safe_sleep(chan, timeout * 1000);
-       }
-
-       return 0;
-}
-
-static int misdn_set_opt_exec(struct ast_channel *chan, const char *data)
-{
-       struct chan_list *ch = MISDN_ASTERISK_TECH_PVT(chan);
-       char *tok;
-       char *tokb;
-       char *parse;
-       int keyidx = 0;
-       int rxgain = 0;
-       int txgain = 0;
-       int change_jitter = 0;
-
-       if (strcasecmp(ast_channel_tech(chan)->type, misdn_type)) {
-               ast_log(LOG_WARNING, "misdn_set_opt makes sense only with %s channels!\n", misdn_type);
-               return -1;
-       }
-
-       if (ast_strlen_zero((char *) data)) {
-               ast_log(LOG_WARNING, "misdn_set_opt Requires arguments\n");
-               return -1;
-       }
-
-       parse = ast_strdupa(data);
-       for (tok = strtok_r(parse, ":", &tokb);
-               tok;
-               tok = strtok_r(NULL, ":", &tokb)) {
-               int neglect = 0;
-
-               if (tok[0] == '!') {
-                       neglect = 1;
-                       tok++;
-               }
-
-               switch(tok[0]) {
-               case 'd' :
-                       ast_copy_string(ch->bc->display, ++tok, sizeof(ch->bc->display));
-                       chan_misdn_log(1, ch->bc->port, "SETOPT: Display:%s\n", ch->bc->display);
-                       break;
-               case 'n':
-                       chan_misdn_log(1, ch->bc->port, "SETOPT: No DSP\n");
-                       ch->bc->nodsp = 1;
-                       break;
-               case 'j':
-                       chan_misdn_log(1, ch->bc->port, "SETOPT: jitter\n");
-                       tok++;
-                       change_jitter = 1;
-
-                       switch (tok[0]) {
-                       case 'b':
-                               ch->jb_len = atoi(++tok);
-                               chan_misdn_log(1, ch->bc->port, " --> buffer_len:%d\n", ch->jb_len);
-                               break;
-                       case 't' :
-                               ch->jb_upper_threshold = atoi(++tok);
-                               chan_misdn_log(1, ch->bc->port, " --> upper_threshold:%d\n", ch->jb_upper_threshold);
-                               break;
-                       case 'n':
-                               ch->bc->nojitter = 1;
-                               chan_misdn_log(1, ch->bc->port, " --> nojitter\n");
-                               break;
-                       default:
-                               ch->jb_len = 4000;
-                               ch->jb_upper_threshold = 0;
-                               chan_misdn_log(1, ch->bc->port, " --> buffer_len:%d (default)\n", ch->jb_len);
-                               chan_misdn_log(1, ch->bc->port, " --> upper_threshold:%d (default)\n", ch->jb_upper_threshold);
-                               break;
-                       }
-                       break;
-               case 'v':
-                       tok++;
-
-                       switch (tok[0]) {
-                       case 'r' :
-                               rxgain = atoi(++tok);
-                               if (rxgain < -8) {
-                                       rxgain = -8;
-                               }
-                               if (rxgain > 8) {
-                                       rxgain = 8;
-                               }
-                               ch->bc->rxgain = rxgain;
-                               chan_misdn_log(1, ch->bc->port, "SETOPT: Volume:%d\n", rxgain);
-                               break;
-                       case 't':
-                               txgain = atoi(++tok);
-                               if (txgain < -8) {
-                                       txgain = -8;
-                               }
-                               if (txgain > 8) {
-                                       txgain = 8;
-                               }
-                               ch->bc->txgain = txgain;
-                               chan_misdn_log(1, ch->bc->port, "SETOPT: Volume:%d\n", txgain);
-                               break;
-                       }
-                       break;
-               case 'c':
-                       keyidx = atoi(++tok);
-                       {
-                               char keys[4096];
-                               char *key = NULL;
-                               char *tmp = keys;
-                               int i;
-
-                               misdn_cfg_get(0, MISDN_GEN_CRYPT_KEYS, keys, sizeof(keys));
-
-                               for (i = 0; i < keyidx; i++) {
-                                       key = strsep(&tmp, ",");
-                               }
-
-                               if (key) {
-                                       ast_copy_string(ch->bc->crypt_key, key, sizeof(ch->bc->crypt_key));
-                               }
-
-                               chan_misdn_log(0, ch->bc->port, "SETOPT: crypt with key:%s\n", ch->bc->crypt_key);
-                               break;
-                       }
-               case 'e':
-                       chan_misdn_log(1, ch->bc->port, "SETOPT: EchoCancel\n");
-
-                       if (neglect) {
-                               chan_misdn_log(1, ch->bc->port, " --> disabled\n");
-#ifdef MISDN_1_2
-                               *ch->bc->pipeline = 0;
-#else
-                               ch->bc->ec_enable = 0;
-#endif
-                       } else {
-#ifdef MISDN_1_2
-                               update_pipeline_config(ch->bc);
-#else
-                               ch->bc->ec_enable = 1;
-                               ch->bc->orig = ch->originator;
-                               tok++;
-                               if (*tok) {
-                                       ch->bc->ec_deftaps = atoi(tok);
-                               }
-#endif
-                       }
-                       break;
-               case 'h':
-                       chan_misdn_log(1, ch->bc->port, "SETOPT: Digital\n");
-
-                       if (strlen(tok) > 1 && tok[1] == '1') {
-                               chan_misdn_log(1, ch->bc->port, "SETOPT: HDLC \n");
-                               if (!ch->bc->hdlc) {
-                                       ch->bc->hdlc = 1;
-                               }
-                       }
-                       ch->bc->capability = INFO_CAPABILITY_DIGITAL_UNRESTRICTED;
-                       break;
-               case 's':
-                       chan_misdn_log(1, ch->bc->port, "SETOPT: Send DTMF\n");
-                       ch->bc->send_dtmf = 1;
-                       break;
-               case 'f':
-                       chan_misdn_log(1, ch->bc->port, "SETOPT: Faxdetect\n");
-                       ch->faxdetect = 1;
-                       misdn_cfg_get(ch->bc->port, MISDN_CFG_FAXDETECT_TIMEOUT, &ch->faxdetect_timeout, sizeof(ch->faxdetect_timeout));
-                       break;
-               case 'a':
-                       chan_misdn_log(1, ch->bc->port, "SETOPT: AST_DSP (for DTMF)\n");
-                       ch->ast_dsp = 1;
-                       break;
-               case 'p':
-                       chan_misdn_log(1, ch->bc->port, "SETOPT: callerpres: %s\n", &tok[1]);
-                       /* CRICH: callingpres!!! */
-                       if (strstr(tok, "allowed")) {
-                               ch->bc->presentation = 0;
-                               ch->bc->set_presentation = 1;
-                       } else if (strstr(tok, "restricted")) {
-                               ch->bc->presentation = 1;
-                               ch->bc->set_presentation = 1;
-                       } else if (strstr(tok, "not_screened")) {
-                               chan_misdn_log(0, ch->bc->port, "SETOPT: callerpres: not_screened is deprecated\n");
-                               ch->bc->presentation = 1;
-                               ch->bc->set_presentation = 1;
-                       }
-                       break;
-               case 'i' :
-                       chan_misdn_log(1, ch->bc->port, "Ignoring dtmf tones, just use them inband\n");
-                       ch->ignore_dtmf = 1;
-                       break;
-               default:
-                       break;
-               }
-       }
-
-       if (change_jitter) {
-               config_jitterbuffer(ch);
-       }
-
-       if (ch->faxdetect || ch->ast_dsp) {
-               if (!ch->dsp) {
-                       ch->dsp = ast_dsp_new();
-               }
-               if (ch->dsp) {
-                       ast_dsp_set_features(ch->dsp, DSP_FEATURE_DIGIT_DETECT | DSP_FEATURE_FAX_DETECT);
-               }
-       }
-
-       if (ch->ast_dsp) {
-               chan_misdn_log(1, ch->bc->port, "SETOPT: with AST_DSP we deactivate mISDN_dsp\n");
-               ch->bc->nodsp = 1;
-       }
-
-       return 0;
-}
-
-
-int chan_misdn_jb_empty(struct misdn_bchannel *bc, char *buf, int len)
-{
-       struct chan_list *ch;
-       int res;
-
-       ch = find_chan_by_bc(bc);
-       if (!ch) {
-               return 0;
-       }
-
-       if (ch->jb) {
-               res = misdn_jb_empty(ch->jb, buf, len);
-       } else {
-               res = 0;
-       }
-       chan_list_unref(ch, "Done emptying jb");
-
-       return res;
-}
-
-
-
-/*******************************************************/
-/***************** JITTERBUFFER ************************/
-/*******************************************************/
-
-
-/* allocates the jb-structure and initialize the elements*/
-struct misdn_jb *misdn_jb_init(int size, int upper_threshold)
-{
-       struct misdn_jb *jb;
-
-       jb = ast_calloc(1, sizeof(*jb));
-       if (!jb) {
-           chan_misdn_log(-1, 0, "No free Mem for jb\n");
-           return NULL;
-       }
-       jb->size = size;
-       jb->upper_threshold = upper_threshold;
-       //jb->wp = 0;
-       //jb->rp = 0;
-       //jb->state_full = 0;
-       //jb->state_empty = 0;
-       //jb->bytes_wrote = 0;
-       jb->samples = ast_calloc(size, sizeof(*jb->samples));
-       if (!jb->samples) {
-               ast_free(jb);
-               chan_misdn_log(-1, 0, "No free Mem for jb->samples\n");
-               return NULL;
-       }
-
-       jb->ok = ast_calloc(size, sizeof(*jb->ok));
-       if (!jb->ok) {
-               ast_free(jb->samples);
-               ast_free(jb);
-               chan_misdn_log(-1, 0, "No free Mem for jb->ok\n");
-               return NULL;
-       }
-
-       ast_mutex_init(&jb->mutexjb);
-
-       return jb;
-}
-
-/* frees the data and destroys the given jitterbuffer struct */
-void misdn_jb_destroy(struct misdn_jb *jb)
-{
-       ast_mutex_destroy(&jb->mutexjb);
-
-       ast_free(jb->ok);
-       ast_free(jb->samples);
-       ast_free(jb);
-}
-
-/* fills the jitterbuffer with len data returns < 0 if there was an
-   error (buffer overflow). */
-int misdn_jb_fill(struct misdn_jb *jb, const char *data, int len)
-{
-       int i;
-       int j;
-       int rp;
-       int wp;
-
-       if (!jb || ! data) {
-               return 0;
-       }
-
-       ast_mutex_lock(&jb->mutexjb);
-
-       wp = jb->wp;
-       rp = jb->rp;
-
-       for (i = 0; i < len; i++) {
-               jb->samples[wp] = data[i];
-               jb->ok[wp] = 1;
-               wp = (wp != jb->size - 1) ? wp + 1 : 0;
-
-               if (wp == jb->rp) {
-                       jb->state_full = 1;
-               }
-       }
-
-       if (wp >= rp) {
-               jb->state_buffer = wp - rp;
-       } else {
-               jb->state_buffer = jb->size - rp + wp;
-       }
-       chan_misdn_log(9, 0, "misdn_jb_fill: written:%d | Buffer status:%d p:%p\n", len, jb->state_buffer, jb);
-
-       if (jb->state_full) {
-               jb->wp = wp;
-
-               rp = wp;
-               for (j = 0; j < jb->upper_threshold; j++) {
-                       rp = (rp != 0) ? rp - 1 : jb->size - 1;
-               }
-               jb->rp = rp;
-               jb->state_full = 0;
-               jb->state_empty = 1;
-
-               ast_mutex_unlock(&jb->mutexjb);
-
-               return -1;
-       }
-
-       if (!jb->state_empty) {
-               jb->bytes_wrote += len;
-               if (jb->bytes_wrote >= jb->upper_threshold) {
-                       jb->state_empty = 1;
-                       jb->bytes_wrote = 0;
-               }
-       }
-       jb->wp = wp;
-
-       ast_mutex_unlock(&jb->mutexjb);
-
-       return 0;
-}
-
-/* gets len bytes out of the jitterbuffer if available, else only the
-available data is returned and the return value indicates the number
-of data. */
-int misdn_jb_empty(struct misdn_jb *jb, char *data, int len)
-{
-       int i;
-       int wp;
-       int rp;
-       int read = 0;
-
-       ast_mutex_lock(&jb->mutexjb);
-
-       rp = jb->rp;
-       wp = jb->wp;
-
-       if (jb->state_empty) {
-               for (i = 0; i < len; i++) {
-                       if (wp == rp) {
-                               jb->rp = rp;
-                               jb->state_empty = 0;
-
-                               ast_mutex_unlock(&jb->mutexjb);
-
-                               return read;
-                       } else {
-                               if (jb->ok[rp] == 1) {
-                                       data[i] = jb->samples[rp];
-                                       jb->ok[rp] = 0;
-                                       rp = (rp != jb->size - 1) ? rp + 1 : 0;
-                                       read += 1;
-                               }
-                       }
-               }
-
-               if (wp >= rp) {
-                       jb->state_buffer = wp - rp;
-               } else {
-                       jb->state_buffer = jb->size - rp + wp;
-               }
-               chan_misdn_log(9, 0, "misdn_jb_empty: read:%d | Buffer status:%d p:%p\n", len, jb->state_buffer, jb);
-
-               jb->rp = rp;
-       } else {
-               chan_misdn_log(9, 0, "misdn_jb_empty: Wait...requested:%d p:%p\n", len, jb);
-       }
-
-       ast_mutex_unlock(&jb->mutexjb);
-
-       return read;
-}
-
-/*******************************************************/
-/*************** JITTERBUFFER  END *********************/
-/*******************************************************/
-
-static void chan_misdn_log(int level, int port, char *tmpl, ...)
-{
-       va_list ap;
-       char buf[1024];
-       char port_buf[8];
-
-       if (!(0 <= port && port <= max_ports)) {
-               ast_log(LOG_WARNING, "chan_misdn_log called with out-of-range port number! (%d)\n", port);
-               port = 0;
-               level = -1;
-       } else if (!(level == -1
-               || (misdn_debug_only[port]
-                       ? (level == 1 && misdn_debug[port]) || level == misdn_debug[port]
-                       : level <= misdn_debug[port])
-               || (level <= misdn_debug[0] && !ast_strlen_zero(global_tracefile)))) {
-               /*
-                * We are not going to print anything so lets not
-                * go to all the work of generating a string.
-                */
-               return;
-       }
-
-       snprintf(port_buf, sizeof(port_buf), "P[%2d] ", port);
-       va_start(ap, tmpl);
-       vsnprintf(buf, sizeof(buf), tmpl, ap);
-       va_end(ap);
-
-       if (level == -1) {
-               ast_log(LOG_WARNING, "%s", buf);
-       } else if (misdn_debug_only[port]
-               ? (level == 1 && misdn_debug[port]) || level == misdn_debug[port]
-               : level <= misdn_debug[port]) {
-               ast_verbose("%s%s", port_buf, buf);
-       }
-
-       if (level <= misdn_debug[0] && !ast_strlen_zero(global_tracefile)) {
-               char ctimebuf[30];
-               time_t tm;
-               char *tmp;
-               char *p;
-               FILE *fp;
-
-               fp = fopen(global_tracefile, "a+");
-               if (!fp) {
-                       ast_verbose("Error opening Tracefile: [ %s ] %s\n", global_tracefile, strerror(errno));
-                       return;
-               }
-
-               tm = time(NULL);
-               tmp = ctime_r(&tm, ctimebuf);
-               p = strchr(tmp, '\n');
-               if (p) {
-                       *p = ':';
-               }
-               fputs(tmp, fp);
-               fputs(" ", fp);
-               fputs(port_buf, fp);
-               fputs(" ", fp);
-               fputs(buf, fp);
-
-               fclose(fp);
-       }
-}
-
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Channel driver for mISDN Support (BRI/PRI)",
-       .support_level = AST_MODULE_SUPPORT_DEPRECATED,
-       .load = load_module,
-       .unload = unload_module,
-       .reload = reload,
-       .load_pri = AST_MODPRI_CHANNEL_DRIVER,
-);
diff --git a/channels/misdn/Makefile b/channels/misdn/Makefile
deleted file mode 100644 (file)
index 96d5a2a..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-#
-# Makefile for chan_misdn support
-#
-ifneq ($(wildcard /usr/include/linux/mISDNdsp.h),)
-CFLAGS+=-DMISDN_1_2
-endif
-
-all:
-
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $<
-
-portinfo: portinfo.o
-       $(CC) -o $@ $^ -lisdnnet -lmISDN -lpthread
-
-clean:
-       rm -rf *.a *.o *.so portinfo *.i *.gcda *.gcno
diff --git a/channels/misdn/chan_misdn_config.h b/channels/misdn/chan_misdn_config.h
deleted file mode 100644 (file)
index c4054a8..0000000
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Chan_Misdn -- Channel Driver for Asterisk
- *
- * Interface to mISDN
- *
- * Copyright (C) 2004, Christian Richter
- *
- * Christian Richter <crich@beronet.com>
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License
- */
-
-/*! \file
- * \brief Interface to mISDN - Config
- * \author Christian Richter <crich@beronet.com>
- */
-
-
-
-
-#ifndef CHAN_MISDN_CONFIG_H
-#define CHAN_MISDN_CONFIG_H
-
-#define BUFFERSIZE 512
-
-enum misdn_cfg_elements {
-
-       /* port config items */
-       MISDN_CFG_FIRST = 0,
-       MISDN_CFG_GROUPNAME,           /* char[] */
-       MISDN_CFG_ALLOWED_BEARERS,           /* char[] */
-       MISDN_CFG_FAR_ALERTING,        /* int (bool) */
-       MISDN_CFG_RXGAIN,              /* int */
-       MISDN_CFG_TXGAIN,              /* int */
-       MISDN_CFG_TE_CHOOSE_CHANNEL,   /* int (bool) */
-       MISDN_CFG_PMP_L1_CHECK,        /* int (bool) */
-       MISDN_CFG_REJECT_CAUSE,         /* int */
-       MISDN_CFG_ALARM_BLOCK,        /* int (bool) */
-       MISDN_CFG_HDLC,                /* int (bool) */
-       MISDN_CFG_CONTEXT,             /* char[] */
-       MISDN_CFG_LANGUAGE,            /* char[] */
-       MISDN_CFG_MUSICCLASS,            /* char[] */
-       MISDN_CFG_CALLERID,            /* char[] */
-       MISDN_CFG_INCOMING_CALLERID_TAG, /* char[] */
-       MISDN_CFG_APPEND_MSN_TO_CALLERID_TAG, /* int (bool) */
-       MISDN_CFG_METHOD,              /* char[] */
-       MISDN_CFG_DIALPLAN,            /* int */
-       MISDN_CFG_LOCALDIALPLAN,       /* int */
-       MISDN_CFG_CPNDIALPLAN,       /* int */
-       MISDN_CFG_TON_PREFIX_UNKNOWN,         /* char[] */
-       MISDN_CFG_TON_PREFIX_INTERNATIONAL,   /* char[] */
-       MISDN_CFG_TON_PREFIX_NATIONAL,        /* char[] */
-       MISDN_CFG_TON_PREFIX_NETWORK_SPECIFIC,/* char[] */
-       MISDN_CFG_TON_PREFIX_SUBSCRIBER,      /* char[] */
-       MISDN_CFG_TON_PREFIX_ABBREVIATED,     /* char[] */
-       MISDN_CFG_PRES,                /* int */
-       MISDN_CFG_SCREEN,              /* int */
-       MISDN_CFG_DISPLAY_CONNECTED,   /* int */
-       MISDN_CFG_DISPLAY_SETUP,       /* int */
-       MISDN_CFG_ALWAYS_IMMEDIATE,    /* int (bool) */
-       MISDN_CFG_NODIALTONE,    /* int (bool) */
-       MISDN_CFG_IMMEDIATE,           /* int (bool) */
-       MISDN_CFG_SENDDTMF,           /* int (bool) */
-       MISDN_CFG_ASTDTMF,            /* int (bool) */
-       MISDN_CFG_HOLD_ALLOWED,        /* int (bool) */
-       MISDN_CFG_EARLY_BCONNECT,      /* int (bool) */
-       MISDN_CFG_INCOMING_EARLY_AUDIO,      /* int (bool) */
-       MISDN_CFG_ECHOCANCEL,          /* int */
-       MISDN_CFG_CC_REQUEST_RETENTION,/* bool */
-       MISDN_CFG_OUTGOING_COLP,       /* int */
-#ifdef MISDN_1_2
-       MISDN_CFG_PIPELINE,      /* char[] */
-#endif
-
-#ifdef WITH_BEROEC
-       MISDN_CFG_BNECHOCANCEL,
-       MISDN_CFG_BNEC_ANTIHOWL,
-       MISDN_CFG_BNEC_NLP,
-       MISDN_CFG_BNEC_ZEROCOEFF,
-       MISDN_CFG_BNEC_TD,
-       MISDN_CFG_BNEC_ADAPT,
-#endif
-       MISDN_CFG_NEED_MORE_INFOS,     /* bool */
-       MISDN_CFG_NOAUTORESPOND_ON_SETUP,     /* bool */
-       MISDN_CFG_NTTIMEOUT,            /* bool */
-       MISDN_CFG_BRIDGING,              /* bool */
-       MISDN_CFG_JITTERBUFFER,             /* int */
-       MISDN_CFG_JITTERBUFFER_UPPER_THRESHOLD,              /* int */
-       MISDN_CFG_CALLGROUP,           /* ast_group_t */
-       MISDN_CFG_PICKUPGROUP,         /* ast_group_t */
-       MISDN_CFG_NAMEDCALLGROUP,      /* ast_namedgroups * */
-       MISDN_CFG_NAMEDPICKUPGROUP,    /* ast_namedgroups * */
-       MISDN_CFG_MAX_IN,              /* int */
-       MISDN_CFG_MAX_OUT,              /* int */
-       MISDN_CFG_L1_TIMEOUT,          /* int */
-       MISDN_CFG_OVERLAP_DIAL,         /* int (bool)*/
-       MISDN_CFG_MSNS,                /* char[] */
-       MISDN_CFG_FAXDETECT,           /* char[] */
-       MISDN_CFG_FAXDETECT_CONTEXT,   /* char[] */
-       MISDN_CFG_FAXDETECT_TIMEOUT,   /* int */
-       MISDN_CFG_PTP,                 /* int (bool) */
-       MISDN_CFG_LAST,
-
-       /* general config items */
-       MISDN_GEN_FIRST,
-#ifndef MISDN_1_2
-       MISDN_GEN_MISDN_INIT,           /* char[] */
-#endif
-       MISDN_GEN_DEBUG,               /* int */
-       MISDN_GEN_TRACEFILE,           /* char[] */
-       MISDN_GEN_BRIDGING,            /* int (bool) */
-       MISDN_GEN_STOP_TONE,           /* int (bool) */
-       MISDN_GEN_APPEND_DIGITS2EXTEN, /* int (bool) */
-       MISDN_GEN_DYNAMIC_CRYPT,       /* int (bool) */
-       MISDN_GEN_CRYPT_PREFIX,        /* char[] */
-       MISDN_GEN_CRYPT_KEYS,          /* char[] */
-       MISDN_GEN_NTKEEPCALLS,          /* int (bool) */
-       MISDN_GEN_NTDEBUGFLAGS,          /* int */
-       MISDN_GEN_NTDEBUGFILE,          /* char[] */
-       MISDN_GEN_LAST
-};
-
-enum misdn_cfg_method {
-       METHOD_STANDARD = 0,
-       METHOD_ROUND_ROBIN,
-       METHOD_STANDARD_DEC
-};
-
-/* you must call misdn_cfg_init before any other function of this header file */
-int misdn_cfg_init(int max_ports, int reload);
-void misdn_cfg_reload(void);
-void misdn_cfg_destroy(void);
-
-void misdn_cfg_update_ptp( void );
-
-/* if you requst a general config element, the port value is ignored. if the requested
- * value is not available, or the buffer is too small, the buffer will be nulled (in
- * case of a char* only its first byte will be nulled). */
-void misdn_cfg_get(int port, enum misdn_cfg_elements elem, void* buf, int bufsize);
-
-/* returns the enum element for the given name, returns MISDN_CFG_FIRST if none was found */
-enum misdn_cfg_elements misdn_cfg_get_elem (const char *name);
-
-/* fills the buffer with the name of the given config element */
-void misdn_cfg_get_name (enum misdn_cfg_elements elem, void *buf, int bufsize);
-
-/* fills the buffer with the description of the given config element */
-void misdn_cfg_get_desc (enum misdn_cfg_elements elem, void *buf, int bufsize, void *buf_default, int bufsize_default);
-
-/* fills the buffer with a ',' separated list of all active ports */
-void misdn_cfg_get_ports_string(char *ports);
-
-/* fills the buffer with a nice printable string representation of the config element */
-void misdn_cfg_get_config_string(int port, enum misdn_cfg_elements elem, char* buf, int bufsize);
-
-/* returns the next available port number. returns -1 if the last one was reached. */
-int misdn_cfg_get_next_port(int port);
-int misdn_cfg_get_next_port_spin(int port);
-
-int misdn_cfg_is_msn_valid(int port, char* msn);
-int misdn_cfg_is_port_valid(int port);
-int misdn_cfg_is_group_method(char *group, enum misdn_cfg_method meth);
-
-#if 0
-char *misdn_cfg_get_next_group(char *group);
-int misdn_cfg_get_next_port_in_group(int port, char *group);
-#endif
-
-struct ast_jb_conf *misdn_get_global_jbconf(void);
-
-#endif
diff --git a/channels/misdn/ie.c b/channels/misdn/ie.c
deleted file mode 100644 (file)
index 67fc958..0000000
+++ /dev/null
@@ -1,1414 +0,0 @@
-/*
- * Chan_Misdn -- Channel Driver for Asterisk
- *
- * Interface to mISDN
- *
- * Copyright (C) 2005, Christian Richter
- *
- * Christian Richter <crich@beronet.com>
- *
- * heaviliy patched from jollys ie.cpp, jolly gave me ALL
- * rights for this code, i can even have my own copyright on it.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License
- */
-
-/*! \file
- * \brief Interface to mISDN
- * \author Christian Richter <crich@beronet.com>
- */
-
-/*
-  the pointer of enc_ie_* always points to the IE itself
-  if qi is not NULL (TE-mode), offset is set
-*/
-
-/*** MODULEINFO
-       <support_level>extended</support_level>
- ***/
-
-#include "asterisk.h"
-
-#include <string.h>
-
-#include <mISDNuser/mISDNlib.h>
-#include <mISDNuser/isdn_net.h>
-#include <mISDNuser/l3dss1.h>
-#include <mISDNuser/net_l3.h>
-#include "asterisk/localtime.h"
-
-
-
-#define MISDN_IE_DEBG 0
-
-/* support stuff */
-static void strnncpy(char *dest, const char *src, size_t len, size_t dst_len)
-{
-       if (len > dst_len-1)
-               len = dst_len-1;
-       strncpy(dest, src, len);
-       dest[len] = '\0';
-}
-
-
-/* IE_COMPLETE */
-static void enc_ie_complete(unsigned char **ntmode, msg_t *msg, int complete, int nt, struct misdn_bchannel *bc)
-{
-       unsigned char *p;
-       Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
-
-       if (complete<0 || complete>1)
-       {
-               printf("%s: ERROR: complete(%d) is out of range.\n", __FUNCTION__, complete);
-               return;
-       }
-
-       if (complete)
-               if (MISDN_IE_DEBG) printf("    complete=%d\n", complete);
-
-       if (complete)
-       {
-               p = msg_put(msg, 1);
-               if (nt)
-               {
-                       *ntmode = p;
-               } else
-                       qi->QI_ELEMENT(sending_complete) = p - (unsigned char *)qi - sizeof(Q931_info_t);
-
-               p[0] = IE_COMPLETE;
-       }
-}
-
-static void dec_ie_complete(unsigned char *p, Q931_info_t *qi, int *complete, int nt, struct misdn_bchannel *bc)
-{
-       *complete = 0;
-       if (!nt)
-       {
-               if (qi->QI_ELEMENT(sending_complete))
-                       *complete = 1;
-       } else
-               if (p)
-                       *complete = 1;
-
-       if (*complete)
-               if (MISDN_IE_DEBG) printf("    complete=%d\n", *complete);
-}
-
-
-/* IE_BEARER */
-static void enc_ie_bearer(unsigned char **ntmode, msg_t *msg, int coding, int capability, int mode, int rate, int multi, int user, int nt, struct misdn_bchannel *bc)
-{
-       unsigned char *p;
-       Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
-       int l;
-
-       if (coding<0 || coding>3)
-       {
-               printf("%s: ERROR: coding(%d) is out of range.\n", __FUNCTION__, coding);
-               return;
-       }
-       if (capability<0 || capability>31)
-       {
-               printf("%s: ERROR: capability(%d) is out of range.\n", __FUNCTION__, capability);
-               return;
-       }
-       if (mode<0 || mode>3)
-       {
-               printf("%s: ERROR: mode(%d) is out of range.\n", __FUNCTION__, mode);
-               return;
-       }
-       if (rate<0 || rate>31)
-       {
-               printf("%s: ERROR: rate(%d) is out of range.\n", __FUNCTION__, rate);
-               return;
-       }
-       if (multi>127)
-       {
-               printf("%s: ERROR: multi(%d) is out of range.\n", __FUNCTION__, multi);
-               return;
-       }
-       if (user>31)
-       {
-               printf("%s: ERROR: user L1(%d) is out of range.\n", __FUNCTION__, rate);
-               return;
-       }
-       if (rate!=24 && multi>=0)
-       {
-               printf("%s: WARNING: multi(%d) is only possible if rate(%d) would be 24.\n", __FUNCTION__, multi, rate);
-               multi = -1;
-       }
-
-       if (MISDN_IE_DEBG) printf("    coding=%d capability=%d mode=%d rate=%d multi=%d user=%d\n", coding, capability, mode, rate, multi, user);
-
-       l = 2 + (multi>=0) + (user>=0);
-       p = msg_put(msg, l+2);
-       if (nt)
-               *ntmode = p+1;
-       else
-               qi->QI_ELEMENT(bearer_capability) = p - (unsigned char *)qi - sizeof(Q931_info_t);
-       p[0] = IE_BEARER;
-       p[1] = l;
-       p[2] = 0x80 + (coding<<5) + capability;
-       p[3] = 0x80 + (mode<<5) + rate;
-       if (multi >= 0)
-               p[4] = 0x80 + multi;
-       if (user >= 0)
-               p[4+(multi>=0)] = 0xa0 + user;
-}
-
-static void dec_ie_bearer(unsigned char *p, Q931_info_t *qi, int *coding, int *capability, int *mode, int *rate, int *multi, int *user,
-                  int *async, int *urate, int *stopbits, int *dbits, int *parity, int nt, struct misdn_bchannel *bc)
-{
-       int octet;
-       *coding = -1;
-       *capability = -1;
-       *mode = -1;
-       *rate = -1;
-       *multi = -1;
-       *user = -1;
-       *async = -1;
-       *urate = -1;
-       *stopbits = -1;
-       *dbits = -1;
-       *parity = -1;
-
-       if (!nt)
-       {
-               p = NULL;
-#ifdef LLC_SUPPORT
-               if (qi->QI_ELEMENT(llc)) {
-
-                       p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(llc) + 1;
-               }
-#endif
-               if (qi->QI_ELEMENT(bearer_capability))
-                       p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(bearer_capability) + 1;
-       }
-       if (!p)
-               return;
-
-       if (p[0] < 2)
-       {
-               printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
-               return;
-       }
-
-       *coding = (p[1]&0x60) >> 5;
-       *capability = p[1] & 0x1f;
-       octet = 2;
-       if (!(p[1] & 0x80))
-               octet++;
-
-       if (p[0] < octet)
-               goto done;
-
-       *mode = (p[octet]&0x60) >> 5;
-       *rate = p[octet] & 0x1f;
-
-       octet++;
-
-       if (p[0] < octet)
-               goto done;
-
-       if (*rate == 0x18) {
-               /* Rate multiplier only present if 64Kb/s base rate */
-               *multi = p[octet++] & 0x7f;
-       }
-
-       if (p[0] < octet)
-               goto done;
-
-       /* Start L1 info */
-       if ((p[octet] & 0x60) == 0x20) {
-               *user = p[octet] & 0x1f;
-
-               if (p[0] <= octet)
-                       goto done;
-
-               if (p[octet++] & 0x80)
-                       goto l2;
-
-               *async = !!(p[octet] & 0x40);
-               /* 0x20 is inband negotiation */
-               *urate = p[octet] & 0x1f;
-
-               if (p[0] <= octet)
-                       goto done;
-
-               if (p[octet++] & 0x80)
-                       goto l2;
-
-               /* Ignore next byte for now: Intermediate rate, NIC, flow control */
-
-               if (p[0] <= octet)
-                       goto done;
-
-               if (p[octet++] & 0x80)
-                       goto l2;
-
-               /* And the next one. Header, multiframe, mode, assignor/ee, negotiation */
-
-               if (p[0] <= octet)
-                       goto done;
-
-               if (~p[octet++] & 0x80)
-                       goto l2;
-
-               /* Wheee. V.110 speed information */
-
-               *stopbits = (p[octet] & 0x60) >> 5;
-               *dbits = (p[octet] & 0x18) >> 3;
-               *parity = p[octet] & 7;
-
-               octet++;
-       }
- l2: /* Nobody seems to want the rest so we don't bother (yet) */
- done:
-       if (MISDN_IE_DEBG) printf("    coding=%d capability=%d mode=%d rate=%d multi=%d user=%d async=%d urate=%d stopbits=%d dbits=%d parity=%d\n", *coding, *capability, *mode, *rate, *multi, *user, *async, *urate, *stopbits, *dbits, *parity);
-}
-
-
-/* IE_CALL_ID */
-#if 0
-static void enc_ie_call_id(unsigned char **ntmode, msg_t *msg, char *callid, int callid_len, int nt, struct misdn_bchannel *bc)
-{
-       unsigned char *p;
-       Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
-       int l;
-
-       char debug[25];
-       int i;
-
-       if (!callid || callid_len<=0)
-       {
-               return;
-       }
-       if (callid_len>8)
-       {
-               printf("%s: ERROR: callid_len(%d) is out of range.\n", __FUNCTION__, callid_len);
-               return;
-       }
-
-       i = 0;
-       while(i < callid_len)
-       {
-               if (MISDN_IE_DEBG) printf(debug+(i*3), " %02hhx", (unsigned char)callid[i]);
-               i++;
-       }
-
-       if (MISDN_IE_DEBG) printf("    callid%s\n", debug);
-
-       l = callid_len;
-       p = msg_put(msg, l+2);
-       if (nt)
-               *ntmode = p+1;
-       else
-               qi->QI_ELEMENT(call_id) = p - (unsigned char *)qi - sizeof(Q931_info_t);
-       p[0] = IE_CALL_ID;
-       p[1] = l;
-       memcpy(p+2, callid, callid_len);
-}
-#endif
-
-#if 0
-static void dec_ie_call_id(unsigned char *p, Q931_info_t *qi, char *callid, int *callid_len, int nt, struct misdn_bchannel *bc)
-{
-       char debug[25];
-       int i;
-
-       *callid_len = -1;
-
-       if (!nt)
-       {
-               p = NULL;
-               if (qi->QI_ELEMENT(call_id))
-                       p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(call_id) + 1;
-       }
-       if (!p)
-               return;
-       if (p[0] > 8)
-       {
-               printf("%s: ERROR: IE too long (%d).\n", __FUNCTION__, p[0]);
-               return;
-       }
-
-       *callid_len = p[0];
-       memcpy(callid, p+1, *callid_len);
-
-       i = 0;
-       while(i < *callid_len)
-       {
-               if (MISDN_IE_DEBG) printf(debug+(i*3), " %02hhx", (unsigned char)callid[i]);
-               i++;
-       }
-
-       if (MISDN_IE_DEBG) printf("    callid%s\n", debug);
-}
-#endif
-
-/* IE_CALLED_PN */
-static void enc_ie_called_pn(unsigned char **ntmode, msg_t *msg, int type, int plan, char *number, int nt, struct misdn_bchannel *bc)
-{
-       unsigned char *p;
-       Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
-       int l;
-
-       if (type<0 || type>7)
-       {
-               printf("%s: ERROR: type(%d) is out of range.\n", __FUNCTION__, type);
-               return;
-       }
-       if (plan<0 || plan>15)
-       {
-               printf("%s: ERROR: plan(%d) is out of range.\n", __FUNCTION__, plan);
-               return;
-       }
-       if (!number[0])
-       {
-               printf("%s: ERROR: number is not given.\n", __FUNCTION__);
-               return;
-       }
-
-       if (MISDN_IE_DEBG) printf("    type=%d plan=%d number='%s'\n", type, plan, number);
-
-       l = 1+strlen((char *)number);
-       p = msg_put(msg, l+2);
-       if (nt)
-               *ntmode = p+1;
-       else
-               qi->QI_ELEMENT(called_nr) = p - (unsigned char *)qi - sizeof(Q931_info_t);
-       p[0] = IE_CALLED_PN;
-       p[1] = l;
-       p[2] = 0x80 + (type<<4) + plan;
-       strncpy((char *)p+3, (char *)number, strlen((char *)number));
-}
-
-static void dec_ie_called_pn(unsigned char *p, Q931_info_t *qi, int *type, int *plan, char *number, size_t number_len, int nt, struct misdn_bchannel *bc)
-{
-       *type = -1;
-       *plan = -1;
-       *number = '\0';
-
-       if (!nt)
-       {
-               p = NULL;
-               if (qi->QI_ELEMENT(called_nr))
-                       p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(called_nr) + 1;
-       }
-       if (!p)
-               return;
-       if (p[0] < 2)
-       {
-               printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
-               return;
-       }
-
-       *type = (p[1]&0x70) >> 4;
-       *plan = p[1] & 0xf;
-       strnncpy(number, (char *)p+2, p[0]-1, number_len);
-
-       if (MISDN_IE_DEBG) printf("    type=%d plan=%d number='%s'\n", *type, *plan, number);
-}
-
-
-/* IE_CALLING_PN */
-static void enc_ie_calling_pn(unsigned char **ntmode, msg_t *msg, int type, int plan, int present, int screen, char *number, int nt, struct misdn_bchannel *bc)
-{
-       unsigned char *p;
-       Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
-       int l;
-
-       if (type<0 || type>7)
-       {
-               printf("%s: ERROR: type(%d) is out of range.\n", __FUNCTION__, type);
-               return;
-       }
-       if (plan<0 || plan>15)
-       {
-               printf("%s: ERROR: plan(%d) is out of range.\n", __FUNCTION__, plan);
-               return;
-       }
-       if (present>3)
-       {
-               printf("%s: ERROR: present(%d) is out of range.\n", __FUNCTION__, present);
-               return;
-       }
-       if (present >= 0) if (screen<0 || screen>3)
-       {
-               printf("%s: ERROR: screen(%d) is out of range.\n", __FUNCTION__, screen);
-               return;
-       }
-
-       if (MISDN_IE_DEBG) printf("    type=%d plan=%d present=%d screen=%d number='%s'\n", type, plan, present, screen, number);
-
-       l = 1;
-       if (number) if (number[0])
-               l += strlen((char *)number);
-       if (present >= 0)
-               l += 1;
-       p = msg_put(msg, l+2);
-       if (nt)
-               *ntmode = p+1;
-       else
-               qi->QI_ELEMENT(calling_nr) = p - (unsigned char *)qi - sizeof(Q931_info_t);
-       p[0] = IE_CALLING_PN;
-       p[1] = l;
-       if (present >= 0)
-       {
-               p[2] = 0x00 + (type<<4) + plan;
-               p[3] = 0x80 + (present<<5) + screen;
-               if (number) if (number[0])
-                       strncpy((char *)p+4, (char *)number, strlen((char *)number));
-       } else
-       {
-               p[2] = 0x80 + (type<<4) + plan;
-               if (number) if (number[0])
-                       strncpy((char *)p+3, (char *)number, strlen((char *)number));
-       }
-}
-
-static void dec_ie_calling_pn(unsigned char *p, Q931_info_t *qi, int *type, int *plan, int *present, int *screen, char *number, size_t number_len, int nt, struct misdn_bchannel *bc)
-{
-       *type = -1;
-       *plan = -1;
-       *present = -1;
-       *screen = -1;
-       *number = '\0';
-
-       if (!nt)
-       {
-               p = NULL;
-               if (qi->QI_ELEMENT(calling_nr))
-                       p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(calling_nr) + 1;
-       }
-       if (!p)
-               return;
-       if (p[0] < 1)
-       {
-               printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
-               return;
-       }
-
-       *type = (p[1]&0x70) >> 4;
-       *plan = p[1] & 0xf;
-       if (!(p[1] & 0x80))
-       {
-               if (p[0] < 2)
-               {
-                       printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
-                       return;
-               }
-               *present = (p[2]&0x60) >> 5;
-               *screen = p[2] & 0x3;
-               strnncpy(number, (char *)p+3, p[0]-2, number_len);
-       } else
-       {
-               strnncpy(number, (char *)p+2, p[0]-1, number_len);
-               /* SPECIAL workarround for IBT software bug */
-               /* if (number[0]==0x80) */
-               /*  strcpy((char *)number, (char *)number+1); */
-       }
-
-       if (MISDN_IE_DEBG) printf("    type=%d plan=%d present=%d screen=%d number='%s'\n", *type, *plan, *present, *screen, number);
-}
-
-
-/* IE_CONNECTED_PN */
-static void enc_ie_connected_pn(unsigned char **ntmode, msg_t *msg, int type, int plan, int present, int screen, char *number, int nt, struct misdn_bchannel *bc)
-{
-       unsigned char *p;
-       Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
-       int l;
-
-       if (type<0 || type>7)
-       {
-               printf("%s: ERROR: type(%d) is out of range.\n", __FUNCTION__, type);
-               return;
-       }
-       if (plan<0 || plan>15)
-       {
-               printf("%s: ERROR: plan(%d) is out of range.\n", __FUNCTION__, plan);
-               return;
-       }
-       if (present>3)
-       {
-               printf("%s: ERROR: present(%d) is out of range.\n", __FUNCTION__, present);
-               return;
-       }
-       if (present >= 0) if (screen<0 || screen>3)
-       {
-               printf("%s: ERROR: screen(%d) is out of range.\n", __FUNCTION__, screen);
-               return;
-       }
-
-       if (MISDN_IE_DEBG) printf("    type=%d plan=%d present=%d screen=%d number='%s'\n", type, plan, present, screen, number);
-
-       l = 1;
-       if (number) if (number[0])
-               l += strlen((char *)number);
-       if (present >= 0)
-               l += 1;
-       p = msg_put(msg, l+2);
-       if (nt)
-               *ntmode = p+1;
-       else
-               qi->QI_ELEMENT(connected_nr) = p - (unsigned char *)qi - sizeof(Q931_info_t);
-       p[0] = IE_CONNECT_PN;
-       p[1] = l;
-       if (present >= 0)
-       {
-               p[2] = 0x00 + (type<<4) + plan;
-               p[3] = 0x80 + (present<<5) + screen;
-               if (number) if (number[0])
-                       strncpy((char *)p+4, (char *)number, strlen((char *)number));
-       } else
-       {
-               p[2] = 0x80 + (type<<4) + plan;
-               if (number) if (number[0])
-                       strncpy((char *)p+3, (char *)number, strlen((char *)number));
-       }
-}
-
-static void dec_ie_connected_pn(unsigned char *p, Q931_info_t *qi, int *type, int *plan, int *present, int *screen, char *number, size_t number_len, int nt, struct misdn_bchannel *bc)
-{
-       *type = -1;
-       *plan = -1;
-       *present = -1;
-       *screen = -1;
-       *number = '\0';
-
-       if (!nt)
-       {
-               p = NULL;
-               if (qi->QI_ELEMENT(connected_nr))
-                       p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(connected_nr) + 1;
-       }
-       if (!p)
-               return;
-       if (p[0] < 1)
-       {
-               printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
-               return;
-       }
-
-       *type = (p[1]&0x70) >> 4;
-       *plan = p[1] & 0xf;
-       if (!(p[1] & 0x80))
-       {
-               if (p[0] < 2)
-               {
-                       printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
-                       return;
-               }
-               *present = (p[2]&0x60) >> 5;
-               *screen = p[2] & 0x3;
-               strnncpy(number, (char *)p+3, p[0]-2, number_len);
-       } else
-       {
-               strnncpy(number, (char *)p+2, p[0]-1, number_len);
-       }
-
-       if (MISDN_IE_DEBG) printf("    type=%d plan=%d present=%d screen=%d number='%s'\n", *type, *plan, *present, *screen, number);
-}
-
-
-/* IE_CAUSE */
-static void enc_ie_cause(unsigned char **ntmode, msg_t *msg, int location, int cause, int nt, struct misdn_bchannel *bc)
-{
-       unsigned char *p;
-       Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
-       int l;
-
-       if (location<0 || location>7)
-       {
-               printf("%s: ERROR: location(%d) is out of range.\n", __FUNCTION__, location);
-               return;
-       }
-       if (cause<0 || cause>127)
-       {
-               printf("%s: ERROR: cause(%d) is out of range.\n", __FUNCTION__, cause);
-               return;
-       }
-
-       if (MISDN_IE_DEBG) printf("    location=%d cause=%d\n", location, cause);
-
-       l = 2;
-       p = msg_put(msg, l+2);
-       if (nt)
-               *ntmode = p+1;
-       else
-               qi->QI_ELEMENT(cause) = p - (unsigned char *)qi - sizeof(Q931_info_t);
-       p[0] = IE_CAUSE;
-       p[1] = l;
-       p[2] = 0x80 + location;
-       p[3] = 0x80 + cause;
-}
-
-#if 0
-static void enc_ie_cause_standalone(unsigned char **ntmode, msg_t *msg, int location, int cause, int nt, struct misdn_bchannel *bc)
-{
-       unsigned char *p = msg_put(msg, 4);
-       Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
-       if (ntmode)
-               *ntmode = p+1;
-       else
-               qi->QI_ELEMENT(cause) = p - (unsigned char *)qi - sizeof(Q931_info_t);
-       p[0] = IE_CAUSE;
-       p[1] = 2;
-       p[2] = 0x80 + location;
-       p[3] = 0x80 + cause;
-}
-#endif
-
-static void dec_ie_cause(unsigned char *p, Q931_info_t *qi, int *location, int *cause, int nt, struct misdn_bchannel *bc)
-{
-       *location = -1;
-       *cause = -1;
-
-       if (!nt)
-       {
-               p = NULL;
-               if (qi->QI_ELEMENT(cause))
-                       p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(cause) + 1;
-       }
-       if (!p)
-               return;
-       if (p[0] < 2)
-       {
-               printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
-               return;
-       }
-
-       *location = p[1] & 0x0f;
-       *cause = p[2] & 0x7f;
-
-       if (MISDN_IE_DEBG) printf("    location=%d cause=%d\n", *location, *cause);
-}
-
-
-/* IE_CHANNEL_ID */
-static void enc_ie_channel_id(unsigned char **ntmode, msg_t *msg, int exclusive, int channel, int nt, struct misdn_bchannel *bc)
-{
-       unsigned char *p;
-       Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
-       int l;
-       struct misdn_stack *stack=get_stack_by_bc(bc);
-       int pri = stack->pri;
-
-       if (exclusive<0 || exclusive>1)
-       {
-               printf("%s: ERROR: exclusive(%d) is out of range.\n", __FUNCTION__, exclusive);
-               return;
-       }
-       if ((channel<0 || channel>0xff)
-           || (!pri && (channel>2 && channel<0xff))
-           || (pri && (channel>31 && channel<0xff))
-           || (pri && channel==16))
-       {
-               printf("%s: ERROR: channel(%d) is out of range.\n", __FUNCTION__, channel);
-               return;
-       }
-
-       /* if (MISDN_IE_DEBG) printf("    exclusive=%d channel=%d\n", exclusive, channel); */
-
-
-       if (!pri)
-       {
-               /* BRI */
-               l = 1;
-               p = msg_put(msg, l+2);
-               if (nt)
-                       *ntmode = p+1;
-               else
-                       qi->QI_ELEMENT(channel_id) = p - (unsigned char *)qi - sizeof(Q931_info_t);
-               p[0] = IE_CHANNEL_ID;
-               p[1] = l;
-               if (channel == 0xff)
-                       channel = 3;
-               p[2] = 0x80 + (exclusive<<3) + channel;
-               /* printf("    exclusive=%d channel=%d\n", exclusive, channel); */
-       } else
-       {
-               /* PRI */
-               if (channel == 0) /* no channel */
-                       return; /* IE not present */
-/*             if (MISDN_IE_DEBG) printf("channel = %d\n", channel); */
-               if (channel == 0xff) /* any channel */
-               {
-                       l = 1;
-                       p = msg_put(msg, l+2);
-                       if (nt)
-                               *ntmode = p+1;
-                       else
-                               qi->QI_ELEMENT(channel_id) = p - (unsigned char *)qi - sizeof(Q931_info_t);
-                       p[0] = IE_CHANNEL_ID;
-                       p[1] = l;
-                       p[2] = 0x80 + 0x20 + 0x03;
-/*                     if (MISDN_IE_DEBG) printf("%02hhx\n", p[2]); */
-                       return; /* end */
-               }
-               l = 3;
-               p = msg_put(msg, l+2);
-               if (nt)
-                       *ntmode = p+1;
-               else
-                       qi->QI_ELEMENT(channel_id) = p - (unsigned char *)qi - sizeof(Q931_info_t);
-               p[0] = IE_CHANNEL_ID;
-               p[1] = l;
-               p[2] = 0x80 + 0x20 + (exclusive<<3) + 0x01;
-               p[3] = 0x80 + 3; /* CCITT, Number, B-type */
-               p[4] = 0x80 + channel;
-/*             if (MISDN_IE_DEBG) printf("%02hhx %02hhx %02hhx\n", p[2], p[3], p[4]); */
-       }
-}
-
-static void dec_ie_channel_id(unsigned char *p, Q931_info_t *qi, int *exclusive, int *channel, int nt, struct misdn_bchannel *bc)
-{
-       struct misdn_stack *stack=get_stack_by_bc(bc);
-       int pri =stack->pri;
-
-       *exclusive = -1;
-       *channel = -1;
-
-       if (!nt)
-       {
-               p = NULL;
-               if (qi->QI_ELEMENT(channel_id))
-                       p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(channel_id) + 1;
-       }
-       if (!p)
-               return;
-       if (p[0] < 1)
-       {
-               printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
-               return;
-       }
-
-       if (p[1] & 0x40)
-       {
-               printf("%s: ERROR: refering to channels of other interfaces is not supported.\n", __FUNCTION__);
-               return;
-       }
-       if (p[1] & 0x04)
-       {
-               printf("%s: ERROR: using d-channel is not supported.\n", __FUNCTION__);
-               return;
-       }
-
-       *exclusive = (p[1]&0x08) >> 3;
-       if (!pri)
-       {
-               /* BRI */
-               if (p[1] & 0x20)
-               {
-                       printf("%s: ERROR: extended channel ID with non PRI interface.\n", __FUNCTION__);
-                       return;
-               }
-               *channel = p[1] & 0x03;
-               if (*channel == 3)
-                       *channel = 0xff;
-       } else
-       {
-               /* PRI */
-               if (p[0] < 1)
-               {
-                       printf("%s: ERROR: IE too short for PRI (%d).\n", __FUNCTION__, p[0]);
-                       return;
-               }
-               if (!(p[1] & 0x20))
-               {
-                       printf("%s: ERROR: basic channel ID with PRI interface.\n", __FUNCTION__);
-                       return;
-               }
-               if ((p[1]&0x03) == 0x00)
-               {
-                       /* no channel */
-                       *channel = 0;
-                       return;
-               }
-               if ((p[1]&0x03) == 0x03)
-               {
-                       /* any channel */
-                       *channel = 0xff;
-                       return;
-               }
-               if (p[0] < 3)
-               {
-                       printf("%s: ERROR: IE too short for PRI with channel(%d).\n", __FUNCTION__, p[0]);
-                       return;
-               }
-               if (p[2] & 0x10)
-               {
-                       printf("%s: ERROR: channel map not supported.\n", __FUNCTION__);
-                       return;
-               }
-               *channel = p[3] & 0x7f;
-               if ( (*channel<1) | (*channel==16) | (*channel>31))
-               {
-                       printf("%s: ERROR: PRI interface channel out of range (%d).\n", __FUNCTION__, *channel);
-                       return;
-               }
-/*             if (MISDN_IE_DEBG) printf("%02hhx %02hhx %02hhx\n", p[1], p[2], p[3]); */
-       }
-
-       if (MISDN_IE_DEBG) printf("    exclusive=%d channel=%d\n", *exclusive, *channel);
-}
-
-
-/* IE_DATE */
-static void enc_ie_date(unsigned char **ntmode, msg_t *msg, time_t ti, int nt, struct misdn_bchannel *bc)
-{
-       unsigned char *p;
-       Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
-       int l;
-       struct timeval tv = { ti, 0 };
-       struct ast_tm tm;
-
-       ast_localtime(&tv, &tm, NULL);
-       if (MISDN_IE_DEBG) printf("    year=%d month=%d day=%d hour=%d minute=%d\n", tm.tm_year%100, tm.tm_mon+1, tm.tm_mday, tm.tm_hour, tm.tm_min);
-
-       l = 5;
-       p = msg_put(msg, l+2);
-       if (nt)
-               *ntmode = p+1;
-       else
-               qi->QI_ELEMENT(date) = p - (unsigned char *)qi - sizeof(Q931_info_t);
-       p[0] = IE_DATE;
-       p[1] = l;
-       p[2] = tm.tm_year % 100;
-       p[3] = tm.tm_mon + 1;
-       p[4] = tm.tm_mday;
-       p[5] = tm.tm_hour;
-       p[6] = tm.tm_min;
-}
-
-
-/* IE_DISPLAY */
-static void enc_ie_display(unsigned char **ntmode, msg_t *msg, char *display, int nt, struct misdn_bchannel *bc)
-{
-       unsigned char *p;
-       Q931_info_t *qi = (Q931_info_t *) (msg->data + mISDN_HEADER_LEN);
-       int l;
-
-       if (!display[0])
-       {
-               printf("%s: ERROR: display text not given.\n", __FUNCTION__);
-               return;
-       }
-
-       l = strlen(display);
-       if (80 < l)
-       {
-               l = 80;
-               printf("%s: WARNING: display text too long (max %d chars), cutting.\n", __FUNCTION__, l);
-               display[l] = '\0';
-       }
-
-       /* if (MISDN_IE_DEBG) printf("    display='%s' (len=%d)\n", display, l); */
-
-       p = msg_put(msg, l + 2);
-       if (nt)
-               *ntmode = p + 1;
-       else
-               qi->QI_ELEMENT(display) = p - (unsigned char *) qi - sizeof(Q931_info_t);
-       p[0] = IE_DISPLAY;
-       p[1] = l;
-       strncpy((char *) p + 2, display, l);
-}
-
-#if 0
-static void dec_ie_display(unsigned char *p, Q931_info_t *qi, char *display, size_t display_len, int nt, struct misdn_bchannel *bc)
-{
-       *display = '\0';
-
-       if (!nt)
-       {
-               p = NULL;
-               if (qi->QI_ELEMENT(display))
-                       p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(display) + 1;
-       }
-       if (!p)
-               return;
-       if (p[0] < 1)
-       {
-               printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
-               return;
-       }
-
-       strnncpy(display, (char *)p+1, p[0], display_len);
-
-       if (MISDN_IE_DEBG) printf("    display='%s'\n", display);
-}
-#endif
-
-/* IE_KEYPAD */
-#if 1
-static void enc_ie_keypad(unsigned char **ntmode, msg_t *msg, char *keypad, int nt, struct misdn_bchannel *bc)
-{
-       unsigned char *p;
-       Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
-       int l;
-
-       if (!keypad[0])
-       {
-               printf("%s: ERROR: keypad info not given.\n", __FUNCTION__);
-               return;
-       }
-
-       if (MISDN_IE_DEBG) printf("    keypad='%s'\n", keypad);
-
-       l = strlen(keypad);
-       p = msg_put(msg, l+2);
-       if (nt)
-               *ntmode = p+1;
-       else
-               qi->QI_ELEMENT(keypad) = p - (unsigned char *)qi - sizeof(Q931_info_t);
-       p[0] = IE_KEYPAD;
-       p[1] = l;
-       strncpy((char *)p+2, keypad, strlen(keypad));
-}
-#endif
-
-static void dec_ie_keypad(unsigned char *p, Q931_info_t *qi, char *keypad, size_t keypad_len, int nt, struct misdn_bchannel *bc)
-{
-       *keypad = '\0';
-
-       if (!nt)
-       {
-               p = NULL;
-               if (qi->QI_ELEMENT(keypad))
-                       p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(keypad) + 1;
-       }
-       if (!p)
-               return;
-       if (p[0] < 1)
-       {
-               printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
-               return;
-       }
-
-       strnncpy(keypad, (char *)p+1, p[0], keypad_len);
-
-       if (MISDN_IE_DEBG) printf("    keypad='%s'\n", keypad);
-}
-
-
-/* IE_NOTIFY */
-static void enc_ie_notify(unsigned char **ntmode, msg_t *msg, int notify, int nt, struct misdn_bchannel *bc)
-{
-       unsigned char *p;
-       Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
-       int l;
-
-       if (notify<0 || notify>0x7f)
-       {
-               printf("%s: ERROR: notify(%d) is out of range.\n", __FUNCTION__, notify);
-               return;
-       }
-
-       if (MISDN_IE_DEBG) printf("    notify=%d\n", notify);
-
-       l = 1;
-       p = msg_put(msg, l+2);
-       if (nt)
-               *ntmode = p+1;
-       else
-               qi->QI_ELEMENT(notify) = p - (unsigned char *)qi - sizeof(Q931_info_t);
-       p[0] = IE_NOTIFY;
-       p[1] = l;
-       p[2] = 0x80 + notify;
-}
-
-static void dec_ie_notify(unsigned char *p, Q931_info_t *qi, int *notify, int nt, struct misdn_bchannel *bc)
-{
-       *notify = -1;
-
-       if (!nt)
-       {
-               p = NULL;
-               if (qi->QI_ELEMENT(notify))
-                       p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(notify) + 1;
-       }
-       if (!p)
-               return;
-       if (p[0] < 1)
-       {
-               printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
-               return;
-       }
-
-       *notify = p[1] & 0x7f;
-
-       if (MISDN_IE_DEBG) printf("    notify=%d\n", *notify);
-}
-
-
-/* IE_PROGRESS */
-static void enc_ie_progress(unsigned char **ntmode, msg_t *msg, int coding, int location, int progress, int nt, struct misdn_bchannel *bc)
-{
-       unsigned char *p;
-       Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
-       int l;
-
-       if (coding<0 || coding>0x03)
-       {
-               printf("%s: ERROR: coding(%d) is out of range.\n", __FUNCTION__, coding);
-               return;
-       }
-       if (location<0 || location>0x0f)
-       {
-               printf("%s: ERROR: location(%d) is out of range.\n", __FUNCTION__, location);
-               return;
-       }
-       if (progress<0 || progress>0x7f)
-       {
-               printf("%s: ERROR: progress(%d) is out of range.\n", __FUNCTION__, progress);
-               return;
-       }
-
-       if (MISDN_IE_DEBG) printf("    coding=%d location=%d progress=%d\n", coding, location, progress);
-
-       l = 2;
-       p = msg_put(msg, l+2);
-       if (nt)
-               *ntmode = p+1;
-       else
-               qi->QI_ELEMENT(progress) = p - (unsigned char *)qi - sizeof(Q931_info_t);
-       p[0] = IE_PROGRESS;
-       p[1] = l;
-       p[2] = 0x80 + (coding<<5) + location;
-       p[3] = 0x80 + progress;
-}
-
-static void dec_ie_progress(unsigned char *p, Q931_info_t *qi, int *coding, int *location, int *progress, int nt, struct misdn_bchannel *bc)
-{
-       *coding = -1;
-       *location = -1;
-       //*progress = -1;
-       *progress = 0;
-
-       if (!nt)
-       {
-               p = NULL;
-               if (qi->QI_ELEMENT(progress))
-                       p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(progress) + 1;
-       }
-       if (!p)
-               return;
-       if (p[0] < 1)
-       {
-               printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
-               return;
-       }
-
-       *coding = (p[1]&0x60) >> 5;
-       *location = p[1] & 0x0f;
-       *progress = p[2] & 0x7f;
-
-       if (MISDN_IE_DEBG) printf("    coding=%d location=%d progress=%d\n", *coding, *location, *progress);
-}
-
-
-/* IE_REDIR_NR (redirecting = during MT_SETUP) */
-static void enc_ie_redir_nr(unsigned char **ntmode, msg_t *msg, int type, int plan, int present, int screen, int reason, char *number, int nt, struct misdn_bchannel *bc)
-{
-       unsigned char *p;
-       Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
-       int l;
-
-       if (type<0 || type>7)
-       {
-               printf("%s: ERROR: type(%d) is out of range.\n", __FUNCTION__, type);
-               return;
-       }
-       if (plan<0 || plan>15)
-       {
-               printf("%s: ERROR: plan(%d) is out of range.\n", __FUNCTION__, plan);
-               return;
-       }
-       if (present > 3)
-       {
-               printf("%s: ERROR: present(%d) is out of range.\n", __FUNCTION__, present);
-               return;
-       }
-       if (present >= 0) if (screen<0 || screen>3)
-       {
-               printf("%s: ERROR: screen(%d) is out of range.\n", __FUNCTION__, screen);
-               return;
-       }
-       if (reason > 0x0f)
-       {
-               printf("%s: ERROR: reason(%d) is out of range.\n", __FUNCTION__, reason);
-               return;
-       }
-
-       if (MISDN_IE_DEBG) printf("    type=%d plan=%d present=%d screen=%d readon=%d number='%s'\n", type, plan, present, screen, reason, number);
-
-       l = 1;
-       if (number)
-               l += strlen((char *)number);
-       if (present >= 0)
-       {
-               l += 1;
-               if (reason >= 0)
-                       l += 1;
-       }
-       p = msg_put(msg, l+2);
-       if (nt)
-               *ntmode = p+1;
-       else
-               qi->QI_ELEMENT(redirect_nr) = p - (unsigned char *)qi - sizeof(Q931_info_t);
-       p[0] = IE_REDIR_NR;
-       p[1] = l;
-       if (present >= 0)
-       {
-               if (reason >= 0)
-               {
-                       p[2] = 0x00 + (type<<4) + plan;
-                       p[3] = 0x00 + (present<<5) + screen;
-                       p[4] = 0x80 + reason;
-                       if (number)
-                               strncpy((char *)p+5, (char *)number, strlen((char *)number));
-               } else
-               {
-                       p[2] = 0x00 + (type<<4) + plan;
-                       p[3] = 0x80 + (present<<5) + screen;
-                       if (number)
-                               strncpy((char *)p+4, (char *)number, strlen((char *)number));
-               }
-       } else
-       {
-               p[2] = 0x80 + (type<<4) + plan;
-               if (number) if (number[0])
-                       strncpy((char *)p+3, (char *)number, strlen((char *)number));
-       }
-}
-
-static void dec_ie_redir_nr(unsigned char *p, Q931_info_t *qi, int *type, int *plan, int *present, int *screen, int *reason, char *number, size_t number_len, int nt, struct misdn_bchannel *bc)
-{
-       *type = -1;
-       *plan = -1;
-       *present = -1;
-       *screen = -1;
-       *reason = -1;
-       *number = '\0';
-
-       if (!nt)
-       {
-               p = NULL;
-               if (qi->QI_ELEMENT(redirect_nr))
-                       p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(redirect_nr) + 1;
-       }
-       if (!p)
-               return;
-       if (p[0] < 1)
-       {
-               printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
-               return;
-       }
-
-       *type = (p[1]&0x70) >> 4;
-       *plan = p[1] & 0xf;
-       if (!(p[1] & 0x80))
-       {
-               *present = (p[2]&0x60) >> 5;
-               *screen = p[2] & 0x3;
-               if (!(p[2] & 0x80))
-               {
-                       *reason = p[3] & 0x0f;
-                       strnncpy(number, (char *)p+4, p[0]-3, number_len);
-               } else
-               {
-                       strnncpy(number, (char *)p+3, p[0]-2, number_len);
-               }
-       } else
-       {
-               strnncpy(number, (char *)p+2, p[0]-1, number_len);
-       }
-
-       if (MISDN_IE_DEBG) printf("    type=%d plan=%d present=%d screen=%d reason=%d number='%s'\n", *type, *plan, *present, *screen, *reason, number);
-}
-
-
-/* IE_REDIR_DN (redirection = during MT_NOTIFY) */
-static void enc_ie_redir_dn(unsigned char **ntmode, msg_t *msg, int type, int plan, int present, char *number, int nt, struct misdn_bchannel *bc)
-{
-       unsigned char *p;
-       Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
-       int l;
-
-       if (type<0 || type>7)
-       {
-               printf("%s: ERROR: type(%d) is out of range.\n", __FUNCTION__, type);
-               return;
-       }
-       if (plan<0 || plan>15)
-       {
-               printf("%s: ERROR: plan(%d) is out of range.\n", __FUNCTION__, plan);
-               return;
-       }
-       if (present > 3)
-       {
-               printf("%s: ERROR: present(%d) is out of range.\n", __FUNCTION__, present);
-               return;
-       }
-
-       if (MISDN_IE_DEBG) printf("    type=%d plan=%d present=%d number='%s'\n", type, plan, present, number);
-
-       l = 1;
-       if (number)
-               l += strlen((char *)number);
-       if (present >= 0)
-               l += 1;
-       p = msg_put(msg, l+2);
-       if (nt)
-               *ntmode = p+1;
-       else {
-               qi->QI_ELEMENT(redirect_dn) = p - (unsigned char *)qi - sizeof(Q931_info_t);
-       }
-       p[0] = IE_REDIR_DN;
-       p[1] = l;
-       if (present >= 0)
-       {
-               p[2] = 0x00 + (type<<4) + plan;
-               p[3] = 0x80 + (present<<5);
-               if (number)
-                       strncpy((char *)p+4, (char *)number, strlen((char *)number));
-       } else
-       {
-               p[2] = 0x80 + (type<<4) + plan;
-               if (number)
-                       strncpy((char *)p+3, (char *)number, strlen((char *)number));
-       }
-}
-
-static void dec_ie_redir_dn(unsigned char *p, Q931_info_t *qi, int *type, int *plan, int *present, char *number, size_t number_len, int nt, struct misdn_bchannel *bc)
-{
-       *type = -1;
-       *plan = -1;
-       *present = -1;
-       *number = '\0';
-
-       if (!nt)
-       {
-               p = NULL;
-               if (qi->QI_ELEMENT(redirect_dn))
-                       p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(redirect_dn) + 1;
-       }
-       if (!p)
-               return;
-       if (p[0] < 1)
-       {
-               printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
-               return;
-       }
-
-       *type = (p[1]&0x70) >> 4;
-       *plan = p[1] & 0xf;
-       if (!(p[1] & 0x80))
-       {
-               *present = (p[2]&0x60) >> 5;
-               strnncpy(number, (char *)p+3, p[0]-2, number_len);
-       } else
-       {
-               strnncpy(number, (char *)p+2, p[0]-1, number_len);
-       }
-
-       if (MISDN_IE_DEBG) printf("    type=%d plan=%d present=%d number='%s'\n", *type, *plan, *present, number);
-}
-
-
-/* IE_USERUSER */
-#if 1
-static void enc_ie_useruser(unsigned char **ntmode, msg_t *msg, int protocol, char *user, int user_len, int nt, struct misdn_bchannel *bc)
-{
-       unsigned char *p;
-       Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
-       int l;
-
-       if (protocol<0 || protocol>127)
-       {
-               printf("%s: ERROR: protocol(%d) is out of range.\n", __FUNCTION__, protocol);
-               return;
-       }
-       if (!user || user_len<=0)
-       {
-               return;
-       }
-
-       if (MISDN_IE_DEBG) {
-               size_t i;
-               char debug[768];
-
-               for (i = 0; i < user_len; ++i) {
-                       sprintf(debug + (i * 3), " %02hhx", (unsigned char)user[i]);
-               }
-               debug[i * 3] = 0;
-               printf("    protocol=%d user-user%s\n", protocol, debug);
-       }
-
-       l = user_len+1;
-       p = msg_put(msg, l+3);
-       if (nt)
-               *ntmode = p+1;
-       else
-               qi->QI_ELEMENT(useruser) = p - (unsigned char *)qi - sizeof(Q931_info_t);
-       p[0] = IE_USER_USER;
-       p[1] = l;
-       p[2] = protocol;
-       memcpy(p+3, user, user_len);
-}
-#endif
-
-#if 1
-static void dec_ie_useruser(unsigned char *p, Q931_info_t *qi, int *protocol, char *user, int *user_len, int nt, struct misdn_bchannel *bc)
-{
-       *user_len = 0;
-       *protocol = -1;
-
-       if (!nt)
-       {
-               p = NULL;
-               if (qi->QI_ELEMENT(useruser))
-                       p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(useruser) + 1;
-       }
-       if (!p)
-               return;
-
-       *user_len = p[0]-1;
-       if (p[0] < 1)
-               return;
-       *protocol = p[1];
-       memcpy(user, p+2, (*user_len<=128)?*(user_len):128); /* clip to 128 maximum */
-
-       if (MISDN_IE_DEBG) {
-               int i;
-               char debug[768];
-
-               for (i = 0; i < *user_len; ++i) {
-                       sprintf(debug + (i * 3), " %02hhx", (unsigned char)user[i]);
-               }
-               debug[i * 3] = 0;
-               printf("    protocol=%d user-user%s\n", *protocol, debug);
-       }
-}
-#endif
-
-/* IE_DISPLAY */
-static void enc_ie_restart_ind(unsigned char **ntmode, msg_t *msg, unsigned char rind, int nt, struct misdn_bchannel *bc)
-{
-       unsigned char *p;
-       Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
-       /* if (MISDN_IE_DEBG) printf("    display='%s' (len=%d)\n", display, strlen((char *)display)); */
-
-       p = msg_put(msg, 3);
-       if (nt)
-               *ntmode = p+1;
-       else
-               qi->QI_ELEMENT(restart_ind) = p - (unsigned char *)qi - sizeof(Q931_info_t);
-       p[0] = IE_RESTART_IND;
-       p[1] = 1;
-       p[2] = rind;
-
-}
diff --git a/channels/misdn/isdn_lib.c b/channels/misdn/isdn_lib.c
deleted file mode 100644 (file)
index cb64106..0000000
+++ /dev/null
@@ -1,4819 +0,0 @@
-/*
- * Chan_Misdn -- Channel Driver for Asterisk
- *
- * Interface to mISDN
- *
- * Copyright (C) 2004, Christian Richter
- *
- * Christian Richter <crich@beronet.com>
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License
- */
-
-/*! \file
- * \brief Interface to mISDN
- * \author Christian Richter <crich@beronet.com>
- */
-
-/*** MODULEINFO
-       <support_level>extended</support_level>
- ***/
-
-#include <syslog.h>
-#include <sys/time.h>
-#include <mISDNuser/isdn_debug.h>
-
-#include "isdn_lib_intern.h"
-#include "isdn_lib.h"
-
-enum event_response_e (*cb_event)(enum event_e event, struct misdn_bchannel *bc, void *user_data);
-
-void (*cb_log)(int level, int port, char *tmpl, ...)
-       __attribute__ ((format (printf, 3, 4)));
-
-int (*cb_jb_empty)(struct misdn_bchannel *bc, char *buffer, int len);
-
-
-/*
- * Define ARRAY_LEN() because I cannot
- * #include "asterisk/utils.h"
- */
-#define ARRAY_LEN(a) (sizeof(a) / sizeof(a[0]))
-
-#include "asterisk/causes.h"
-
-void misdn_join_conf(struct misdn_bchannel *bc, int conf_id);
-void misdn_split_conf(struct misdn_bchannel *bc, int conf_id);
-
-int misdn_lib_get_l2_up(struct misdn_stack *stack);
-
-struct misdn_stack *get_misdn_stack(void);
-
-int misdn_lib_port_is_pri(int port)
-{
-       struct misdn_stack *stack=get_misdn_stack();
-       for ( ; stack; stack=stack->next) {
-               if (stack->port == port) {
-                       return stack->pri;
-               }
-       }
-
-       return -1;
-}
-
-int misdn_lib_port_is_nt(int port)
-{
-       struct misdn_stack *stack=get_misdn_stack();
-       for ( ; stack; stack=stack->next) {
-               if (stack->port == port) {
-                       return stack->nt;
-               }
-       }
-
-       return -1;
-}
-
-void misdn_make_dummy(struct misdn_bchannel *dummybc, int port, int l3id, int nt, int channel)
-{
-       memset (dummybc,0,sizeof(struct misdn_bchannel));
-       dummybc->port=port;
-       if (l3id==0)
-               dummybc->l3_id = MISDN_ID_DUMMY;
-       else
-               dummybc->l3_id=l3id;
-
-       dummybc->nt=nt;
-       dummybc->dummy=1;
-       dummybc->channel=channel;
-}
-
-int misdn_lib_port_block(int port)
-{
-       struct misdn_stack *stack=get_misdn_stack();
-       for ( ; stack; stack=stack->next) {
-               if (stack->port == port) {
-                       stack->blocked=1;
-                       return 0;
-               }
-       }
-       return -1;
-
-}
-
-int misdn_lib_port_unblock(int port)
-{
-       struct misdn_stack *stack=get_misdn_stack();
-       for ( ; stack; stack=stack->next) {
-               if (stack->port == port) {
-                       stack->blocked=0;
-                       return 0;
-               }
-       }
-       return -1;
-
-}
-
-int misdn_lib_is_port_blocked(int port)
-{
-       struct misdn_stack *stack=get_misdn_stack();
-       for ( ; stack; stack=stack->next) {
-               if (stack->port == port) {
-                       return stack->blocked;
-               }
-       }
-       return -1;
-}
-
-int misdn_lib_is_ptp(int port)
-{
-       struct misdn_stack *stack=get_misdn_stack();
-       for ( ; stack; stack=stack->next) {
-               if (stack->port == port) return stack->ptp;
-       }
-       return -1;
-}
-
-int misdn_lib_get_maxchans(int port)
-{
-       struct misdn_stack *stack=get_misdn_stack();
-       for ( ; stack; stack=stack->next) {
-               if (stack->port == port) {
-                       if (stack->pri)
-                               return 30;
-                       else
-                               return 2;
-               }
-       }
-       return -1;
-}
-
-
-struct misdn_stack *get_stack_by_bc(struct misdn_bchannel *bc)
-{
-       struct misdn_stack *stack = get_misdn_stack();
-
-       if (!bc)
-               return NULL;
-
-       for ( ; stack; stack = stack->next) {
-               if (bc->port == stack->port)
-                       return stack;
-       }
-
-       return NULL;
-}
-
-
-void get_show_stack_details(int port, char *buf)
-{
-       struct misdn_stack *stack = get_misdn_stack();
-
-       for (; stack; stack = stack->next) {
-               if (stack->port == port) {
-                       break;
-               }
-       }
-
-       if (stack) {
-               sprintf(buf, "* Port %2d Type %s Prot. %s L2Link %s L1Link:%s Blocked:%d",
-                       stack->port,
-                       stack->nt ? "NT" : "TE",
-                       stack->ptp ? "PTP" : "PMP",
-                       (stack->nt && !stack->ptp) ? "UNKN" : stack->l2link ? "UP  " : "DOWN",
-                       stack->l1link ? "UP  " : "DOWN",
-                       stack->blocked);
-       } else {
-               buf[0] = 0;
-       }
-}
-
-
-static int nt_err_cnt =0 ;
-
-enum global_states {
-       MISDN_INITIALIZING,
-       MISDN_INITIALIZED
-} ;
-
-static enum global_states  global_state=MISDN_INITIALIZING;
-
-
-#include <mISDNuser/net_l2.h>
-#include <mISDNuser/tone.h>
-#include <unistd.h>
-#include <semaphore.h>
-#include <pthread.h>
-#include <signal.h>
-
-#include "isdn_lib.h"
-
-
-struct misdn_lib {
-       /*! \brief mISDN device handle returned by mISDN_open() */
-       int midev;
-
-       pthread_t event_thread;
-       pthread_t event_handler_thread;
-
-       void *user_data;
-
-       msg_queue_t activatequeue;
-
-       sem_t new_msg;
-
-       struct misdn_stack *stack_list;
-} ;
-
-#ifndef ECHOCAN_ON
-#define ECHOCAN_ON 123
-#define ECHOCAN_OFF 124
-#endif
-
-#define MISDN_DEBUG 0
-
-void misdn_tx_jitter(struct misdn_bchannel *bc, int len);
-
-struct misdn_bchannel *find_bc_by_l3id(struct misdn_stack *stack, unsigned long l3id);
-
-int manager_isdn_handler(iframe_t *frm ,msg_t *msg);
-
-int misdn_lib_port_restart(int port);
-int misdn_lib_pid_restart(int pid);
-
-extern struct isdn_msg msgs_g[];
-
-#define ISDN_PID_L3_B_USER 0x430000ff
-#define ISDN_PID_L4_B_USER 0x440000ff
-
-/* #define MISDN_IBUF_SIZE 1024 */
-#define MISDN_IBUF_SIZE 512
-
-/*  Fine Tuning of Inband  Signalling time */
-#define TONE_ALERT_CNT 41 /*  1 Sec  */
-#define TONE_ALERT_SILENCE_CNT 200 /*  4 Sec */
-
-#define TONE_BUSY_CNT 20 /*  ? */
-#define TONE_BUSY_SILENCE_CNT 48 /*  ? */
-
-static int entity;
-
-static struct misdn_lib *glob_mgr;
-
-static char tone_425_flip[TONE_425_SIZE];
-static char tone_silence_flip[TONE_SILENCE_SIZE];
-
-static void misdn_lib_isdn_event_catcher(void *arg);
-static int handle_event_nt(void *dat, void *arg);
-
-
-void stack_holder_add(struct misdn_stack *stack, struct misdn_bchannel *holder);
-void stack_holder_remove(struct misdn_stack *stack, struct misdn_bchannel *holder);
-struct misdn_bchannel *stack_holder_find(struct misdn_stack *stack, unsigned long l3id);
-
-/* from isdn_lib.h */
-       /* user iface */
-void te_lib_destroy(int midev) ;
-struct misdn_bchannel *manager_find_bc_by_pid(int pid);
-void manager_ph_control_block(struct misdn_bchannel *bc, int c1, void *c2, int c2_len);
-void manager_clean_bc(struct misdn_bchannel *bc );
-void manager_bchannel_setup (struct misdn_bchannel *bc);
-void manager_bchannel_cleanup (struct misdn_bchannel *bc);
-
-void ec_chunk( struct misdn_bchannel *bc, unsigned char *rxchunk, unsigned char *txchunk, int chunk_size);
-       /* end */
-int bchdev_echocancel_activate(struct misdn_bchannel* dev);
-void bchdev_echocancel_deactivate(struct misdn_bchannel* dev);
-/* end */
-
-
-static char *bearer2str(int cap) {
-       static char *bearers[]={
-               "Speech",
-               "Audio 3.1k",
-               "Unres Digital",
-               "Res Digital",
-               "Unknown Bearer"
-       };
-
-       switch (cap) {
-       case INFO_CAPABILITY_SPEECH:
-               return bearers[0];
-               break;
-       case INFO_CAPABILITY_AUDIO_3_1K:
-               return bearers[1];
-               break;
-       case INFO_CAPABILITY_DIGITAL_UNRESTRICTED:
-               return bearers[2];
-               break;
-       case INFO_CAPABILITY_DIGITAL_RESTRICTED:
-               return bearers[3];
-               break;
-       default:
-               return bearers[4];
-               break;
-       }
-}
-
-
-static char flip_table[256];
-
-static void init_flip_bits(void)
-{
-       int i,k;
-
-       for (i = 0 ; i < 256 ; i++) {
-               unsigned char sample = 0 ;
-               for (k = 0; k<8; k++) {
-                       if ( i & 1 << k ) sample |= 0x80 >>  k;
-               }
-               flip_table[i] = sample;
-       }
-}
-
-static char * flip_buf_bits ( char * buf , int len)
-{
-       int i;
-       char * start = buf;
-
-       for (i = 0 ; i < len; i++) {
-               buf[i] = flip_table[(unsigned char)buf[i]];
-       }
-
-       return start;
-}
-
-
-
-
-static msg_t *create_l2msg(int prim, int dinfo, int size) /* NT only */
-{
-       int i = 0;
-       msg_t *dmsg;
-
-       while(i < 10)
-       {
-               dmsg = prep_l3data_msg(prim, dinfo, size, 256, NULL);
-               if (dmsg)
-                       return(dmsg);
-
-               if (!i)
-                       printf("cannot allocate memory, trying again...\n");
-               i++;
-               usleep(300000);
-       }
-       printf("cannot allocate memory, system overloaded.\n");
-       exit(-1);
-}
-
-
-
-msg_t *create_l3msg(int prim, int mt, int dinfo, int size, int ntmode)
-{
-       int i = 0;
-       msg_t *dmsg;
-       Q931_info_t *qi;
-       iframe_t *frm;
-
-       if (!ntmode)
-               size = sizeof(Q931_info_t)+2;
-
-       while(i < 10) {
-               if (ntmode) {
-                       dmsg = prep_l3data_msg(prim, dinfo, size, 256, NULL);
-                       if (dmsg) {
-                               return(dmsg);
-                       }
-               } else {
-                       dmsg = alloc_msg(size+256+mISDN_HEADER_LEN+DEFAULT_HEADROOM);
-                       if (dmsg)
-                       {
-                               memset(msg_put(dmsg,size+mISDN_HEADER_LEN), 0, size+mISDN_HEADER_LEN);
-                               frm = (iframe_t *)dmsg->data;
-                               frm->prim = prim;
-                               frm->dinfo = dinfo;
-                               qi = (Q931_info_t *)(dmsg->data + mISDN_HEADER_LEN);
-                               qi->type = mt;
-                               return(dmsg);
-                       }
-               }
-
-               if (!i) printf("cannot allocate memory, trying again...\n");
-               i++;
-               usleep(300000);
-       }
-       printf("cannot allocate memory, system overloaded.\n");
-       exit(-1);
-}
-
-
-static int send_msg (int midev, struct misdn_bchannel *bc, msg_t *dmsg)
-{
-       iframe_t *frm = (iframe_t *)dmsg->data;
-       struct misdn_stack *stack=get_stack_by_bc(bc);
-
-       if (!stack) {
-               cb_log(0,bc->port,"send_msg: IEK!! no stack\n ");
-               return -1;
-       }
-
-       frm->addr = (stack->upper_id | FLG_MSG_DOWN);
-       frm->dinfo = bc->l3_id;
-       frm->len = (dmsg->len) - mISDN_HEADER_LEN;
-
-       cb_log(4,stack->port,"Sending msg, prim:%x addr:%x dinfo:%x\n",frm->prim,frm->addr,frm->dinfo);
-
-       mISDN_write(midev, dmsg->data, dmsg->len, TIMEOUT_1SEC);
-       free_msg(dmsg);
-
-       return 0;
-}
-
-
-static int mypid=1;
-
-
-int misdn_cap_is_speech(int cap)
-/** Poor mans version **/
-{
-       if ( (cap != INFO_CAPABILITY_DIGITAL_UNRESTRICTED) &&
-            (cap != INFO_CAPABILITY_DIGITAL_RESTRICTED) ) return 1;
-       return 0;
-}
-
-int misdn_inband_avail(struct misdn_bchannel *bc)
-{
-
-       if (!bc->early_bconnect) {
-               /* We have opted to never receive any available inband recorded messages */
-               return 0;
-       }
-
-       switch (bc->progress_indicator) {
-       case INFO_PI_INBAND_AVAILABLE:
-       case INFO_PI_CALL_NOT_E2E_ISDN:
-       case INFO_PI_CALLED_NOT_ISDN:
-               return 1;
-       default:
-               return 0;
-       }
-       return 0;
-}
-
-
-static void dump_chan_list(struct misdn_stack *stack)
-{
-       int i;
-
-       for (i = 0; i <= stack->b_num; ++i) {
-               cb_log(6, stack->port, "Idx:%d stack->cchan:%d in_use:%d Chan:%d\n",
-                       i, stack->channels[i], stack->bc[i].in_use, i + 1);
-       }
-#if defined(AST_MISDN_ENHANCEMENTS)
-       for (i = MAX_BCHANS + 1; i < ARRAY_LEN(stack->bc); ++i) {
-               if (stack->bc[i].in_use) {
-                       cb_log(6, stack->port, "Idx:%d stack->cchan:%d REGISTER Chan:%d in_use\n",
-                               i, stack->channels[i], i + 1);
-               }
-       }
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-}
-
-
-void misdn_dump_chanlist(void)
-{
-       struct misdn_stack *stack=get_misdn_stack();
-       for ( ; stack; stack=stack->next) {
-               dump_chan_list(stack);
-       }
-
-}
-
-static int set_chan_in_stack(struct misdn_stack *stack, int channel)
-{
-       cb_log(4,stack->port,"set_chan_in_stack: %d\n",channel);
-       dump_chan_list(stack);
-       if (1 <= channel && channel <= ARRAY_LEN(stack->channels)) {
-               if (!stack->channels[channel-1])
-                       stack->channels[channel-1] = 1;
-               else {
-                       cb_log(4,stack->port,"channel already in use:%d\n", channel );
-                       return -1;
-               }
-       } else {
-               cb_log(0,stack->port,"couldn't set channel %d in\n", channel );
-               return -1;
-       }
-
-       return 0;
-}
-
-
-
-static int find_free_chan_in_stack(struct misdn_stack *stack, struct misdn_bchannel *bc, int channel, int dec)
-{
-       int i;
-       int chan = 0;
-       int bnums;
-
-       if (bc->channel_found) {
-               return 0;
-       }
-
-       bc->channel_found = 1;
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-       if (bc->is_register_pool) {
-               pthread_mutex_lock(&stack->st_lock);
-               for (i = MAX_BCHANS + 1; i < ARRAY_LEN(stack->channels); ++i) {
-                       if (!stack->channels[i]) {
-                               chan = i + 1;
-                               cb_log(3, stack->port, " --> found REGISTER chan: %d\n", chan);
-                               break;
-                       }
-               }
-       } else
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-       {
-               cb_log(5, stack->port, "find_free_chan: req_chan:%d\n", channel);
-
-               if (channel < 0 || channel > MAX_BCHANS) {
-                       cb_log(0, stack->port, " !! out of bound call to find_free_chan_in_stack! (ch:%d)\n", channel);
-                       return 0;
-               }
-
-               --channel;
-
-               pthread_mutex_lock(&stack->st_lock);
-               bnums = stack->pri ? stack->b_num : stack->b_num - 1;
-               if (dec) {
-                       for (i = bnums; i >= 0; --i) {
-                               if (i != 15 && (channel < 0 || i == channel)) { /* skip E1 D channel ;) and work with chan preselection */
-                                       if (!stack->channels[i]) {
-                                               chan = i + 1;
-                                               cb_log(3, stack->port, " --> found chan%s: %d\n", channel >= 0 ? " (preselected)" : "", chan);
-                                               break;
-                                       }
-                               }
-                       }
-               } else {
-                       for (i = 0; i <= bnums; ++i) {
-                               if (i != 15 && (channel < 0 || i == channel)) { /* skip E1 D channel ;) and work with chan preselection */
-                                       if (!stack->channels[i]) {
-                                               chan = i + 1;
-                                               cb_log(3, stack->port, " --> found chan%s: %d\n", channel >= 0 ? " (preselected)" : "", chan);
-                                               break;
-                                       }
-                               }
-                       }
-               }
-       }
-
-       if (!chan) {
-               pthread_mutex_unlock(&stack->st_lock);
-               cb_log(1, stack->port, " !! NO FREE CHAN IN STACK\n");
-               dump_chan_list(stack);
-               bc->out_cause = AST_CAUSE_NORMAL_CIRCUIT_CONGESTION;
-               return -1;
-       }
-
-       if (set_chan_in_stack(stack, chan) < 0) {
-               pthread_mutex_unlock(&stack->st_lock);
-               cb_log(0, stack->port, "Channel Already in use:%d\n", chan);
-               bc->out_cause = AST_CAUSE_REQUESTED_CHAN_UNAVAIL;
-               return -1;
-       }
-       pthread_mutex_unlock(&stack->st_lock);
-
-       bc->channel = chan;
-       return 0;
-}
-
-/*!
- * \internal
- * \brief Release a B channel to the allocation pool.
- *
- * \param stack Which port stack B channel belongs.
- * \param channel B channel to release. (Range 1-MAX_BCHANS representing B1-Bn)
- *
- * \return Nothing
- *
- * \note
- * Must be called after clean_up_bc() to make sure that the media stream is
- * no longer connected.
- */
-static void empty_chan_in_stack(struct misdn_stack *stack, int channel)
-{
-       if (channel < 1 || ARRAY_LEN(stack->channels) < channel) {
-               cb_log(0, stack->port, "empty_chan_in_stack: cannot empty channel %d\n", channel);
-               return;
-       }
-
-       cb_log(4, stack->port, "empty_chan_in_stack: %d\n", channel);
-       stack->channels[channel - 1] = 0;
-       dump_chan_list(stack);
-}
-
-char *bc_state2str(enum bchannel_state state) {
-       int i;
-
-       struct bchan_state_s {
-               char *n;
-               enum bchannel_state s;
-       } states[] = {
-               {"BCHAN_CLEANED", BCHAN_CLEANED },
-               {"BCHAN_EMPTY", BCHAN_EMPTY},
-               {"BCHAN_ACTIVATED", BCHAN_ACTIVATED},
-               {"BCHAN_BRIDGED", BCHAN_BRIDGED},
-               {"BCHAN_RELEASE", BCHAN_RELEASE},
-               {"BCHAN_ERROR", BCHAN_ERROR}
-       };
-
-       for (i=0; i< sizeof(states)/sizeof(struct bchan_state_s); i++)
-               if ( states[i].s == state)
-                       return states[i].n;
-
-       return "UNKNOWN";
-}
-
-void bc_state_change(struct misdn_bchannel *bc, enum bchannel_state state)
-{
-       cb_log(5,bc->port,"BC_STATE_CHANGE: l3id:%x from:%s to:%s\n",
-               bc->l3_id,
-              bc_state2str(bc->bc_state),
-              bc_state2str(state) );
-
-       switch (state) {
-               case BCHAN_ACTIVATED:
-                       if (bc->next_bc_state ==  BCHAN_BRIDGED) {
-                               misdn_join_conf(bc, bc->conf_id);
-                               bc->next_bc_state = BCHAN_EMPTY;
-                               return;
-                       }
-               default:
-                       bc->bc_state=state;
-                       break;
-       }
-}
-
-static void bc_next_state_change(struct misdn_bchannel *bc, enum bchannel_state state)
-{
-       cb_log(5,bc->port,"BC_NEXT_STATE_CHANGE: from:%s to:%s\n",
-              bc_state2str(bc->next_bc_state),
-              bc_state2str(state) );
-
-       bc->next_bc_state=state;
-}
-
-/*!
- * \internal
- * \brief Empty the B channel record of most call data.
- *
- * \param bc B channel record to empty of most call data.
- *
- * \return Nothing
- *
- * \note
- * Sets the last_used time and must be called before clearing bc->in_use.
- */
-static void empty_bc(struct misdn_bchannel *bc)
-{
-       bc->caller.presentation = 0;    /* allowed */
-       bc->caller.number_plan = NUMPLAN_ISDN;
-       bc->caller.number_type = NUMTYPE_UNKNOWN;
-       bc->caller.name[0] = 0;
-       bc->caller.number[0] = 0;
-       bc->caller.subaddress[0] = 0;
-
-       bc->connected.presentation = 0; /* allowed */
-       bc->connected.number_plan = NUMPLAN_ISDN;
-       bc->connected.number_type = NUMTYPE_UNKNOWN;
-       bc->connected.name[0] = 0;
-       bc->connected.number[0] = 0;
-       bc->connected.subaddress[0] = 0;
-
-       bc->redirecting.from.presentation = 0;  /* allowed */
-       bc->redirecting.from.number_plan = NUMPLAN_ISDN;
-       bc->redirecting.from.number_type = NUMTYPE_UNKNOWN;
-       bc->redirecting.from.name[0] = 0;
-       bc->redirecting.from.number[0] = 0;
-       bc->redirecting.from.subaddress[0] = 0;
-
-       bc->redirecting.to.presentation = 0;    /* allowed */
-       bc->redirecting.to.number_plan = NUMPLAN_ISDN;
-       bc->redirecting.to.number_type = NUMTYPE_UNKNOWN;
-       bc->redirecting.to.name[0] = 0;
-       bc->redirecting.to.number[0] = 0;
-       bc->redirecting.to.subaddress[0] = 0;
-
-       bc->redirecting.reason = mISDN_REDIRECTING_REASON_UNKNOWN;
-       bc->redirecting.count = 0;
-       bc->redirecting.to_changed = 0;
-
-       bc->dummy=0;
-
-       bc->bframe_len=0;
-
-       bc->cw= 0;
-
-       bc->dec=0;
-       bc->channel = 0;
-
-       bc->sending_complete = 0;
-
-       bc->restart_channel=0;
-
-       bc->conf_id = 0;
-
-       bc->need_more_infos = 0;
-
-       bc->send_dtmf=0;
-       bc->nodsp=0;
-       bc->nojitter=0;
-
-       bc->time_usec=0;
-
-       bc->rxgain=0;
-       bc->txgain=0;
-
-       bc->crypt=0;
-       bc->curptx=0; bc->curprx=0;
-
-       bc->crypt_key[0] = 0;
-
-       bc->generate_tone=0;
-       bc->tone_cnt=0;
-
-       bc->active = 0;
-
-       bc->early_bconnect = 1;
-
-#ifdef MISDN_1_2
-       *bc->pipeline = 0;
-#else
-       bc->ec_enable = 0;
-       bc->ec_deftaps = 128;
-#endif
-
-       bc->AOCD_need_export = 0;
-
-       bc->orig=0;
-
-       bc->cause = AST_CAUSE_NORMAL_CLEARING;
-       bc->out_cause = AST_CAUSE_NORMAL_CLEARING;
-
-       bc->display_connected = 0;      /* none */
-       bc->display_setup = 0;  /* none */
-
-       bc->outgoing_colp = 0;/* pass */
-
-       bc->presentation = 0;   /* allowed */
-       bc->set_presentation = 0;
-
-       bc->notify_description_code = mISDN_NOTIFY_CODE_INVALID;
-
-       bc->progress_coding=0;
-       bc->progress_location=0;
-       bc->progress_indicator=0;
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-       bc->div_leg_3_rx_wanted = 0;
-       bc->div_leg_3_tx_pending = 0;
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-/** Set Default Bearer Caps **/
-       bc->capability=INFO_CAPABILITY_SPEECH;
-       bc->law=INFO_CODEC_ALAW;
-       bc->mode=0;
-       bc->rate=0x10;
-       bc->user1=0;
-       bc->urate=0;
-
-       bc->hdlc=0;
-
-       bc->dialed.number_plan = NUMPLAN_ISDN;
-       bc->dialed.number_type = NUMTYPE_UNKNOWN;
-       bc->dialed.number[0] = 0;
-       bc->dialed.subaddress[0] = 0;
-
-       bc->info_dad[0] = 0;
-       bc->display[0] = 0;
-       bc->infos_pending[0] = 0;
-       bc->uu[0]=0;
-       bc->uulen=0;
-
-       bc->fac_in.Function = Fac_None;
-       bc->fac_out.Function = Fac_None;
-
-       bc->te_choose_channel = 0;
-       bc->channel_found= 0;
-
-       gettimeofday(&bc->last_used, NULL);
-}
-
-
-static int clean_up_bc(struct misdn_bchannel *bc)
-{
-       int ret=0;
-       unsigned char buff[32];
-       struct misdn_stack * stack;
-
-       cb_log(3, bc->port, "$$$ CLEANUP CALLED pid:%d\n", bc->pid);
-
-       stack=get_stack_by_bc(bc);
-
-       if (!stack) return -1;
-
-       switch (bc->bc_state ) {
-       case BCHAN_CLEANED:
-               cb_log(5, stack->port, "$$$ Already cleaned up bc with stid :%x\n", bc->b_stid);
-               return -1;
-
-       default:
-               break;
-       }
-
-       cb_log(2, stack->port, "$$$ Cleaning up bc with stid :%x pid:%d\n", bc->b_stid, bc->pid);
-
-       manager_ec_disable(bc);
-
-       manager_bchannel_deactivate(bc);
-
-       mISDN_write_frame(stack->midev, buff, bc->layer_id|FLG_MSG_TARGET|FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
-
-       bc->b_stid = 0;
-       bc_state_change(bc, BCHAN_CLEANED);
-
-       return ret;
-}
-
-
-
-static void clear_l3(struct misdn_stack *stack)
-{
-       int i;
-
-       if (global_state == MISDN_INITIALIZED) {
-               for (i = 0; i <= stack->b_num; ++i) {
-                       cb_event(EVENT_CLEANUP, &stack->bc[i], NULL);
-                       empty_bc(&stack->bc[i]);
-                       clean_up_bc(&stack->bc[i]);
-                       empty_chan_in_stack(stack, i + 1);
-                       stack->bc[i].in_use = 0;
-               }
-#if defined(AST_MISDN_ENHANCEMENTS)
-               for (i = MAX_BCHANS + 1; i < ARRAY_LEN(stack->bc); ++i) {
-                       empty_bc(&stack->bc[i]);
-                       empty_chan_in_stack(stack, i + 1);
-                       stack->bc[i].in_use = 0;
-               }
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-       }
-}
-
-static int new_te_id = 0;
-
-static int misdn_lib_get_l1_down(struct misdn_stack *stack)
-{
-       /* Pull Up L1 */
-       iframe_t act;
-       act.prim = PH_DEACTIVATE | REQUEST;
-       act.addr = stack->upper_id | FLG_MSG_DOWN;
-       act.dinfo = 0;
-       act.len = 0;
-
-       cb_log(1, stack->port, "SENDING PH_DEACTIVATE | REQ\n");
-       return mISDN_write(stack->midev, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
-}
-
-
-static int misdn_lib_get_l2_down(struct misdn_stack *stack)
-{
-
-       if (stack->ptp && stack->nt) {
-               msg_t *dmsg;
-               /* L2 */
-               dmsg = create_l2msg(DL_RELEASE| REQUEST, 0, 0);
-
-               pthread_mutex_lock(&stack->nstlock);
-               if (stack->nst.manager_l3(&stack->nst, dmsg))
-                       free_msg(dmsg);
-               pthread_mutex_unlock(&stack->nstlock);
-       } else if (!stack->nt) {
-               iframe_t act;
-
-               act.prim = DL_RELEASE| REQUEST;
-               act.addr = (stack->upper_id |FLG_MSG_DOWN)  ;
-
-               act.dinfo = 0;
-               act.len = 0;
-               return mISDN_write(stack->midev, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
-       }
-       /* cannot deestablish L2 for NT PTMP to unknown TE TEIs */
-
-       return 0;
-}
-
-
-static int misdn_lib_get_l1_up(struct misdn_stack *stack)
-{
-       /* Pull Up L1 */
-       iframe_t act;
-       act.prim = PH_ACTIVATE | REQUEST;
-       act.addr = stack->upper_id | FLG_MSG_DOWN;
-
-       act.dinfo = 0;
-       act.len = 0;
-
-       cb_log(1, stack->port, "SENDING PH_ACTIVATE | REQ\n");
-       return mISDN_write(stack->midev, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
-}
-
-int misdn_lib_get_l2_up(struct misdn_stack *stack)
-{
-
-       if (stack->ptp && stack->nt) {
-               msg_t *dmsg;
-               /* L2 */
-               dmsg = create_l2msg(DL_ESTABLISH | REQUEST, 0, 0);
-
-               pthread_mutex_lock(&stack->nstlock);
-               if (stack->nst.manager_l3(&stack->nst, dmsg))
-                       free_msg(dmsg);
-               pthread_mutex_unlock(&stack->nstlock);
-       } else if (!stack->nt) {
-               iframe_t act;
-
-               act.prim = DL_ESTABLISH | REQUEST;
-               act.addr = (stack->upper_id |FLG_MSG_DOWN)  ;
-
-               act.dinfo = 0;
-               act.len = 0;
-               return mISDN_write(stack->midev, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
-       }
-       /* cannot establish L2 for NT PTMP to unknown TE TEIs */
-
-       return 0;
-}
-
-static int misdn_lib_get_short_status(struct misdn_stack *stack)
-{
-       iframe_t act;
-
-
-       act.prim = MGR_SHORTSTATUS | REQUEST;
-
-       act.addr = (stack->upper_id | MSG_BROADCAST)  ;
-
-       act.dinfo = SSTATUS_BROADCAST_BIT | SSTATUS_ALL;
-
-       act.len = 0;
-       return mISDN_write(stack->midev, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
-}
-
-
-
-static int create_process(int midev, struct misdn_bchannel *bc)
-{
-       iframe_t ncr;
-       int l3_id;
-       int proc_id;
-       struct misdn_stack *stack;
-
-       stack = get_stack_by_bc(bc);
-       if (stack->nt) {
-               if (find_free_chan_in_stack(stack, bc, bc->channel_preselected ? bc->channel : 0, 0) < 0) {
-                       return -1;
-               }
-               cb_log(4, stack->port, " -->  found channel: %d\n", bc->channel);
-
-               for (proc_id = 0; proc_id < MAXPROCS; ++proc_id) {
-                       if (stack->procids[proc_id] == 0) {
-                               break;
-                       }
-               }
-               if (proc_id == MAXPROCS) {
-                       cb_log(0, stack->port, "Couldn't Create New ProcId.\n");
-                       return -1;
-               }
-
-               stack->procids[proc_id] = 1;
-
-               l3_id = 0xff00 | proc_id;
-               bc->l3_id = l3_id;
-               cb_log(3, stack->port, " --> new_l3id %x\n", l3_id);
-       } else {
-               if ((stack->pri && stack->ptp) || bc->te_choose_channel) {
-                       /* we know exactly which channels are in use */
-                       if (find_free_chan_in_stack(stack, bc, bc->channel_preselected ? bc->channel : 0, bc->dec) < 0) {
-                               return -1;
-                       }
-                       cb_log(2, stack->port, " -->  found channel: %d\n", bc->channel);
-               } else {
-                       /* other phones could have made a call also on this port (ptmp) */
-                       bc->channel = 0xff;
-               }
-
-               /* if we are in te-mode, we need to create a process first */
-               if (++new_te_id > 0xffff) {
-                       new_te_id = 0x0001;
-               }
-
-               l3_id = (entity << 16) | new_te_id;
-               bc->l3_id = l3_id;
-               cb_log(3, stack->port, "--> new_l3id %x\n", l3_id);
-
-               /* send message */
-               ncr.prim = CC_NEW_CR | REQUEST;
-               ncr.addr = (stack->upper_id | FLG_MSG_DOWN);
-               ncr.dinfo = l3_id;
-               ncr.len = 0;
-               mISDN_write(midev, &ncr, mISDN_HEADER_LEN + ncr.len, TIMEOUT_1SEC);
-       }
-
-       return l3_id;
-}
-
-
-static int setup_bc(struct misdn_bchannel *bc)
-{
-       unsigned char buff[1025];
-       int midev;
-       int channel;
-       int b_stid;
-       int i;
-       mISDN_pid_t pid;
-       int ret;
-
-       struct misdn_stack *stack=get_stack_by_bc(bc);
-
-       if (!stack) {
-               cb_log(0, bc->port, "setup_bc: NO STACK FOUND!!\n");
-               return -1;
-       }
-
-       midev = stack->midev;
-       channel = bc->channel - 1 - (bc->channel > 16);
-       b_stid = stack->b_stids[channel >= 0 ? channel : 0];
-
-       switch (bc->bc_state) {
-               case BCHAN_CLEANED:
-                       break;
-               default:
-                       cb_log(4, stack->port, "$$$ bc already setup stid :%x (state:%s)\n", b_stid, bc_state2str(bc->bc_state) );
-                       return -1;
-       }
-
-       cb_log(5, stack->port, "$$$ Setting up bc with stid :%x\n", b_stid);
-
-       /*check if the b_stid is already initialized*/
-       for (i=0; i <= stack->b_num; i++) {
-               if (stack->bc[i].b_stid == b_stid) {
-                       cb_log(0, bc->port, "setup_bc: b_stid:%x already in use !!!\n", b_stid);
-                       return -1;
-               }
-       }
-
-       if (b_stid <= 0) {
-               cb_log(0, stack->port," -- Stid <=0 at the moment in channel:%d\n",channel);
-
-               bc_state_change(bc,BCHAN_ERROR);
-               return 1;
-       }
-
-       bc->b_stid = b_stid;
-
-       {
-               layer_info_t li;
-               memset(&li, 0, sizeof(li));
-
-               li.object_id = -1;
-               li.extentions = 0;
-
-               li.st = bc->b_stid; /*  given idx */
-
-
-#define MISDN_DSP
-#ifndef MISDN_DSP
-               bc->nodsp=1;
-#endif
-               if ( bc->hdlc || bc->nodsp) {
-                       cb_log(4, stack->port,"setup_bc: without dsp\n");
-                       {
-                               int l = sizeof(li.name);
-                               strncpy(li.name, "B L3", l);
-                               li.name[l-1] = 0;
-                       }
-                       li.pid.layermask = ISDN_LAYER((3));
-                       li.pid.protocol[3] = ISDN_PID_L3_B_USER;
-
-                       bc->layer=3;
-               } else {
-                       cb_log(4, stack->port,"setup_bc: with dsp\n");
-                       {
-                               int l = sizeof(li.name);
-                               strncpy(li.name, "B L4", l);
-                               li.name[l-1] = 0;
-                       }
-                       li.pid.layermask = ISDN_LAYER((4));
-                       li.pid.protocol[4] = ISDN_PID_L4_B_USER;
-
-                       bc->layer=4;
-               }
-
-               ret = mISDN_new_layer(midev, &li);
-               if (ret ) {
-                       cb_log(0, stack->port,"New Layer Err: %d %s\n",ret,strerror(errno));
-
-                       bc_state_change(bc,BCHAN_ERROR);
-                       return(-EINVAL);
-               }
-
-               bc->layer_id = li.id;
-       }
-
-       memset(&pid, 0, sizeof(pid));
-
-
-
-       cb_log(4, stack->port," --> Channel is %d\n", bc->channel);
-
-       if (bc->nodsp && !bc->hdlc) {
-               cb_log(2, stack->port," --> TRANSPARENT Mode (no DSP, no HDLC)\n");
-               pid.protocol[1] = ISDN_PID_L1_B_64TRANS;
-               pid.protocol[2] = ISDN_PID_L2_B_TRANS;
-               pid.protocol[3] = ISDN_PID_L3_B_USER;
-               pid.layermask = ISDN_LAYER((1)) | ISDN_LAYER((2)) | ISDN_LAYER((3));
-
-       } else if ( bc->hdlc ) {
-               cb_log(2, stack->port," --> HDLC Mode\n");
-               pid.protocol[1] = ISDN_PID_L1_B_64HDLC ;
-               pid.protocol[2] = ISDN_PID_L2_B_TRANS  ;
-               pid.protocol[3] = ISDN_PID_L3_B_USER;
-               pid.layermask = ISDN_LAYER((1)) | ISDN_LAYER((2)) | ISDN_LAYER((3)) ;
-       } else {
-               cb_log(2, stack->port," --> TRANSPARENT Mode\n");
-               pid.protocol[1] = ISDN_PID_L1_B_64TRANS;
-               pid.protocol[2] = ISDN_PID_L2_B_TRANS;
-               pid.protocol[3] = ISDN_PID_L3_B_DSP;
-               pid.protocol[4] = ISDN_PID_L4_B_USER;
-               pid.layermask = ISDN_LAYER((1)) | ISDN_LAYER((2)) | ISDN_LAYER((3)) | ISDN_LAYER((4));
-
-       }
-
-       ret = mISDN_set_stack(midev, bc->b_stid, &pid);
-
-       if (ret){
-               cb_log(0, stack->port,"$$$ Set Stack Err: %d %s\n",ret,strerror(errno));
-
-               mISDN_write_frame(midev, buff, bc->layer_id, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
-
-               bc_state_change(bc,BCHAN_ERROR);
-               cb_event(EVENT_BCHAN_ERROR, bc, glob_mgr->user_data);
-               return(-EINVAL);
-       }
-
-       ret = mISDN_get_setstack_ind(midev, bc->layer_id);
-
-       if (ret) {
-               cb_log(0, stack->port,"$$$ Set StackIND Err: %d %s\n",ret,strerror(errno));
-               mISDN_write_frame(midev, buff, bc->layer_id, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
-
-               bc_state_change(bc,BCHAN_ERROR);
-               cb_event(EVENT_BCHAN_ERROR, bc, glob_mgr->user_data);
-               return(-EINVAL);
-       }
-
-       ret = mISDN_get_layerid(midev, bc->b_stid, bc->layer) ;
-
-       bc->addr = ret>0? ret : 0;
-
-       if (!bc->addr) {
-               cb_log(0, stack->port,"$$$ Get Layerid Err: %d %s\n",ret,strerror(errno));
-               mISDN_write_frame(midev, buff, bc->layer_id, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
-
-               bc_state_change(bc,BCHAN_ERROR);
-               cb_event(EVENT_BCHAN_ERROR, bc, glob_mgr->user_data);
-               return (-EINVAL);
-       }
-
-       manager_bchannel_activate(bc);
-
-       bc_state_change(bc,BCHAN_ACTIVATED);
-
-       return 0;
-}
-
-
-
-/** IFACE **/
-static int init_bc(struct misdn_stack *stack, struct misdn_bchannel *bc, int midev, int port, int bidx)
-{
-       if (!bc) {
-               return -1;
-       }
-
-       cb_log(8, port, "Init.BC %d.\n",bidx);
-
-       bc->send_lock = malloc(sizeof(struct send_lock)); /* XXX BUG! memory leak never freed */
-       if (!bc->send_lock) {
-               return -1;
-       }
-       pthread_mutex_init(&bc->send_lock->lock, NULL);
-
-       empty_bc(bc);
-
-       bc->port=stack->port;
-       bc_state_change(bc, BCHAN_CLEANED);
-       bc->nt=stack->nt?1:0;
-       bc->pri=stack->pri;
-
-       {
-               ibuffer_t* ibuf= init_ibuffer(MISDN_IBUF_SIZE);
-
-               if (!ibuf) return -1;
-
-               clear_ibuffer( ibuf);
-
-               ibuf->rsem=malloc(sizeof(sem_t));
-               if (!ibuf->rsem) {
-                       return -1;
-               }
-
-               bc->astbuf=ibuf;
-
-               if (sem_init(ibuf->rsem,1,0)<0)
-                       sem_init(ibuf->rsem,0,0);
-
-       }
-
-#if 0  /* This code does not seem to do anything useful */
-       if (bidx <= stack->b_num) {
-               unsigned char buff[1025];
-               iframe_t *frm = (iframe_t *) buff;
-               stack_info_t *stinf;
-               int ret;
-
-               ret = mISDN_get_stack_info(midev, stack->port, buff, sizeof(buff));
-               if (ret < 0) {
-                       cb_log(0, port, "%s: Cannot get stack info for this port. (ret=%d)\n", __FUNCTION__, ret);
-                       return -1;
-               }
-
-               stinf = (stack_info_t *)&frm->data.p;
-
-               cb_log(8, port, " --> Child %x\n",stinf->child[bidx]);
-       }
-#endif
-
-       return 0;
-}
-
-
-
-static struct misdn_stack *stack_init(int midev, int port, int ptp)
-{
-       int ret;
-       unsigned char buff[1025];
-       iframe_t *frm = (iframe_t *)buff;
-       stack_info_t *stinf;
-       struct misdn_stack *stack;
-       int i;
-       layer_info_t li;
-
-       stack = calloc(1, sizeof(struct misdn_stack));
-       if (!stack) {
-               return NULL;
-       }
-
-       cb_log(8, port, "Init. Stack.\n");
-
-       stack->port=port;
-       stack->midev=midev;
-       stack->ptp=ptp;
-
-       stack->holding=NULL;
-       stack->pri=0;
-
-       msg_queue_init(&stack->downqueue);
-
-       pthread_mutex_init(&stack->st_lock, NULL);
-
-       /* query port's requirements */
-       ret = mISDN_get_stack_info(midev, port, buff, sizeof(buff));
-       if (ret < 0) {
-               cb_log(0, port, "%s: Cannot get stack info for this port. (ret=%d)\n", __FUNCTION__, ret);
-               free(stack);
-               return(NULL);
-       }
-
-       stinf = (stack_info_t *)&frm->data.p;
-
-       stack->d_stid = stinf->id;
-       stack->b_num = stinf->childcnt;
-
-       for (i=0; i<=stinf->childcnt; i++)
-               stack->b_stids[i] = stinf->child[i];
-
-       switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK) {
-       case ISDN_PID_L0_TE_S0:
-               cb_log(8, port, "TE Stack\n");
-               stack->nt=0;
-               break;
-       case ISDN_PID_L0_NT_S0:
-               cb_log(8, port, "NT Stack\n");
-               stack->nt=1;
-               break;
-       case ISDN_PID_L0_TE_E1:
-               cb_log(8, port, "TE S2M Stack\n");
-               stack->nt=0;
-               stack->pri=1;
-               break;
-       case ISDN_PID_L0_NT_E1:
-               cb_log(8, port, "NT S2M Stack\n");
-               stack->nt=1;
-               stack->pri=1;
-               break;
-       default:
-               cb_log(0, port, "this is a unknown port type 0x%08x\n", stinf->pid.protocol[0]);
-
-       }
-
-       if (!stack->nt) {
-               if (stinf->pid.protocol[2] & ISDN_PID_L2_DF_PTP ) {
-                       stack->ptp = 1;
-               } else {
-                       stack->ptp = 0;
-               }
-       }
-
-       {
-               int ret;
-               int nt=stack->nt;
-
-               memset(&li, 0, sizeof(li));
-               {
-                       int l = sizeof(li.name);
-                       strncpy(li.name,nt?"net l2":"user l4", l);
-                       li.name[l-1] = 0;
-               }
-               li.object_id = -1;
-               li.extentions = 0;
-               li.pid.protocol[nt?2:4] = nt?ISDN_PID_L2_LAPD_NET:ISDN_PID_L4_CAPI20;
-               li.pid.layermask = ISDN_LAYER((nt?2:4));
-               li.st = stack->d_stid;
-
-
-               ret = mISDN_new_layer(midev, &li);
-               if (ret) {
-                       cb_log(0, port, "%s: Cannot add layer %d to this port.\n", __FUNCTION__, nt?2:4);
-                       free(stack);
-                       return(NULL);
-               }
-
-
-               ret = mISDN_register_layer(midev, stack->d_stid, li.id);
-               if (ret)
-               {
-                       cb_log(0,port,"Cannot register layer %d of this port.\n", nt?2:4);
-                       free(stack);
-                       return(NULL);
-               }
-
-               stack->lower_id = mISDN_get_layerid(midev, stack->d_stid, nt?1:3);
-               if (stack->lower_id < 0) {
-                       cb_log(0, port, "%s: Cannot get layer(%d) id of this port.\n", __FUNCTION__, nt?1:3);
-                       free(stack);
-                       return(NULL);
-               }
-
-               stack->upper_id = mISDN_get_layerid(midev, stack->d_stid, nt?2:4);
-               if (stack->upper_id < 0) {
-                       cb_log(0, port, "%s: Cannot get layer(%d) id of this port.\n", __FUNCTION__, nt?2:4);
-                       free(stack);
-                       return(NULL);
-               }
-
-               /* create nst (nt-mode only) */
-               if (nt) {
-
-                       memset(&stack->nst, 0, sizeof(net_stack_t));
-                       memset(&stack->mgr, 0, sizeof(manager_t));
-
-                       stack->mgr.nst = &stack->nst;
-                       stack->nst.manager = &stack->mgr;
-
-                       stack->nst.l3_manager = handle_event_nt;
-                       stack->nst.device = midev;
-                       stack->nst.cardnr = port;
-                       stack->nst.d_stid = stack->d_stid;
-
-                       stack->nst.feature = FEATURE_NET_HOLD;
-                       if (stack->ptp)
-                               stack->nst.feature |= FEATURE_NET_PTP;
-                       if (stack->pri)
-                               stack->nst.feature |= FEATURE_NET_CRLEN2 | FEATURE_NET_EXTCID;
-
-                       stack->nst.l1_id = stack->lower_id; /* never used */
-                       stack->nst.l2_id = stack->upper_id;
-
-                       msg_queue_init(&stack->nst.down_queue);
-                       pthread_mutex_init(&stack->nstlock, NULL);
-
-                       Isdnl2Init(&stack->nst);
-                       Isdnl3Init(&stack->nst);
-
-               }
-
-               stack->l1link=0;
-               stack->l2link=0;
-#if 0
-               if (!stack->nt) {
-                       misdn_lib_get_short_status(stack);
-               } else {
-                       misdn_lib_get_l1_up(stack);
-                       if (!stack->ptp) misdn_lib_get_l1_up(stack);
-                       misdn_lib_get_l2_up(stack);
-               }
-#endif
-
-               misdn_lib_get_short_status(stack);
-               misdn_lib_get_l1_up(stack);
-               /* handle_l1 will start L2 for NT. */
-               if (!stack->nt) {
-                       misdn_lib_get_l2_up(stack);
-               }
-       }
-
-       cb_log(8, port, "stack_init: lowerId:%x upperId:%x\n", stack->lower_id, stack->upper_id);
-
-       return stack;
-}
-
-
-static void stack_destroy(struct misdn_stack *stack)
-{
-       char buf[1024];
-       if (!stack) return;
-
-       if (stack->nt) {
-               pthread_mutex_destroy(&stack->nstlock);
-               cleanup_Isdnl2(&stack->nst);
-               cleanup_Isdnl3(&stack->nst);
-       }
-
-       if (stack->upper_id)
-               mISDN_write_frame(stack->midev, buf, stack->upper_id, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
-
-       pthread_mutex_destroy(&stack->st_lock);
-}
-
-
-static struct misdn_stack * find_stack_by_addr(int  addr)
-{
-       struct misdn_stack *stack;
-
-       for (stack = glob_mgr->stack_list; stack; stack = stack->next) {
-               if ((stack->upper_id & STACK_ID_MASK) == (addr & STACK_ID_MASK)) {
-                       /* Found the stack */
-                       break;
-               }
-       }
-
-       return stack;
-}
-
-
-static struct misdn_stack *find_stack_by_port(int port)
-{
-       struct misdn_stack *stack;
-
-       for (stack = glob_mgr->stack_list; stack; stack = stack->next) {
-               if (stack->port == port) {
-                       /* Found the stack */
-                       break;
-               }
-       }
-
-       return stack;
-}
-
-static struct misdn_stack *find_stack_by_mgr(manager_t *mgr_nt)
-{
-       struct misdn_stack *stack;
-
-       for (stack = glob_mgr->stack_list; stack; stack = stack->next) {
-               if (&stack->mgr == mgr_nt) {
-                       /* Found the stack */
-                       break;
-               }
-       }
-
-       return stack;
-}
-
-static struct misdn_bchannel *find_bc_by_masked_l3id(struct misdn_stack *stack, unsigned long l3id, unsigned long mask)
-{
-       int i;
-
-       for (i = 0; i <= stack->b_num; ++i) {
-               if (stack->bc[i].in_use && (stack->bc[i].l3_id & mask) == (l3id & mask)) {
-                       return &stack->bc[i];
-               }
-       }
-#if defined(AST_MISDN_ENHANCEMENTS)
-       /* Search the B channel records for a REGISTER signaling link. */
-       for (i = MAX_BCHANS + 1; i < ARRAY_LEN(stack->bc); ++i) {
-               if (stack->bc[i].in_use && (stack->bc[i].l3_id & mask) == (l3id & mask)) {
-                       return &stack->bc[i];
-               }
-       }
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-       return stack_holder_find(stack, l3id);
-}
-
-
-struct misdn_bchannel *find_bc_by_l3id(struct misdn_stack *stack, unsigned long l3id)
-{
-       int i;
-
-       for (i = 0; i <= stack->b_num; ++i) {
-               if (stack->bc[i].in_use && stack->bc[i].l3_id == l3id) {
-                       return &stack->bc[i];
-               }
-       }
-#if defined(AST_MISDN_ENHANCEMENTS)
-       /* Search the B channel records for a REGISTER signaling link. */
-       for (i = MAX_BCHANS + 1; i < ARRAY_LEN(stack->bc); ++i) {
-               if (stack->bc[i].in_use && stack->bc[i].l3_id == l3id) {
-                       return &stack->bc[i];
-               }
-       }
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-       return stack_holder_find(stack, l3id);
-}
-
-static struct misdn_bchannel *find_bc_by_addr(unsigned long addr)
-{
-       struct misdn_stack *stack;
-       int i;
-
-       for (stack = glob_mgr->stack_list; stack; stack = stack->next) {
-               for (i = 0; i <= stack->b_num; i++) {
-                       if (stack->bc[i].in_use
-                               && ((stack->bc[i].addr & STACK_ID_MASK) == (addr & STACK_ID_MASK)
-                                       || stack->bc[i].layer_id == addr)) {
-                               return &stack->bc[i];
-                       }
-               }
-       }
-
-       return NULL;
-}
-
-static struct misdn_bchannel *find_bc_by_confid(unsigned long confid)
-{
-       struct misdn_stack *stack;
-       int i;
-
-       for (stack = glob_mgr->stack_list; stack; stack = stack->next) {
-               for (i = 0; i <= stack->b_num; i++) {
-                       if (stack->bc[i].in_use && stack->bc[i].conf_id == confid) {
-                               return &stack->bc[i];
-                       }
-               }
-       }
-       return NULL;
-}
-
-
-static int handle_event_te(struct misdn_bchannel *bc, enum event_e event, iframe_t *frm)
-{
-       struct misdn_stack *stack=get_stack_by_bc(bc);
-
-       switch (event) {
-               case EVENT_CONNECT_ACKNOWLEDGE:
-                       setup_bc(bc);
-
-                       if ( *bc->crypt_key ) {
-                               cb_log(4, stack->port,
-                                       "ENABLING BLOWFISH channel:%d caller%d:\"%s\" <%s> dialed%d:%s\n",
-                                       bc->channel,
-                                       bc->caller.number_type,
-                                       bc->caller.name,
-                                       bc->caller.number,
-                                       bc->dialed.number_type,
-                                       bc->dialed.number);
-                               manager_ph_control_block(bc,  BF_ENABLE_KEY, bc->crypt_key, strlen(bc->crypt_key) );
-                       }
-
-                       if (misdn_cap_is_speech(bc->capability)) {
-                               if (  !bc->nodsp) manager_ph_control(bc,  DTMF_TONE_START, 0);
-                               manager_ec_enable(bc);
-
-                               if ( bc->txgain != 0 ) {
-                                       cb_log(4, stack->port, "--> Changing txgain to %d\n", bc->txgain);
-                                       manager_ph_control(bc, VOL_CHANGE_TX, bc->txgain);
-                               }
-                               if ( bc->rxgain != 0 ) {
-                                       cb_log(4, stack->port, "--> Changing rxgain to %d\n", bc->rxgain);
-                                       manager_ph_control(bc, VOL_CHANGE_RX, bc->rxgain);
-                               }
-                       }
-
-                       break;
-               case EVENT_CONNECT:
-
-                       if ( *bc->crypt_key ) {
-                               cb_log(4, stack->port,
-                                       "ENABLING BLOWFISH channel:%d caller%d:\"%s\" <%s> dialed%d:%s\n",
-                                       bc->channel,
-                                       bc->caller.number_type,
-                                       bc->caller.name,
-                                       bc->caller.number,
-                                       bc->dialed.number_type,
-                                       bc->dialed.number);
-                               manager_ph_control_block(bc,  BF_ENABLE_KEY, bc->crypt_key, strlen(bc->crypt_key) );
-                       }
-               case EVENT_ALERTING:
-               case EVENT_PROGRESS:
-               case EVENT_PROCEEDING:
-               case EVENT_SETUP_ACKNOWLEDGE:
-               case EVENT_SETUP:
-               {
-                       if (bc->channel == 0xff || bc->channel<=0)
-                               bc->channel=0;
-
-                       if (find_free_chan_in_stack(stack, bc, bc->channel, 0)<0){
-                               if (!stack->pri && !stack->ptp)  {
-                                       bc->cw=1;
-                                       break;
-                               }
-
-                               if (!bc->channel) {
-                                       cb_log(0, stack->port, "Any Channel Requested, but we have no more!!\n");
-                               } else {
-                                       cb_log(0, stack->port,
-                                               "Requested Channel Already in Use releasing this call with cause %d!!!!\n",
-                                               bc->out_cause);
-                               }
-
-                               /* when the channel is already in use, we can't
-                                * simply clear it, we need to make sure that
-                                * it will still be marked as in_use in the
-                                * available channels list.*/
-                               bc->channel=0;
-
-                               misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE);
-                               return -1;
-                       }
-
-                       if (event != EVENT_SETUP) {
-                               setup_bc(bc);
-                       }
-                       break;
-               }
-
-               case EVENT_RELEASE_COMPLETE:
-               case EVENT_RELEASE:
-                       break;
-               default:
-                       break;
-       }
-       return 0;
-}
-
-static int handle_cr ( struct misdn_stack *stack, iframe_t *frm)
-{
-       struct misdn_bchannel dummybc;
-       struct misdn_bchannel *bc;
-       int channel;
-
-       if (!stack) return -1;
-
-       switch (frm->prim) {
-       case CC_NEW_CR|INDICATION:
-               cb_log(7, stack->port, " --> lib: NEW_CR Ind with l3id:%x on this port.\n",frm->dinfo);
-
-               bc = misdn_lib_get_free_bc(stack->port, 0, 1, 0);
-               if (!bc) {
-                       cb_log(0, stack->port, " --> !! lib: No free channel!\n");
-                       return -1;
-               }
-
-               cb_log(7, stack->port, " --> new_process: New L3Id: %x\n",frm->dinfo);
-               bc->l3_id=frm->dinfo;
-               return 1;
-       case CC_NEW_CR|CONFIRM:
-               return 1;
-       case CC_NEW_CR|REQUEST:
-               return 1;
-       case CC_RELEASE_CR|REQUEST:
-               return 1;
-       case CC_RELEASE_CR|CONFIRM:
-               break;
-       case CC_RELEASE_CR|INDICATION:
-               cb_log(4, stack->port, " --> lib: RELEASE_CR Ind with l3id:%x\n", frm->dinfo);
-               bc = find_bc_by_l3id(stack, frm->dinfo);
-               if (!bc) {
-                       cb_log(4, stack->port, " --> Didn't find BC so temporarily creating dummy BC (l3id:%x) on this port.\n", frm->dinfo);
-                       misdn_make_dummy(&dummybc, stack->port, frm->dinfo, stack->nt, 0);
-                       bc = &dummybc;
-               }
-
-               channel = bc->channel;
-               cb_log(4, stack->port, " --> lib: CLEANING UP l3id: %x\n", frm->dinfo);
-
-               /* bc->pid = 0; */
-               bc->need_disconnect = 0;
-               bc->need_release = 0;
-               bc->need_release_complete = 0;
-
-               cb_event(EVENT_CLEANUP, bc, glob_mgr->user_data);
-
-               empty_bc(bc);
-               clean_up_bc(bc);
-
-               if (channel > 0)
-                       empty_chan_in_stack(stack, channel);
-               bc->in_use = 0;
-
-               dump_chan_list(stack);
-
-               if (bc->stack_holder) {
-                       cb_log(4, stack->port, "REMOVING Holder\n");
-                       stack_holder_remove(stack, bc);
-                       free(bc);
-               }
-
-               return 1;
-       default:
-               break;
-       }
-
-       return 0;
-}
-
-
-/* Empties bc if it's reserved (no SETUP out yet) */
-void misdn_lib_release(struct misdn_bchannel *bc)
-{
-       int channel;
-       struct misdn_stack *stack=get_stack_by_bc(bc);
-
-       if (!stack) {
-               cb_log(1,0,"misdn_release: No Stack found\n");
-               return;
-       }
-
-       channel = bc->channel;
-       empty_bc(bc);
-       clean_up_bc(bc);
-       if (channel > 0) {
-               empty_chan_in_stack(stack, channel);
-       }
-       bc->in_use=0;
-}
-
-
-
-
-int misdn_lib_get_port_up (int port)
-{ /* Pull Up L1 */
-       struct misdn_stack *stack;
-
-       for (stack=glob_mgr->stack_list;
-            stack;
-            stack=stack->next) {
-
-               if (stack->port == port) {
-
-                       if (!stack->l1link)
-                               misdn_lib_get_l1_up(stack);
-                       /* handle_l1 will start L2 for NT. */
-                       if (!stack->l2link && !stack->nt) {
-                               misdn_lib_get_l2_up(stack);
-                       }
-
-                       return 0;
-               }
-       }
-       return 0;
-}
-
-
-int misdn_lib_get_port_down (int port)
-{ /* Pull Down L1 */
-       struct misdn_stack *stack;
-       for (stack=glob_mgr->stack_list;
-            stack;
-            stack=stack->next) {
-               if (stack->port == port) {
-                               if (stack->l2link)
-                                       misdn_lib_get_l2_down(stack);
-                               misdn_lib_get_l1_down(stack);
-                       return 0;
-               }
-       }
-       return 0;
-}
-
-int misdn_lib_port_up(int port, int check)
-{
-       struct misdn_stack *stack;
-
-
-       for (stack=glob_mgr->stack_list;
-            stack;
-            stack=stack->next) {
-
-               if (stack->port == port) {
-
-                       if (stack->blocked) {
-                               cb_log(0,port, "Port Blocked:%d L2:%d L1:%d\n", stack->blocked, stack->l2link, stack->l1link);
-                               return -1;
-                       }
-
-                       if (stack->ptp ) {
-
-                               if (stack->l1link && stack->l2link) {
-                                       return 1;
-                               } else {
-                                       cb_log(1,port, "Port Down L2:%d L1:%d\n",
-                                               stack->l2link, stack->l1link);
-                                       return 0;
-                               }
-                       } else {
-                               if ( !check || stack->l1link )
-                                       return 1;
-                               else {
-                                       cb_log(1,port, "Port down PMP\n");
-                                       return 0;
-                               }
-                       }
-               }
-       }
-
-       return -1;
-}
-
-
-static int release_cr(struct misdn_stack *stack, mISDNuser_head_t *hh)
-{
-       struct misdn_bchannel *bc=find_bc_by_l3id(stack, hh->dinfo);
-       struct misdn_bchannel dummybc;
-       iframe_t frm; /* fake te frm to remove callref from global callreflist */
-
-       frm.dinfo = hh->dinfo;
-       frm.addr=stack->upper_id | FLG_MSG_DOWN;
-       frm.prim = CC_RELEASE_CR|INDICATION;
-       cb_log(4, stack->port, " --> CC_RELEASE_CR: Faking Release_cr for %x l3id:%x\n",frm.addr, frm.dinfo);
-
-       /** removing procid **/
-       if (!bc) {
-               cb_log(4, stack->port, " --> Didn't find BC so temporarily creating dummy BC (l3id:%x) on this port.\n", hh->dinfo);
-               misdn_make_dummy(&dummybc, stack->port, hh->dinfo, stack->nt, 0);
-               bc=&dummybc;
-       }
-
-       if ((bc->l3_id & 0xff00) == 0xff00) {
-               cb_log(4, stack->port, " --> Removing Process Id:%x on this port.\n", bc->l3_id & 0xff);
-               stack->procids[bc->l3_id & 0xff] = 0;
-       }
-
-       if (handle_cr(stack, &frm)<0) {
-       }
-
-       return 0 ;
-}
-
-static int handle_event_nt(void *dat, void *arg)
-{
-       struct misdn_bchannel dummybc;
-       struct misdn_bchannel *bc;
-       manager_t *mgr = (manager_t *)dat;
-       msg_t *msg = (msg_t *)arg;
-       msg_t *dmsg;
-       mISDNuser_head_t *hh;
-       struct misdn_stack *stack;
-       enum event_e event;
-       int reject=0;
-       int l3id;
-       int channel;
-       int tmpcause;
-
-       if (!msg || !mgr)
-               return(-EINVAL);
-
-       stack = find_stack_by_mgr(mgr);
-       hh=(mISDNuser_head_t*)msg->data;
-
-       /*
-        * When we are called from the mISDNuser lib, the nstlock is held and it
-        * must be held when we return.  We unlock here because the lib may be
-        * entered again recursively.
-        */
-       pthread_mutex_unlock(&stack->nstlock);
-
-       cb_log(5, stack->port, " --> lib: prim %x dinfo %x\n",hh->prim, hh->dinfo);
-       switch(hh->prim) {
-       case CC_RETRIEVE|INDICATION:
-       {
-               struct misdn_bchannel *hold_bc;
-               iframe_t frm; /* fake te frm to add callref to global callreflist */
-
-               frm.dinfo = hh->dinfo;
-               frm.addr=stack->upper_id | FLG_MSG_DOWN;
-               frm.prim = CC_NEW_CR|INDICATION;
-               if (handle_cr( stack, &frm)< 0) {
-                       goto ERR_NO_CHANNEL;
-               }
-
-               bc = find_bc_by_l3id(stack, hh->dinfo);
-               hold_bc = stack_holder_find(stack, bc->l3_id);
-               cb_log(4, stack->port, "bc_l3id:%x holded_bc_l3id:%x\n",bc->l3_id, hold_bc->l3_id);
-
-               if (hold_bc) {
-                       cb_log(4, stack->port, "REMOVING Holder\n");
-
-                       /* swap the backup to our new channel back */
-                       stack_holder_remove(stack, hold_bc);
-                       memcpy(bc, hold_bc, sizeof(*bc));
-                       free(hold_bc);
-
-                       bc->holded=0;
-                       bc->b_stid=0;
-               }
-               break;
-       }
-
-       case CC_SETUP | CONFIRM:
-               l3id = *((int *) (msg->data + mISDNUSER_HEAD_SIZE));
-
-               cb_log(4, stack->port, " --> lib: Event_ind:SETUP CONFIRM [NT] : new L3ID is %x\n", l3id);
-
-               bc = find_bc_by_l3id(stack, hh->dinfo);
-               if (bc) {
-                       cb_log (2, bc->port, "I IND :CC_SETUP|CONFIRM: old l3id:%x new l3id:%x\n", bc->l3_id, l3id);
-                       bc->l3_id = l3id;
-                       cb_event(EVENT_NEW_L3ID, bc, glob_mgr->user_data);
-               } else {
-                       cb_log(4, stack->port, "Bc Not found (after SETUP CONFIRM)\n");
-               }
-               free_msg(msg);
-               pthread_mutex_lock(&stack->nstlock);
-               return 0;
-
-       case CC_SETUP | INDICATION:
-               bc = misdn_lib_get_free_bc(stack->port, 0, 1, 0);
-               if (!bc) {
-                       goto ERR_NO_CHANNEL;
-               }
-
-               cb_log(4, stack->port, " --> new_process: New L3Id: %x\n",hh->dinfo);
-               bc->l3_id=hh->dinfo;
-               break;
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-       case CC_REGISTER | CONFIRM:
-               l3id = *((int *) (msg->data + mISDNUSER_HEAD_SIZE));
-
-               cb_log(4, stack->port, " --> lib: Event_ind:REGISTER CONFIRM [NT] : new L3ID is %x\n", l3id);
-
-               bc = find_bc_by_l3id(stack, hh->dinfo);
-               if (bc) {
-                       cb_log (2, bc->port, "I IND :CC_REGISTER|CONFIRM: old l3id:%x new l3id:%x\n", bc->l3_id, l3id);
-                       bc->l3_id = l3id;
-               } else {
-                       cb_log(4, stack->port, "Bc Not found (after REGISTER CONFIRM)\n");
-               }
-               free_msg(msg);
-               pthread_mutex_lock(&stack->nstlock);
-               return 0;
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-       case CC_REGISTER | INDICATION:
-               bc = misdn_lib_get_register_bc(stack->port);
-               if (!bc) {
-                       goto ERR_NO_CHANNEL;
-               }
-
-               cb_log(4, stack->port, " --> new_process: New L3Id: %x\n",hh->dinfo);
-               bc->l3_id=hh->dinfo;
-               break;
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-       case CC_CONNECT_ACKNOWLEDGE|INDICATION:
-               break;
-
-       case CC_ALERTING|INDICATION:
-       case CC_PROCEEDING|INDICATION:
-       case CC_SETUP_ACKNOWLEDGE|INDICATION:
-       case CC_CONNECT|INDICATION:
-               break;
-       case CC_DISCONNECT|INDICATION:
-               bc = find_bc_by_l3id(stack, hh->dinfo);
-               if (!bc) {
-                       bc=find_bc_by_masked_l3id(stack, hh->dinfo, 0xffff0000);
-                       if (bc) {
-                               int myprocid=bc->l3_id&0x0000ffff;
-
-                               hh->dinfo=(hh->dinfo&0xffff0000)|myprocid;
-                               cb_log(3,stack->port,"Reject dinfo: %x cause:%d\n",hh->dinfo,bc->cause);
-                               reject=1;
-                       }
-               }
-               break;
-
-       case CC_FACILITY|INDICATION:
-               bc = find_bc_by_l3id(stack, hh->dinfo);
-               if (!bc) {
-                       bc=find_bc_by_masked_l3id(stack, hh->dinfo, 0xffff0000);
-                       if (bc) {
-                               int myprocid=bc->l3_id&0x0000ffff;
-
-                               hh->dinfo=(hh->dinfo&0xffff0000)|myprocid;
-                               cb_log(4,bc->port,"Repaired reject Bug, new dinfo: %x\n",hh->dinfo);
-                       }
-               }
-               break;
-
-       case CC_RELEASE_COMPLETE|INDICATION:
-               break;
-
-       case CC_SUSPEND|INDICATION:
-               cb_log(4, stack->port, " --> Got Suspend, sending Reject for now\n");
-               dmsg = create_l3msg(CC_SUSPEND_REJECT | REQUEST,MT_SUSPEND_REJECT, hh->dinfo,sizeof(RELEASE_COMPLETE_t), 1);
-               pthread_mutex_lock(&stack->nstlock);
-               stack->nst.manager_l3(&stack->nst, dmsg);
-               free_msg(msg);
-               return 0;
-
-       case CC_RESUME|INDICATION:
-               break;
-
-       case CC_RELEASE|CONFIRM:
-               bc = find_bc_by_l3id(stack, hh->dinfo);
-               if (bc) {
-                       cb_log(1, stack->port, "CC_RELEASE|CONFIRM (l3id:%x), sending RELEASE_COMPLETE\n", hh->dinfo);
-                       misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE);
-               }
-               break;
-
-       case CC_RELEASE|INDICATION:
-               break;
-
-       case CC_RELEASE_CR|INDICATION:
-               release_cr(stack, hh);
-               free_msg(msg);
-               pthread_mutex_lock(&stack->nstlock);
-               return 0;
-
-       case CC_NEW_CR|INDICATION:
-               /*  Got New CR for bchan, for now I handle this one in */
-               /*  connect_ack, Need to be changed */
-               l3id = *((int *) (msg->data + mISDNUSER_HEAD_SIZE));
-
-               bc = find_bc_by_l3id(stack, hh->dinfo);
-               if (!bc) {
-                       cb_log(0, stack->port, " --> In NEW_CR: didn't found bc ??\n");
-                       pthread_mutex_lock(&stack->nstlock);
-                       return -1;
-               }
-               if (((l3id&0xff00)!=0xff00) && ((bc->l3_id&0xff00)==0xff00)) {
-                       cb_log(4, stack->port, " --> Removing Process Id:%x on this port.\n", 0xff&bc->l3_id);
-                       stack->procids[bc->l3_id&0xff] = 0 ;
-               }
-               cb_log(4, stack->port, "lib: Event_ind:CC_NEW_CR : very new L3ID  is %x\n",l3id );
-
-               bc->l3_id =l3id;
-               if (!bc->is_register_pool) {
-                       cb_event(EVENT_NEW_L3ID, bc, glob_mgr->user_data);
-               }
-
-               free_msg(msg);
-               pthread_mutex_lock(&stack->nstlock);
-               return 0;
-
-       case DL_ESTABLISH | INDICATION:
-       case DL_ESTABLISH | CONFIRM:
-               cb_log(3, stack->port, "%% GOT L2 Activate Info.\n");
-
-               if (stack->ptp && stack->l2link) {
-                       cb_log(0, stack->port, "%% GOT L2 Activate Info. but we're activated already.. this l2 is faulty, blocking port\n");
-                       cb_event(EVENT_PORT_ALARM, &stack->bc[0], glob_mgr->user_data);
-               }
-
-               if (stack->ptp && !stack->restart_sent) {
-                       /* make sure we restart the interface of the
-                        * other side */
-                       stack->restart_sent=1;
-                       misdn_lib_send_restart(stack->port, -1);
-
-               }
-
-               /* when we get the L2 UP, the L1 is UP definitely too*/
-               stack->l2link = 1;
-               stack->l2upcnt=0;
-
-               free_msg(msg);
-               pthread_mutex_lock(&stack->nstlock);
-               return 0;
-
-       case DL_RELEASE | INDICATION:
-       case DL_RELEASE | CONFIRM:
-               cb_log(3, stack->port, "%% GOT L2 DeActivate Info.\n");
-               if (stack->ptp) {
-
-                       if (stack->l2upcnt>3) {
-                               cb_log(0 , stack->port, "!!! Could not Get the L2 up after 3 Attempts!!!\n");
-                       } else {
-                               if (stack->l1link) {
-                                       misdn_lib_get_l2_up(stack);
-                                       stack->l2upcnt++;
-                               }
-                       }
-               }
-
-               stack->l2link = 0;
-               free_msg(msg);
-               pthread_mutex_lock(&stack->nstlock);
-               return 0;
-
-       default:
-               break;
-       }
-
-       /*  Parse Events and fire_up to App. */
-       event = isdn_msg_get_event(msgs_g, msg, 1);
-
-       bc = find_bc_by_l3id(stack, hh->dinfo);
-       if (!bc) {
-               cb_log(4, stack->port, " --> Didn't find BC so temporarily creating dummy BC (l3id:%x).\n", hh->dinfo);
-               misdn_make_dummy(&dummybc, stack->port,  hh->dinfo, stack->nt, 0);
-               bc = &dummybc;
-       }
-
-       isdn_msg_parse_event(msgs_g, msg, bc, 1);
-
-       switch (event) {
-       case EVENT_SETUP:
-               if (bc->channel <= 0 || bc->channel == 0xff) {
-                       bc->channel = 0;
-               }
-
-               if (find_free_chan_in_stack(stack, bc, bc->channel, 0) < 0) {
-                       goto ERR_NO_CHANNEL;
-               }
-               break;
-       case EVENT_RELEASE:
-       case EVENT_RELEASE_COMPLETE:
-               channel = bc->channel;
-               tmpcause = bc->cause;
-
-               empty_bc(bc);
-               bc->cause = tmpcause;
-               clean_up_bc(bc);
-
-               if (channel > 0)
-                       empty_chan_in_stack(stack, channel);
-               bc->in_use = 0;
-               break;
-       default:
-               break;
-       }
-
-       if(!isdn_get_info(msgs_g, event, 1)) {
-               cb_log(4, stack->port, "Unknown Event Ind: prim %x dinfo %x\n", hh->prim, hh->dinfo);
-       } else {
-               if (reject) {
-                       switch(bc->cause) {
-                       case AST_CAUSE_USER_BUSY:
-                               cb_log(1, stack->port, "Siemens Busy reject..\n");
-                               break;
-                       default:
-                               break;
-                       }
-               }
-               cb_event(event, bc, glob_mgr->user_data);
-       }
-
-       free_msg(msg);
-       pthread_mutex_lock(&stack->nstlock);
-       return 0;
-
-ERR_NO_CHANNEL:
-       cb_log(4, stack->port, "Patch from MEIDANIS:Sending RELEASE_COMPLETE %x (No free Chan for you..)\n", hh->dinfo);
-       dmsg = create_l3msg(CC_RELEASE_COMPLETE | REQUEST, MT_RELEASE_COMPLETE, hh->dinfo, sizeof(RELEASE_COMPLETE_t), 1);
-       pthread_mutex_lock(&stack->nstlock);
-       stack->nst.manager_l3(&stack->nst, dmsg);
-       free_msg(msg);
-       return 0;
-}
-
-
-static int handle_timers(msg_t* msg)
-{
-       iframe_t *frm= (iframe_t*)msg->data;
-       struct misdn_stack *stack;
-
-       /* Timer Stuff */
-       switch (frm->prim) {
-       case MGR_INITTIMER | CONFIRM:
-       case MGR_ADDTIMER | CONFIRM:
-       case MGR_DELTIMER | CONFIRM:
-       case MGR_REMOVETIMER | CONFIRM:
-               free_msg(msg);
-               return(1);
-       }
-
-
-
-       if (frm->prim==(MGR_TIMER | INDICATION) ) {
-               for (stack = glob_mgr->stack_list;
-                    stack;
-                    stack = stack->next) {
-                       itimer_t *it;
-
-                       if (!stack->nt) continue;
-
-                       it = stack->nst.tlist;
-                       /* find timer */
-                       for(it=stack->nst.tlist;
-                           it;
-                           it=it->next) {
-                               if (it->id == (int)frm->addr)
-                                       break;
-                       }
-                       if (it) {
-                               mISDN_write_frame(stack->midev, msg->data, frm->addr,
-                                                 MGR_TIMER | RESPONSE, 0, 0, NULL, TIMEOUT_1SEC);
-                               test_and_clear_bit(FLG_TIMER_RUNING, (long unsigned int *)&it->Flags);
-                               pthread_mutex_lock(&stack->nstlock);
-                               it->function(it->data);
-                               pthread_mutex_unlock(&stack->nstlock);
-                               free_msg(msg);
-                               return 1;
-                       }
-               }
-
-               cb_log(0, 0, "Timer Msg without Timer ??\n");
-               free_msg(msg);
-               return 1;
-       }
-
-       return 0;
-}
-
-
-
-void misdn_lib_tone_generator_start(struct misdn_bchannel *bc)
-{
-       bc->generate_tone=1;
-}
-
-void misdn_lib_tone_generator_stop(struct misdn_bchannel *bc)
-{
-       bc->generate_tone=0;
-}
-
-
-static int do_tone(struct misdn_bchannel *bc, int len)
-{
-       bc->tone_cnt=len;
-
-       if (bc->generate_tone) {
-               cb_event(EVENT_TONE_GENERATE, bc, glob_mgr->user_data);
-
-               if ( !bc->nojitter ) {
-                       misdn_tx_jitter(bc,len);
-               }
-
-               return 1;
-       }
-
-       return 0;
-}
-
-
-#ifdef MISDN_SAVE_DATA
-static void misdn_save_data(int id, char *p1, int l1, char *p2, int l2)
-{
-       char n1[32],n2[32];
-       FILE *rx, *tx;
-
-       sprintf(n1,"/tmp/misdn-rx-%d.raw",id);
-       sprintf(n2,"/tmp/misdn-tx-%d.raw",id);
-
-       rx = fopen(n1,"a+");
-       tx = fopen(n2,"a+");
-
-       if (!rx || !tx) {
-               cb_log(0,0,"Couldn't open files: %s\n",strerror(errno));
-               if (rx)
-                       fclose(rx);
-               if (tx)
-                       fclose(tx);
-               return ;
-       }
-
-       fwrite(p1,1,l1,rx);
-       fwrite(p2,1,l2,tx);
-
-       fclose(rx);
-       fclose(tx);
-
-}
-#endif
-
-void misdn_tx_jitter(struct misdn_bchannel *bc, int len)
-{
-       char buf[4096 + mISDN_HEADER_LEN];
-       char *data=&buf[mISDN_HEADER_LEN];
-       iframe_t *txfrm= (iframe_t*)buf;
-       int jlen, r;
-
-       jlen=cb_jb_empty(bc,data,len);
-
-       if (jlen) {
-#ifdef MISDN_SAVE_DATA
-               misdn_save_data((bc->port*100+bc->channel), data, jlen, bc->bframe, bc->bframe_len);
-#endif
-               flip_buf_bits( data, jlen);
-
-               if (jlen < len) {
-                       cb_log(1, bc->port, "Jitterbuffer Underrun. Got %d of expected %d\n", jlen, len);
-               }
-
-               txfrm->prim = DL_DATA|REQUEST;
-
-               txfrm->dinfo = 0;
-
-               txfrm->addr = bc->addr|FLG_MSG_DOWN; /*  | IF_DOWN; */
-
-               txfrm->len =jlen;
-               cb_log(9, bc->port, "Transmitting %d samples 2 misdn\n", txfrm->len);
-
-               r=mISDN_write( glob_mgr->midev, buf, txfrm->len + mISDN_HEADER_LEN, 8000 );
-       } else {
-#define MISDN_GEN_SILENCE
-#ifdef MISDN_GEN_SILENCE
-               int cnt=len/TONE_SILENCE_SIZE;
-               int rest=len%TONE_SILENCE_SIZE;
-               int i;
-
-               for (i=0; i<cnt; i++) {
-                       memcpy(data, tone_silence_flip, TONE_SILENCE_SIZE );
-                       data +=TONE_SILENCE_SIZE;
-               }
-
-               if (rest) {
-                       memcpy(data, tone_silence_flip, rest);
-               }
-
-               txfrm->prim = DL_DATA|REQUEST;
-
-               txfrm->dinfo = 0;
-
-               txfrm->addr = bc->addr|FLG_MSG_DOWN; /*  | IF_DOWN; */
-
-               txfrm->len =len;
-               cb_log(5, bc->port, "Transmitting %d samples of silence to misdn\n", len);
-
-               r=mISDN_write( glob_mgr->midev, buf, txfrm->len + mISDN_HEADER_LEN, 8000 );
-#else
-               r = 0;
-#endif
-       }
-
-       if (r < 0) {
-               cb_log(1, bc->port, "Error in mISDN_write (%s)\n", strerror(errno));
-       }
-}
-
-static int handle_bchan(msg_t *msg)
-{
-       iframe_t *frm= (iframe_t*)msg->data;
-       struct misdn_bchannel *bc=find_bc_by_addr(frm->addr);
-       struct misdn_stack *stack;
-
-       if (!bc) {
-               cb_log(1,0,"handle_bchan: BC not found for prim:%x with addr:%x dinfo:%x\n", frm->prim, frm->addr, frm->dinfo);
-               return 0 ;
-       }
-
-       stack = get_stack_by_bc(bc);
-
-       if (!stack) {
-               cb_log(0, bc->port,"handle_bchan: STACK not found for prim:%x with addr:%x dinfo:%x\n", frm->prim, frm->addr, frm->dinfo);
-               return 0;
-       }
-
-       switch (frm->prim) {
-
-       case MGR_SETSTACK| CONFIRM:
-               cb_log(3, stack->port, "BCHAN: MGR_SETSTACK|CONFIRM pid:%d\n",bc->pid);
-               break;
-
-       case MGR_SETSTACK| INDICATION:
-               cb_log(3, stack->port, "BCHAN: MGR_SETSTACK|IND pid:%d\n",bc->pid);
-       break;
-
-       case MGR_DELLAYER| INDICATION:
-               cb_log(3, stack->port, "BCHAN: MGR_DELLAYER|IND pid:%d\n",bc->pid);
-               break;
-
-       case MGR_DELLAYER| CONFIRM:
-               cb_log(3, stack->port, "BCHAN: MGR_DELLAYER|CNF pid:%d\n",bc->pid);
-
-               bc->pid=0;
-               bc->addr=0;
-
-               free_msg(msg);
-               return 1;
-
-       case PH_ACTIVATE | INDICATION:
-       case DL_ESTABLISH | INDICATION:
-               cb_log(3, stack->port, "BCHAN: ACT Ind pid:%d\n", bc->pid);
-
-               free_msg(msg);
-               return 1;
-
-       case PH_ACTIVATE | CONFIRM:
-       case DL_ESTABLISH | CONFIRM:
-
-               cb_log(3, stack->port, "BCHAN: bchan ACT Confirm pid:%d\n",bc->pid);
-               free_msg(msg);
-
-               return 1;
-
-       case DL_ESTABLISH | REQUEST:
-               {
-                       char buf[128];
-                       mISDN_write_frame(stack->midev, buf, bc->addr | FLG_MSG_TARGET | FLG_MSG_DOWN,  DL_ESTABLISH | CONFIRM, 0,0, NULL, TIMEOUT_1SEC);
-               }
-               free_msg(msg);
-               return 1;
-
-       case DL_RELEASE|REQUEST:
-               {
-                       char buf[128];
-                       mISDN_write_frame(stack->midev, buf, bc->addr | FLG_MSG_TARGET | FLG_MSG_DOWN,  DL_RELEASE| CONFIRM, 0,0, NULL, TIMEOUT_1SEC);
-               }
-               free_msg(msg);
-               return 1;
-
-       case PH_DEACTIVATE | INDICATION:
-       case DL_RELEASE | INDICATION:
-               cb_log (3, stack->port, "BCHAN: DeACT Ind pid:%d\n",bc->pid);
-
-               free_msg(msg);
-               return 1;
-
-       case PH_DEACTIVATE | CONFIRM:
-       case DL_RELEASE | CONFIRM:
-               cb_log(3, stack->port, "BCHAN: DeACT Conf pid:%d\n",bc->pid);
-
-               free_msg(msg);
-               return 1;
-
-       case PH_CONTROL|INDICATION:
-       {
-               unsigned int *cont = (unsigned int *) &frm->data.p;
-
-               cb_log(4, stack->port,
-                       "PH_CONTROL: channel:%d caller%d:\"%s\" <%s> dialed%d:%s \n",
-                       bc->channel,
-                       bc->caller.number_type,
-                       bc->caller.name,
-                       bc->caller.number,
-                       bc->dialed.number_type,
-                       bc->dialed.number);
-
-               if ((*cont & ~DTMF_TONE_MASK) == DTMF_TONE_VAL) {
-                       int dtmf = *cont & DTMF_TONE_MASK;
-                       cb_log(4, stack->port, " --> DTMF TONE: %c\n",dtmf);
-                       bc->dtmf=dtmf;
-                       cb_event(EVENT_DTMF_TONE, bc, glob_mgr->user_data);
-
-                       free_msg(msg);
-                       return 1;
-               }
-               if (*cont == BF_REJECT) {
-                       cb_log(4, stack->port, " --> BF REJECT\n");
-                       free_msg(msg);
-                       return 1;
-               }
-               if (*cont == BF_ACCEPT) {
-                       cb_log(4, stack->port, " --> BF ACCEPT\n");
-                       free_msg(msg);
-                       return 1;
-               }
-       }
-       break;
-
-       case PH_DATA|REQUEST:
-       case DL_DATA|REQUEST:
-               cb_log(0, stack->port, "DL_DATA REQUEST \n");
-               do_tone(bc, 64);
-
-               free_msg(msg);
-               return 1;
-
-
-       case PH_DATA|INDICATION:
-       case DL_DATA|INDICATION:
-       {
-               bc->bframe = (void*)&frm->data.i;
-               bc->bframe_len = frm->len;
-
-               /** Anyway flip the bufbits **/
-               if ( misdn_cap_is_speech(bc->capability) )
-                       flip_buf_bits(bc->bframe, bc->bframe_len);
-
-
-               if (!bc->bframe_len) {
-                       cb_log(2, stack->port, "DL_DATA INDICATION bc->addr:%x frm->addr:%x\n", bc->addr, frm->addr);
-                       free_msg(msg);
-                       return 1;
-               }
-
-               if ( (bc->addr&STACK_ID_MASK) != (frm->addr&STACK_ID_MASK) ) {
-                       cb_log(2, stack->port, "DL_DATA INDICATION bc->addr:%x frm->addr:%x\n", bc->addr, frm->addr);
-                       free_msg(msg);
-                       return 1;
-               }
-
-#if MISDN_DEBUG
-               cb_log(0, stack->port, "DL_DATA INDICATION Len %d\n", frm->len);
-
-#endif
-
-               if ( (bc->bc_state == BCHAN_ACTIVATED) && frm->len > 0) {
-                       int t;
-
-#ifdef MISDN_B_DEBUG
-                       cb_log(0,bc->port,"do_tone START\n");
-#endif
-                       t=do_tone(bc,frm->len);
-
-#ifdef MISDN_B_DEBUG
-                       cb_log(0,bc->port,"do_tone STOP (%d)\n",t);
-#endif
-                       if (  !t ) {
-                               int i;
-
-                               if ( misdn_cap_is_speech(bc->capability)) {
-                                       if ( !bc->nojitter ) {
-#ifdef MISDN_B_DEBUG
-                                               cb_log(0,bc->port,"tx_jitter START\n");
-#endif
-                                               misdn_tx_jitter(bc,frm->len);
-#ifdef MISDN_B_DEBUG
-                                               cb_log(0,bc->port,"tx_jitter STOP\n");
-#endif
-                                       }
-                               }
-
-#ifdef MISDN_B_DEBUG
-                               cb_log(0,bc->port,"EVENT_B_DATA START\n");
-#endif
-
-                               i = cb_event(EVENT_BCHAN_DATA, bc, glob_mgr->user_data);
-#ifdef MISDN_B_DEBUG
-                               cb_log(0,bc->port,"EVENT_B_DATA STOP\n");
-#endif
-
-                               if (i<0) {
-                                       cb_log(10,stack->port,"cb_event returned <0\n");
-                                       /*clean_up_bc(bc);*/
-                               }
-                       }
-               }
-               free_msg(msg);
-               return 1;
-       }
-
-
-       case PH_CONTROL | CONFIRM:
-               cb_log(4, stack->port, "PH_CONTROL|CNF bc->addr:%x\n", frm->addr);
-               free_msg(msg);
-               return 1;
-
-       case PH_DATA | CONFIRM:
-       case DL_DATA|CONFIRM:
-#if MISDN_DEBUG
-
-               cb_log(0, stack->port, "Data confirmed\n");
-
-#endif
-               free_msg(msg);
-               return 1;
-       case DL_DATA|RESPONSE:
-#if MISDN_DEBUG
-               cb_log(0, stack->port, "Data response\n");
-
-#endif
-               break;
-       }
-
-       return 0;
-}
-
-
-
-static int handle_frm_nt(msg_t *msg)
-{
-       iframe_t *frm= (iframe_t*)msg->data;
-       struct misdn_stack *stack;
-       int err=0;
-
-       stack=find_stack_by_addr( frm->addr );
-
-
-
-       if (!stack || !stack->nt) {
-               return 0;
-       }
-
-
-       pthread_mutex_lock(&stack->nstlock);
-       if ((err=stack->nst.l1_l2(&stack->nst,msg))) {
-               pthread_mutex_unlock(&stack->nstlock);
-               if (nt_err_cnt > 0 ) {
-                       if (nt_err_cnt < 100) {
-                               nt_err_cnt++;
-                               cb_log(0, stack->port, "NT Stack sends us error: %d \n", err);
-                       } else if (nt_err_cnt < 105){
-                               cb_log(0, stack->port, "NT Stack sends us error: %d over 100 times, so I'll stop this message\n", err);
-                               nt_err_cnt = - 1;
-                       }
-               }
-               free_msg(msg);
-               return 1;
-       }
-       pthread_mutex_unlock(&stack->nstlock);
-       return 1;
-}
-
-
-static int handle_frm_te(msg_t *msg)
-{
-       struct misdn_bchannel dummybc;
-       struct misdn_bchannel *bc;
-       iframe_t *frm;
-       struct misdn_stack *stack;
-       enum event_e event;
-       enum event_response_e response;
-       int ret;
-       int channel;
-       int tmpcause;
-       int tmp_out_cause;
-
-       frm = (iframe_t*) msg->data;
-       stack = find_stack_by_addr(frm->addr);
-       if (!stack || stack->nt) {
-               return 0;
-       }
-
-       cb_log(4, stack->port, "handle_frm_te: frm->addr:%x frm->prim:%x\n", frm->addr, frm->prim);
-
-       ret = handle_cr(stack, frm);
-       if (ret < 0) {
-               cb_log(3, stack->port, "handle_frm_te: handle_cr <0 prim:%x addr:%x\n", frm->prim, frm->addr);
-       }
-       if (ret) {
-               free_msg(msg);
-               return 1;
-       }
-
-       bc = find_bc_by_l3id(stack, frm->dinfo);
-       if (!bc) {
-               misdn_make_dummy(&dummybc, stack->port, 0, stack->nt, 0);
-               switch (frm->prim) {
-               case CC_RESTART | CONFIRM:
-                       dummybc.l3_id = MISDN_ID_GLOBAL;
-                       bc = &dummybc;
-                       break;
-               case CC_SETUP | INDICATION:
-                       dummybc.l3_id = frm->dinfo;
-                       bc = &dummybc;
-
-                       /* set a reasonable cause */
-                       bc->out_cause = AST_CAUSE_REQUESTED_CHAN_UNAVAIL;
-                       /* if we want to send something the flag must be set! */
-                       bc->need_release_complete = 1;
-                       misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE);
-
-                       free_msg(msg);
-                       return 1;
-               default:
-                       if (frm->prim == (CC_FACILITY | INDICATION)) {
-                               cb_log(5, stack->port, " --> Using Dummy BC for FACILITY\n");
-                       } else {
-                               cb_log(0, stack->port, " --> Didn't find BC so temporarily creating dummy BC (l3id:%x) on this port.\n", frm->dinfo);
-                               dummybc.l3_id = frm->dinfo;
-                       }
-                       bc = &dummybc;
-                       break;
-               }
-       }
-
-       event = isdn_msg_get_event(msgs_g, msg, 0);
-       isdn_msg_parse_event(msgs_g, msg, bc, 0);
-
-       /* Preprocess some Events */
-       ret = handle_event_te(bc, event, frm);
-       if (ret < 0) {
-               cb_log(0, stack->port, "couldn't handle event\n");
-               free_msg(msg);
-               return 1;
-       }
-
-       /* shoot up event to App: */
-       cb_log(5, stack->port, "lib Got Prim: Addr %x prim %x dinfo %x\n", frm->addr, frm->prim, frm->dinfo);
-
-       if (!isdn_get_info(msgs_g, event, 0)) {
-               cb_log(0, stack->port, "Unknown Event Ind: Addr:%x prim %x dinfo %x\n", frm->addr, frm->prim, frm->dinfo);
-               response = RESPONSE_OK;
-       } else {
-               response = cb_event(event, bc, glob_mgr->user_data);
-       }
-
-       switch (event) {
-       case EVENT_SETUP:
-               switch (response) {
-               case RESPONSE_IGNORE_SETUP_WITHOUT_CLOSE:
-                       cb_log(0, stack->port, "TOTALLY IGNORING SETUP\n");
-                       break;
-               case RESPONSE_IGNORE_SETUP:
-                       cb_log(0, stack->port, "GOT IGNORE SETUP\n");
-                       /* I think we should send CC_RELEASE_CR, but am not sure*/
-                       bc->out_cause = AST_CAUSE_NORMAL_CLEARING;
-                       /* fall through */
-               case RESPONSE_RELEASE_SETUP:
-                       if (response == RESPONSE_RELEASE_SETUP) {
-                               cb_log(0, stack->port, "GOT RELEASE SETUP\n");
-                       }
-                       misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE);
-                       break;
-               case RESPONSE_OK:
-                       cb_log(4, stack->port, "GOT SETUP OK\n");
-                       break;
-               default:
-                       cb_log(0, stack->port, "GOT UNKNOWN SETUP RESPONSE\n");
-                       break;
-               }
-               break;
-       case EVENT_RELEASE_COMPLETE:
-               /* release bchannel only after we've announced the RELEASE_COMPLETE */
-               channel = bc->channel;
-               tmpcause = bc->cause;
-               tmp_out_cause = bc->out_cause;
-
-               empty_bc(bc);
-               bc->cause = tmpcause;
-               bc->out_cause = tmp_out_cause;
-               clean_up_bc(bc);
-               bc->in_use = 0;
-
-               if (tmpcause == AST_CAUSE_REQUESTED_CHAN_UNAVAIL) {
-                       cb_log(0, stack->port, "**** Received CAUSE:%d, restarting channel %d\n", AST_CAUSE_REQUESTED_CHAN_UNAVAIL, channel);
-                       misdn_lib_send_restart(stack->port, channel);
-               }
-               if (channel > 0) {
-                       empty_chan_in_stack(stack, channel);
-               }
-               break;
-       case EVENT_RESTART:
-               cb_log(0, stack->port, "**** Received RESTART channel:%d\n", bc->restart_channel);
-               empty_chan_in_stack(stack, bc->restart_channel);
-               break;
-       default:
-               break;
-       }
-
-       cb_log(5, stack->port, "Freeing Msg on prim:%x \n", frm->prim);
-       free_msg(msg);
-       return 1;
-}
-
-
-static int handle_l1(msg_t *msg)
-{
-       iframe_t *frm = (iframe_t*) msg->data;
-       struct misdn_stack *stack = find_stack_by_addr(frm->addr);
-
-       if (!stack) return 0 ;
-
-       switch (frm->prim) {
-       case PH_ACTIVATE | CONFIRM:
-               /* we have to check for errors! */
-               if (frm->len) {
-                       cb_log (3, stack->port, "L1: PH_ACTIVATE|REQUEST returned error!\n");
-                       free_msg(msg);
-                       return 1;
-               }
-               /* fall through */
-       case PH_ACTIVATE | INDICATION:
-               cb_log (3, stack->port, "L1: PH L1Link Up!\n");
-               stack->l1link=1;
-
-               if (stack->nt) {
-
-                       pthread_mutex_lock(&stack->nstlock);
-                       if (stack->nst.l1_l2(&stack->nst, msg))
-                               free_msg(msg);
-                       pthread_mutex_unlock(&stack->nstlock);
-
-                       if (stack->ptp)
-                               misdn_lib_get_l2_up(stack);
-               } else {
-                       free_msg(msg);
-               }
-               return 1;
-
-       case PH_ACTIVATE | REQUEST:
-               free_msg(msg);
-               cb_log(3,stack->port,"L1: PH_ACTIVATE|REQUEST \n");
-               return 1;
-
-       case PH_DEACTIVATE | REQUEST:
-               free_msg(msg);
-               cb_log(3,stack->port,"L1: PH_DEACTIVATE|REQUEST \n");
-               return 1;
-
-       case PH_DEACTIVATE | CONFIRM:
-               /* we have to check for errors! */
-               if (frm->len) {
-                       cb_log (3, stack->port, "L1: PH_DEACTIVATE|REQUEST returned error!\n");
-                       free_msg(msg);
-                       return 1;
-               }
-               /* fall through */
-       case PH_DEACTIVATE | INDICATION:
-               cb_log (3, stack->port, "L1: PH L1Link Down! \n");
-
-#if 0
-               for (i=0; i<=stack->b_num; i++) {
-                       if (global_state == MISDN_INITIALIZED)  {
-                               cb_event(EVENT_CLEANUP, &stack->bc[i], glob_mgr->user_data);
-                       }
-               }
-#endif
-
-               if (stack->nt) {
-                       pthread_mutex_lock(&stack->nstlock);
-                       if (stack->nst.l1_l2(&stack->nst, msg))
-                               free_msg(msg);
-                       pthread_mutex_unlock(&stack->nstlock);
-               } else {
-                       free_msg(msg);
-               }
-
-               stack->l1link=0;
-               stack->l2link=0;
-               return 1;
-       }
-
-       return 0;
-}
-
-static int handle_l2(msg_t *msg)
-{
-       iframe_t *frm = (iframe_t*) msg->data;
-
-       struct misdn_stack *stack = find_stack_by_addr(frm->addr);
-
-       if (!stack) {
-               return 0 ;
-       }
-
-       switch(frm->prim) {
-
-       case DL_ESTABLISH | REQUEST:
-               cb_log(1,stack->port,"DL_ESTABLISH|REQUEST \n");
-               free_msg(msg);
-               return 1;
-       case DL_RELEASE | REQUEST:
-               cb_log(1,stack->port,"DL_RELEASE|REQUEST \n");
-               free_msg(msg);
-               return 1;
-
-       case DL_ESTABLISH | INDICATION:
-       case DL_ESTABLISH | CONFIRM:
-       {
-               cb_log (3, stack->port, "L2: L2Link Up! \n");
-               if (stack->ptp && stack->l2link) {
-                       cb_log (-1, stack->port, "L2: L2Link Up! but it's already UP.. must be faulty, blocking port\n");
-                       cb_event(EVENT_PORT_ALARM, &stack->bc[0], glob_mgr->user_data);
-               }
-               stack->l2link=1;
-               free_msg(msg);
-               return 1;
-       }
-       break;
-
-       case DL_RELEASE | INDICATION:
-       case DL_RELEASE | CONFIRM:
-       {
-               cb_log (3, stack->port, "L2: L2Link Down! \n");
-               stack->l2link=0;
-
-               free_msg(msg);
-               return 1;
-       }
-       break;
-       }
-       return 0;
-}
-
-static int handle_mgmt(msg_t *msg)
-{
-       iframe_t *frm = (iframe_t*) msg->data;
-       struct misdn_stack *stack;
-
-       if ( (frm->addr == 0) && (frm->prim == (MGR_DELLAYER|CONFIRM)) ) {
-               cb_log(2, 0, "MGMT: DELLAYER|CONFIRM Addr: 0 !\n") ;
-               free_msg(msg);
-               return 1;
-       }
-
-       stack = find_stack_by_addr(frm->addr);
-
-       if (!stack) {
-               if (frm->prim == (MGR_DELLAYER|CONFIRM)) {
-                       cb_log(2, 0, "MGMT: DELLAYER|CONFIRM Addr: %x !\n",
-                                       frm->addr) ;
-                       free_msg(msg);
-                       return 1;
-               }
-
-               return 0;
-       }
-
-       switch(frm->prim) {
-       case MGR_SHORTSTATUS | INDICATION:
-       case MGR_SHORTSTATUS | CONFIRM:
-               cb_log(5, stack->port, "MGMT: Short status dinfo %x\n",frm->dinfo);
-
-               switch (frm->dinfo) {
-               case SSTATUS_L1_ACTIVATED:
-                       cb_log(3, stack->port, "MGMT: SSTATUS: L1_ACTIVATED \n");
-                       stack->l1link=1;
-
-                       break;
-               case SSTATUS_L1_DEACTIVATED:
-                       cb_log(3, stack->port, "MGMT: SSTATUS: L1_DEACTIVATED \n");
-                       stack->l1link=0;
-#if 0
-                       clear_l3(stack);
-#endif
-                       break;
-
-               case SSTATUS_L2_ESTABLISHED:
-                       cb_log(3, stack->port, "MGMT: SSTATUS: L2_ESTABLISH \n");
-                       stack->l2link=1;
-                       break;
-
-               case SSTATUS_L2_RELEASED:
-                       cb_log(3, stack->port, "MGMT: SSTATUS: L2_RELEASED \n");
-                       stack->l2link=0;
-                       break;
-               }
-
-               free_msg(msg);
-               return 1;
-
-       case MGR_SETSTACK | INDICATION:
-               cb_log(4, stack->port, "MGMT: SETSTACK|IND dinfo %x\n",frm->dinfo);
-               free_msg(msg);
-               return 1;
-       case MGR_DELLAYER | CONFIRM:
-               cb_log(4, stack->port, "MGMT: DELLAYER|CNF dinfo %x\n",frm->dinfo) ;
-               free_msg(msg);
-               return 1;
-
-       }
-
-       /*
-       if ( (frm->prim & 0x0f0000) ==  0x0f0000) {
-       cb_log(5, 0, "$$$ MGMT FRAME: prim %x addr %x dinfo %x\n",frm->prim, frm->addr, frm->dinfo) ;
-       free_msg(msg);
-       return 1;
-       } */
-
-       return 0;
-}
-
-
-static msg_t *fetch_msg(int midev)
-{
-       msg_t *msg=alloc_msg(MAX_MSG_SIZE);
-       int r;
-
-       if (!msg) {
-               cb_log(0, 0, "fetch_msg: alloc msg failed !!");
-               return NULL;
-       }
-
-       AGAIN:
-               r=mISDN_read(midev,msg->data,MAX_MSG_SIZE, TIMEOUT_10SEC);
-               msg->len=r;
-
-               if (r==0) {
-                       free_msg(msg); /* danger, cause usually freeing in main_loop */
-                       cb_log(6,0,"Got empty Msg..\n");
-                       return NULL;
-               }
-
-               if (r<0) {
-                       if (errno == EAGAIN) {
-                               /*we wait for mISDN here*/
-                               cb_log(4,0,"mISDN_read wants us to wait\n");
-                               usleep(5000);
-                               goto AGAIN;
-                       }
-
-                       cb_log(0,0,"mISDN_read returned :%d error:%s (%d)\n",r,strerror(errno),errno);
-               }
-
-#if 0
-               if  (!(frm->prim == (DL_DATA|INDICATION) )|| (frm->prim == (PH_DATA|INDICATION)))
-                       cb_log(0,0,"prim: %x dinfo:%x addr:%x msglen:%d frm->len:%d\n",frm->prim, frm->dinfo, frm->addr, msg->len,frm->len );
-#endif
-               return msg;
-}
-
-void misdn_lib_isdn_l1watcher(int port)
-{
-       struct misdn_stack *stack;
-
-       for (stack = glob_mgr->stack_list; stack && (stack->port != port); stack = stack->next)
-               ;
-
-       if (stack) {
-               cb_log(4, port, "Checking L1 State\n");
-               if (!stack->l1link) {
-                       cb_log(4, port, "L1 State Down, trying to get it up again\n");
-                       misdn_lib_get_short_status(stack);
-                       misdn_lib_get_l1_up(stack);
-                       misdn_lib_get_l2_up(stack);
-               }
-       }
-}
-
-/* This is a thread */
-static void misdn_lib_isdn_event_catcher(void *arg)
-{
-       struct misdn_lib *mgr = arg;
-       int zero_frm=0 , fff_frm=0 ;
-       int midev= mgr->midev;
-       int port=0;
-
-       while (1) {
-               msg_t *msg = fetch_msg(midev);
-               iframe_t *frm;
-
-
-               if (!msg) continue;
-
-               frm = (iframe_t*) msg->data;
-
-               /** When we make a call from NT2Ast we get these frames **/
-               if (frm->len == 0 && frm->addr == 0 && frm->dinfo == 0 && frm->prim == 0 ) {
-                       zero_frm++;
-                       free_msg(msg);
-                       continue;
-               } else {
-                       if (zero_frm) {
-                               cb_log(0, port, "*** Alert: %d zero_frms caught\n", zero_frm);
-                               zero_frm = 0 ;
-                       }
-               }
-
-               /** I get this sometimes after setup_bc **/
-               if (frm->len == 0 &&  frm->dinfo == 0 && frm->prim == 0xffffffff ) {
-                       fff_frm++;
-                       free_msg(msg);
-                       continue;
-               } else {
-                       if (fff_frm) {
-                               cb_log(0, port, "*** Alert: %d fff_frms caught\n", fff_frm);
-                               fff_frm = 0 ;
-                       }
-               }
-
-               manager_isdn_handler(frm, msg);
-       }
-
-}
-
-
-/** App Interface **/
-
-static int te_lib_init(void)
-{
-       char buff[1025] = "";
-       iframe_t *frm = (iframe_t *) buff;
-       int midev;
-       int ret;
-
-       midev = mISDN_open();
-       if (midev <= 0) {
-               return midev;
-       }
-
-       /* create entity for layer 3 TE-mode */
-       mISDN_write_frame(midev, buff, 0, MGR_NEWENTITY | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
-
-       ret = mISDN_read_frame(midev, frm, sizeof(iframe_t), 0, MGR_NEWENTITY | CONFIRM, TIMEOUT_1SEC);
-       entity = frm->dinfo & 0xffff;
-       if (ret < mISDN_HEADER_LEN || !entity) {
-               fprintf(stderr, "cannot request MGR_NEWENTITY from mISDN: %s\n", strerror(errno));
-               mISDN_close(midev);
-               return -1;
-       }
-
-       return midev;
-}
-
-void te_lib_destroy(int midev)
-{
-       char buf[1024];
-       mISDN_write_frame(midev, buf, 0, MGR_DELENTITY | REQUEST, entity, 0, NULL, TIMEOUT_1SEC);
-
-       cb_log(4, 0, "Entity deleted\n");
-       mISDN_close(midev);
-       cb_log(4, 0, "midev closed\n");
-}
-
-struct misdn_bchannel *manager_find_bc_by_pid(int pid)
-{
-       struct misdn_stack *stack;
-       int i;
-
-       for (stack = glob_mgr->stack_list; stack; stack = stack->next) {
-               for (i = 0; i <= stack->b_num; i++) {
-                       if (stack->bc[i].in_use && stack->bc[i].pid == pid) {
-                               return &stack->bc[i];
-                       }
-               }
-       }
-
-       return NULL;
-}
-
-static int test_inuse(struct misdn_bchannel *bc)
-{
-       struct timeval now;
-
-       if (!bc->in_use) {
-               gettimeofday(&now, NULL);
-               if (bc->last_used.tv_sec == now.tv_sec
-                       && misdn_lib_port_is_pri(bc->port)) {
-                       cb_log(2, bc->port, "channel with stid:%x for one second still in use! (n:%d lu:%d)\n",
-                               bc->b_stid, (int) now.tv_sec, (int) bc->last_used.tv_sec);
-                       return 1;
-               }
-
-               cb_log(3,bc->port, "channel with stid:%x not in use!\n", bc->b_stid);
-               return 0;
-       }
-
-       cb_log(2,bc->port, "channel with stid:%x in use!\n", bc->b_stid);
-       return 1;
-}
-
-
-static void prepare_bc(struct misdn_bchannel*bc, int channel)
-{
-       bc->channel = channel;
-       bc->channel_preselected = channel?1:0;
-       bc->need_disconnect=1;
-       bc->need_release=1;
-       bc->need_release_complete=1;
-       bc->cause = AST_CAUSE_NORMAL_CLEARING;
-
-       if (++mypid>5000) mypid=1;
-       bc->pid=mypid;
-
-       bc->in_use = 1;
-}
-
-struct misdn_bchannel *misdn_lib_get_free_bc(int port, int channel, int inout, int dec)
-{
-       struct misdn_stack *stack;
-       int i;
-       int maxnum;
-
-       if (channel < 0 || channel > MAX_BCHANS) {
-               cb_log(0, port, "Requested channel out of bounds (%d)\n", channel);
-               return NULL;
-       }
-
-       /* Find the port stack structure */
-       stack = find_stack_by_port(port);
-       if (!stack) {
-               cb_log(0, port, "Port is not configured (%d)\n", port);
-               return NULL;
-       }
-
-       if (stack->blocked) {
-               cb_log(0, port, "Port is blocked\n");
-               return NULL;
-       }
-
-       pthread_mutex_lock(&stack->st_lock);
-       if (channel > 0) {
-               if (channel <= stack->b_num) {
-                       for (i = 0; i < stack->b_num; i++) {
-                               if (stack->bc[i].channel == channel) {
-                                       if (test_inuse(&stack->bc[i])) {
-                                               pthread_mutex_unlock(&stack->st_lock);
-                                               cb_log(0, port, "Requested channel:%d on port:%d is already in use\n", channel, port);
-                                               return NULL;
-                                       } else {
-                                               prepare_bc(&stack->bc[i], channel);
-                                               pthread_mutex_unlock(&stack->st_lock);
-                                               return &stack->bc[i];
-                                       }
-                               }
-                       }
-               } else {
-                       pthread_mutex_unlock(&stack->st_lock);
-                       cb_log(0, port, "Requested channel:%d is out of bounds on port:%d\n", channel, port);
-                       return NULL;
-               }
-       }
-
-       /* Note: channel == 0 here */
-       maxnum = (inout && !stack->pri && !stack->ptp) ? stack->b_num + 1 : stack->b_num;
-       if (dec) {
-               for (i = maxnum - 1; i >= 0; --i) {
-                       if (!test_inuse(&stack->bc[i])) {
-                               /* 3. channel on bri means CW*/
-                               if (!stack->pri && i == stack->b_num) {
-                                       stack->bc[i].cw = 1;
-                               }
-
-                               prepare_bc(&stack->bc[i], channel);
-                               stack->bc[i].dec = 1;
-                               pthread_mutex_unlock(&stack->st_lock);
-                               return &stack->bc[i];
-                       }
-               }
-       } else {
-               for (i = 0; i < maxnum; ++i) {
-                       if (!test_inuse(&stack->bc[i])) {
-                               /* 3. channel on bri means CW */
-                               if (!stack->pri && i == stack->b_num) {
-                                       stack->bc[i].cw = 1;
-                               }
-
-                               prepare_bc(&stack->bc[i], channel);
-                               pthread_mutex_unlock(&stack->st_lock);
-                               return &stack->bc[i];
-                       }
-               }
-       }
-       pthread_mutex_unlock(&stack->st_lock);
-
-       cb_log(1, port, "There is no free channel on port (%d)\n", port);
-       return NULL;
-}
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-/*!
- * \brief Allocate a B channel struct from the REGISTER pool
- *
- * \param port Logical port number
- *
- * \retval B channel struct on success.
- * \retval NULL on error.
- */
-struct misdn_bchannel *misdn_lib_get_register_bc(int port)
-{
-       struct misdn_stack *stack;
-       struct misdn_bchannel *bc;
-       unsigned index;
-
-       /* Find the port stack structure */
-       stack = find_stack_by_port(port);
-       if (!stack) {
-               cb_log(0, port, "Port is not configured (%d)\n", port);
-               return NULL;
-       }
-
-       if (stack->blocked) {
-               cb_log(0, port, "Port is blocked\n");
-               return NULL;
-       }
-
-       pthread_mutex_lock(&stack->st_lock);
-       for (index = MAX_BCHANS + 1; index < ARRAY_LEN(stack->bc); ++index) {
-               bc = &stack->bc[index];
-               if (!test_inuse(bc)) {
-                       prepare_bc(bc, 0);
-                       bc->need_disconnect = 0;
-                       bc->need_release = 0;
-                       pthread_mutex_unlock(&stack->st_lock);
-                       return bc;
-               }
-       }
-       pthread_mutex_unlock(&stack->st_lock);
-
-       cb_log(1, port, "There is no free REGISTER link on port (%d)\n", port);
-       return NULL;
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-/*!
- * \internal
- * \brief Convert the facility function enum value into a string.
- *
- * \return String version of the enum value
- */
-static const char *fac2str(enum FacFunction facility)
-{
-       static const struct {
-               enum FacFunction facility;
-               char *name;
-       } arr[] = {
-/* *INDENT-OFF* */
-               { Fac_None, "Fac_None" },
-#if defined(AST_MISDN_ENHANCEMENTS)
-               { Fac_ERROR, "Fac_ERROR" },
-               { Fac_RESULT, "Fac_RESULT" },
-               { Fac_REJECT, "Fac_REJECT" },
-
-               { Fac_ActivationDiversion, "Fac_ActivationDiversion" },
-               { Fac_DeactivationDiversion, "Fac_DeactivationDiversion" },
-               { Fac_ActivationStatusNotificationDiv, "Fac_ActivationStatusNotificationDiv" },
-               { Fac_DeactivationStatusNotificationDiv, "Fac_DeactivationStatusNotificationDiv" },
-               { Fac_InterrogationDiversion, "Fac_InterrogationDiversion" },
-               { Fac_DiversionInformation, "Fac_DiversionInformation" },
-               { Fac_CallDeflection, "Fac_CallDeflection" },
-               { Fac_CallRerouteing, "Fac_CallRerouteing" },
-               { Fac_DivertingLegInformation2, "Fac_DivertingLegInformation2" },
-               { Fac_InterrogateServedUserNumbers, "Fac_InterrogateServedUserNumbers" },
-               { Fac_DivertingLegInformation1, "Fac_DivertingLegInformation1" },
-               { Fac_DivertingLegInformation3, "Fac_DivertingLegInformation3" },
-
-               { Fac_EctExecute, "Fac_EctExecute" },
-               { Fac_ExplicitEctExecute, "Fac_ExplicitEctExecute" },
-               { Fac_RequestSubaddress, "Fac_RequestSubaddress" },
-               { Fac_SubaddressTransfer, "Fac_SubaddressTransfer" },
-               { Fac_EctLinkIdRequest, "Fac_EctLinkIdRequest" },
-               { Fac_EctInform, "Fac_EctInform" },
-               { Fac_EctLoopTest, "Fac_EctLoopTest" },
-
-               { Fac_ChargingRequest, "Fac_ChargingRequest" },
-               { Fac_AOCSCurrency, "Fac_AOCSCurrency" },
-               { Fac_AOCSSpecialArr, "Fac_AOCSSpecialArr" },
-               { Fac_AOCDCurrency, "Fac_AOCDCurrency" },
-               { Fac_AOCDChargingUnit, "Fac_AOCDChargingUnit" },
-               { Fac_AOCECurrency, "Fac_AOCECurrency" },
-               { Fac_AOCEChargingUnit, "Fac_AOCEChargingUnit" },
-
-               { Fac_StatusRequest, "Fac_StatusRequest" },
-
-               { Fac_CallInfoRetain, "Fac_CallInfoRetain" },
-               { Fac_EraseCallLinkageID, "Fac_EraseCallLinkageID" },
-               { Fac_CCBSDeactivate, "Fac_CCBSDeactivate" },
-               { Fac_CCBSErase, "Fac_CCBSErase" },
-               { Fac_CCBSRemoteUserFree, "Fac_CCBSRemoteUserFree" },
-               { Fac_CCBSCall, "Fac_CCBSCall" },
-               { Fac_CCBSStatusRequest, "Fac_CCBSStatusRequest" },
-               { Fac_CCBSBFree, "Fac_CCBSBFree" },
-               { Fac_CCBSStopAlerting, "Fac_CCBSStopAlerting" },
-
-               { Fac_CCBSRequest, "Fac_CCBSRequest" },
-               { Fac_CCBSInterrogate, "Fac_CCBSInterrogate" },
-
-               { Fac_CCNRRequest, "Fac_CCNRRequest" },
-               { Fac_CCNRInterrogate, "Fac_CCNRInterrogate" },
-
-               { Fac_CCBS_T_Call, "Fac_CCBS_T_Call" },
-               { Fac_CCBS_T_Suspend, "Fac_CCBS_T_Suspend" },
-               { Fac_CCBS_T_Resume, "Fac_CCBS_T_Resume" },
-               { Fac_CCBS_T_RemoteUserFree, "Fac_CCBS_T_RemoteUserFree" },
-               { Fac_CCBS_T_Available, "Fac_CCBS_T_Available" },
-
-               { Fac_CCBS_T_Request, "Fac_CCBS_T_Request" },
-
-               { Fac_CCNR_T_Request, "Fac_CCNR_T_Request" },
-
-#else
-
-               { Fac_CFActivate, "Fac_CFActivate" },
-               { Fac_CFDeactivate, "Fac_CFDeactivate" },
-               { Fac_CD, "Fac_CD" },
-
-               { Fac_AOCDCurrency, "Fac_AOCDCurrency" },
-               { Fac_AOCDChargingUnit, "Fac_AOCDChargingUnit" },
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-/* *INDENT-ON* */
-       };
-
-       unsigned index;
-
-       for (index = 0; index < ARRAY_LEN(arr); ++index) {
-               if (arr[index].facility == facility) {
-                       return arr[index].name;
-               }
-       }
-
-       return "unknown";
-}
-
-void misdn_lib_log_ies(struct misdn_bchannel *bc)
-{
-       struct misdn_stack *stack;
-
-       if (!bc) return;
-
-       stack = get_stack_by_bc(bc);
-
-       if (!stack) return;
-
-       cb_log(2, stack->port,
-               " --> channel:%d mode:%s cause:%d ocause:%d\n",
-               bc->channel,
-               stack->nt ? "NT" : "TE",
-               bc->cause,
-               bc->out_cause);
-
-       cb_log(2, stack->port,
-               " --> info_dad:%s dialed numtype:%d plan:%d\n",
-               bc->info_dad,
-               bc->dialed.number_type,
-               bc->dialed.number_plan);
-
-       cb_log(2, stack->port,
-               " --> caller:\"%s\" <%s> type:%d plan:%d pres:%d screen:%d\n",
-               bc->caller.name,
-               bc->caller.number,
-               bc->caller.number_type,
-               bc->caller.number_plan,
-               bc->caller.presentation,
-               bc->caller.screening);
-
-       cb_log(2, stack->port,
-               " --> redirecting-from:\"%s\" <%s> type:%d plan:%d pres:%d screen:%d\n",
-               bc->redirecting.from.name,
-               bc->redirecting.from.number,
-               bc->redirecting.from.number_type,
-               bc->redirecting.from.number_plan,
-               bc->redirecting.from.presentation,
-               bc->redirecting.from.screening);
-       cb_log(2, stack->port,
-               " --> redirecting-to:\"%s\" <%s> type:%d plan:%d pres:%d screen:%d\n",
-               bc->redirecting.to.name,
-               bc->redirecting.to.number,
-               bc->redirecting.to.number_type,
-               bc->redirecting.to.number_plan,
-               bc->redirecting.to.presentation,
-               bc->redirecting.to.screening);
-       cb_log(2, stack->port,
-               " --> redirecting reason:%d count:%d\n",
-               bc->redirecting.reason,
-               bc->redirecting.count);
-
-       cb_log(2, stack->port,
-               " --> connected:\"%s\" <%s> type:%d plan:%d pres:%d screen:%d\n",
-               bc->connected.name,
-               bc->connected.number,
-               bc->connected.number_type,
-               bc->connected.number_plan,
-               bc->connected.presentation,
-               bc->connected.screening);
-
-       cb_log(3, stack->port, " --> caps:%s pi:%x keypad:%s sending_complete:%d\n", bearer2str(bc->capability),bc->progress_indicator, bc->keypad, bc->sending_complete);
-
-       cb_log(4, stack->port, " --> set_pres:%d pres:%d\n", bc->set_presentation, bc->presentation);
-
-       cb_log(4, stack->port, " --> addr:%x l3id:%x b_stid:%x layer_id:%x\n", bc->addr, bc->l3_id, bc->b_stid, bc->layer_id);
-
-       cb_log(4, stack->port, " --> facility in:%s out:%s\n", fac2str(bc->fac_in.Function), fac2str(bc->fac_out.Function));
-
-       cb_log(5, stack->port, " --> urate:%d rate:%d mode:%d user1:%d\n", bc->urate, bc->rate, bc->mode,bc->user1);
-
-       cb_log(5, stack->port, " --> bc:%p h:%d sh:%d\n", bc, bc->holded, bc->stack_holder);
-}
-
-
-#define RETURN(a,b) {retval=a; goto b;}
-
-static void misdn_send_lock(struct misdn_bchannel *bc)
-{
-       //cb_log(0,bc->port,"Locking bc->pid:%d\n", bc->pid);
-       if (bc->send_lock)
-               pthread_mutex_lock(&bc->send_lock->lock);
-}
-
-static void misdn_send_unlock(struct misdn_bchannel *bc)
-{
-       //cb_log(0,bc->port,"UnLocking bc->pid:%d\n", bc->pid);
-       if (bc->send_lock)
-               pthread_mutex_unlock(&bc->send_lock->lock);
-}
-
-int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event )
-{
-       msg_t *msg;
-       struct misdn_bchannel *bc2;
-       struct misdn_bchannel *held_bc;
-       struct misdn_stack *stack;
-       int retval = 0;
-       int channel;
-       int tmpcause;
-       int tmp_out_cause;
-
-       if (!bc)
-               RETURN(-1,OUT_POST_UNLOCK);
-
-       stack = get_stack_by_bc(bc);
-       if (!stack) {
-               cb_log(0,bc->port,
-                       "SENDEVENT: no Stack for event:%s caller:\"%s\" <%s> dialed:%s \n",
-                       isdn_get_info(msgs_g, event, 0),
-                       bc->caller.name,
-                       bc->caller.number,
-                       bc->dialed.number);
-               RETURN(-1,OUT);
-       }
-
-       misdn_send_lock(bc);
-
-
-       cb_log(6,stack->port,"SENDEVENT: stack->nt:%d stack->upperid:%x\n",stack->nt, stack->upper_id);
-
-       if ( stack->nt && !stack->l1link) {
-               misdn_lib_get_l1_up(stack);
-       }
-
-       cb_log(1, stack->port,
-               "I SEND:%s caller:\"%s\" <%s> dialed:%s pid:%d\n",
-               isdn_get_info(msgs_g, event, 0),
-               bc->caller.name,
-               bc->caller.number,
-               bc->dialed.number,
-               bc->pid);
-       cb_log(4, stack->port, " --> bc_state:%s\n",bc_state2str(bc->bc_state));
-       misdn_lib_log_ies(bc);
-
-       switch (event) {
-       case EVENT_REGISTER:
-       case EVENT_SETUP:
-               if (create_process(glob_mgr->midev, bc) < 0) {
-                       cb_log(0, stack->port, " No free channel at the moment @ send_event\n");
-
-                       RETURN(-ENOCHAN,OUT);
-               }
-               break;
-
-       case EVENT_PROGRESS:
-       case EVENT_ALERTING:
-       case EVENT_PROCEEDING:
-       case EVENT_SETUP_ACKNOWLEDGE:
-       case EVENT_CONNECT:
-               if (!stack->nt) {
-                       if (stack->ptp) {
-                               setup_bc(bc);
-                       }
-                       break;
-               }
-               /* fall through */
-
-       case EVENT_RETRIEVE_ACKNOWLEDGE:
-               if (stack->nt) {
-                       if (bc->channel <=0 ) { /*  else we have the channel already */
-                               if (find_free_chan_in_stack(stack, bc, 0, 0)<0) {
-                                       cb_log(0, stack->port, " No free channel at the moment\n");
-                                       /*FIXME: add disconnect*/
-                                       RETURN(-ENOCHAN,OUT);
-                               }
-                       }
-                       /* Its that i generate channels */
-               }
-
-               retval=setup_bc(bc);
-               if (retval == -EINVAL) {
-                       cb_log(0,bc->port,"send_event: setup_bc failed\n");
-               }
-
-               if (misdn_cap_is_speech(bc->capability)) {
-                       if ((event==EVENT_CONNECT)||(event==EVENT_RETRIEVE_ACKNOWLEDGE)) {
-                               if ( *bc->crypt_key ) {
-                                       cb_log(4, stack->port,
-                                               " --> ENABLING BLOWFISH channel:%d caller%d:\"%s\" <%s> dialed%d:%s\n",
-                                               bc->channel,
-                                               bc->caller.number_type,
-                                               bc->caller.name,
-                                               bc->caller.number,
-                                               bc->dialed.number_type,
-                                               bc->dialed.number);
-
-                                       manager_ph_control_block(bc,  BF_ENABLE_KEY, bc->crypt_key, strlen(bc->crypt_key) );
-                               }
-
-                               if (!bc->nodsp) manager_ph_control(bc,  DTMF_TONE_START, 0);
-                               manager_ec_enable(bc);
-
-                               if (bc->txgain != 0) {
-                                       cb_log(4, stack->port,  "--> Changing txgain to %d\n", bc->txgain);
-                                       manager_ph_control(bc, VOL_CHANGE_TX, bc->txgain);
-                               }
-
-                               if ( bc->rxgain != 0 ) {
-                                       cb_log(4, stack->port,  "--> Changing rxgain to %d\n", bc->rxgain);
-                                       manager_ph_control(bc, VOL_CHANGE_RX, bc->rxgain);
-                               }
-                       }
-               }
-               break;
-
-       case EVENT_HOLD_ACKNOWLEDGE:
-               held_bc = malloc(sizeof(struct misdn_bchannel));
-               if (!held_bc) {
-                       cb_log(0, bc->port, "Could not allocate held_bc!!!\n");
-                       RETURN(-1,OUT);
-               }
-
-               /* backup the bc and put it in storage */
-               *held_bc = *bc;
-               held_bc->holded = 1;
-               held_bc->channel = 0;/* A held call does not have a channel anymore. */
-               held_bc->channel_preselected = 0;
-               held_bc->channel_found = 0;
-               bc_state_change(held_bc, BCHAN_CLEANED);
-               stack_holder_add(stack, held_bc);
-
-               /* kill the bridge and clean the real b-channel record */
-               if (stack->nt) {
-                       if (bc->bc_state == BCHAN_BRIDGED) {
-                               misdn_split_conf(bc,bc->conf_id);
-                               bc2 = find_bc_by_confid(bc->conf_id);
-                               if (!bc2) {
-                                       cb_log(0,bc->port,"We have no second bc in bridge???\n");
-                               } else {
-                                       misdn_split_conf(bc2,bc->conf_id);
-                               }
-                       }
-
-                       channel = bc->channel;
-
-                       empty_bc(bc);
-                       clean_up_bc(bc);
-
-                       if (channel>0)
-                               empty_chan_in_stack(stack,channel);
-
-                       bc->in_use=0;
-               }
-               break;
-
-       /* finishing the channel eh ? */
-       case EVENT_DISCONNECT:
-               if (!bc->need_disconnect) {
-                       cb_log(0, bc->port, " --> we have already sent DISCONNECT\n");
-                       RETURN(-1,OUT);
-               }
-               /* IE cause is mandatory for DISCONNECT, but optional for the answers to DISCONNECT.
-                * We must initialize cause, so it is later correctly indicated to ast_channel
-                * in case the answer does not include one!
-                */
-               bc->cause = bc->out_cause;
-
-               bc->need_disconnect=0;
-               break;
-       case EVENT_RELEASE:
-               if (!bc->need_release) {
-                       cb_log(0, bc->port, " --> we have already sent RELEASE\n");
-                       RETURN(-1,OUT);
-               }
-               bc->need_disconnect=0;
-               bc->need_release=0;
-               break;
-       case EVENT_RELEASE_COMPLETE:
-               if (!bc->need_release_complete) {
-                       cb_log(0, bc->port, " --> we have already sent RELEASE_COMPLETE\n");
-                       RETURN(-1,OUT);
-               }
-               bc->need_disconnect=0;
-               bc->need_release=0;
-               bc->need_release_complete=0;
-
-               if (!stack->nt) {
-                       /* create cleanup in TE */
-                       channel = bc->channel;
-                       tmpcause = bc->cause;
-                       tmp_out_cause = bc->out_cause;
-
-                       empty_bc(bc);
-                       bc->cause=tmpcause;
-                       bc->out_cause=tmp_out_cause;
-                       clean_up_bc(bc);
-
-                       if (channel>0)
-                               empty_chan_in_stack(stack,channel);
-
-                       bc->in_use=0;
-               }
-               break;
-
-       case EVENT_CONNECT_ACKNOWLEDGE:
-               if ( bc->nt || misdn_cap_is_speech(bc->capability)) {
-                       int retval=setup_bc(bc);
-                       if (retval == -EINVAL){
-                               cb_log(0,bc->port,"send_event: setup_bc failed\n");
-
-                       }
-               }
-
-               if (misdn_cap_is_speech(bc->capability)) {
-                       if (  !bc->nodsp) manager_ph_control(bc,  DTMF_TONE_START, 0);
-                       manager_ec_enable(bc);
-
-                       if ( bc->txgain != 0 ) {
-                               cb_log(4, stack->port, "--> Changing txgain to %d\n", bc->txgain);
-                               manager_ph_control(bc, VOL_CHANGE_TX, bc->txgain);
-                       }
-                       if ( bc->rxgain != 0 ) {
-                               cb_log(4, stack->port, "--> Changing rxgain to %d\n", bc->rxgain);
-                               manager_ph_control(bc, VOL_CHANGE_RX, bc->rxgain);
-                       }
-               }
-               break;
-
-       default:
-               break;
-       }
-
-       /* Later we should think about sending bchannel data directly to misdn. */
-       msg = isdn_msg_build_event(msgs_g, bc, event, stack->nt);
-       if (!msg) {
-               /*
-                * The message was not built.
-                *
-                * NOTE:  The only time that the message will fail to build
-                * is because the requested FACILITY message is not supported.
-                * A failed malloc() results in exit() being called.
-                */
-               RETURN(-1, OUT);
-       } else {
-               msg_queue_tail(&stack->downqueue, msg);
-               sem_post(&glob_mgr->new_msg);
-       }
-
-OUT:
-       misdn_send_unlock(bc);
-
-OUT_POST_UNLOCK:
-       return retval;
-}
-
-
-static int handle_err(msg_t *msg)
-{
-       iframe_t *frm = (iframe_t*) msg->data;
-
-
-       if (!frm->addr) {
-               static int cnt=0;
-               if (!cnt)
-                       cb_log(0,0,"mISDN Msg without Address pr:%x dinfo:%x\n",frm->prim,frm->dinfo);
-               cnt++;
-               if (cnt>100) {
-                       cb_log(0,0,"mISDN Msg without Address pr:%x dinfo:%x (already more than 100 of them)\n",frm->prim,frm->dinfo);
-                       cnt=0;
-               }
-
-               free_msg(msg);
-               return 1;
-
-       }
-
-       switch (frm->prim) {
-               case MGR_SETSTACK|INDICATION:
-                       return handle_bchan(msg);
-               break;
-
-               case MGR_SETSTACK|CONFIRM:
-               case MGR_CLEARSTACK|CONFIRM:
-                       free_msg(msg) ;
-                       return 1;
-               break;
-
-               case DL_DATA|CONFIRM:
-                       cb_log(4,0,"DL_DATA|CONFIRM\n");
-                       free_msg(msg);
-                       return 1;
-
-               case PH_CONTROL|CONFIRM:
-                       cb_log(4,0,"PH_CONTROL|CONFIRM\n");
-                       free_msg(msg);
-                       return 1;
-
-               case DL_DATA|INDICATION:
-               {
-                       int port=(frm->addr&MASTER_ID_MASK) >> 8;
-                       int channel=(frm->addr&CHILD_ID_MASK) >> 16;
-
-                       /*we flush the read buffer here*/
-
-                       cb_log(9,0,"BCHAN DATA without BC: addr:%x port:%d channel:%d\n",frm->addr, port,channel);
-
-                       free_msg(msg);
-                       return 1;
-               }
-       }
-
-       return 0;
-}
-
-int manager_isdn_handler(iframe_t *frm ,msg_t *msg)
-{
-
-       if (frm->dinfo==0xffffffff && frm->prim==(PH_DATA|CONFIRM)) {
-               cb_log(0,0,"SERIOUS BUG, dinfo == 0xffffffff, prim == PH_DATA | CONFIRM !!!!\n");
-       }
-
-       /* Timer primitives must be handled first, because the frm->addr is a different
-        * "address space" than the stack/instance address of other Lx primitives.
-        */
-       if (handle_timers(msg)) {
-               return 0;
-       }
-
-       if ( ((frm->addr | ISDN_PID_BCHANNEL_BIT )>> 28 ) == 0x5) {
-               static int unhandled_bmsg_count=1000;
-               if (handle_bchan(msg)) {
-                       return 0 ;
-               }
-
-               if (unhandled_bmsg_count==1000) {
-                       cb_log(0, 0, "received 1k Unhandled Bchannel Messages: prim %x len %d from addr %x, dinfo %x on this port.\n",frm->prim, frm->len, frm->addr, frm->dinfo);
-                       unhandled_bmsg_count=0;
-               }
-
-               unhandled_bmsg_count++;
-               free_msg(msg);
-               return 0;
-       }
-
-#ifdef RECV_FRM_SYSLOG_DEBUG
-       syslog(LOG_NOTICE,"mISDN recv: ADDR:%x PRIM:%x DINFO:%x\n", frm->addr, frm->prim, frm->dinfo);
-#endif
-
-       if (handle_mgmt(msg))
-               return 0 ;
-
-       if (handle_l2(msg))
-               return 0 ;
-
-       /* Its important to handle l1 AFTER l2  */
-       if (handle_l1(msg))
-               return 0 ;
-
-       if (handle_frm_nt(msg)) {
-               return 0;
-       }
-
-       if (handle_frm_te(msg)) {
-               return 0;
-       }
-
-       if (handle_err(msg)) {
-               return 0 ;
-       }
-
-       cb_log(0, 0, "Unhandled Message: prim %x len %d from addr %x, dinfo %x on this port.\n",frm->prim, frm->len, frm->addr, frm->dinfo);
-       free_msg(msg);
-
-
-       return 0;
-}
-
-
-
-
-int misdn_lib_get_port_info(int port)
-{
-       msg_t *msg=alloc_msg(MAX_MSG_SIZE);
-       iframe_t *frm;
-       struct misdn_stack *stack=find_stack_by_port(port);
-       if (!msg) {
-               cb_log(0, port, "misdn_lib_get_port_info: alloc_msg failed!\n");
-               return -1;
-       }
-       frm=(iframe_t*)msg->data;
-       if (!stack ) {
-               cb_log(0, port, "There is no Stack for this port.\n");
-               return -1;
-       }
-       /* activate bchannel */
-       frm->prim = CC_STATUS_ENQUIRY | REQUEST;
-
-       frm->addr = stack->upper_id| FLG_MSG_DOWN;
-
-       frm->dinfo = 0;
-       frm->len = 0;
-
-       msg_queue_tail(&glob_mgr->activatequeue, msg);
-       sem_post(&glob_mgr->new_msg);
-
-
-       return 0;
-}
-
-int misdn_lib_pid_restart(int pid)
-{
-       struct misdn_bchannel *bc=manager_find_bc_by_pid(pid);
-
-       if (bc) {
-               manager_clean_bc(bc);
-       }
-       return 0;
-}
-
-/*Sends Restart message for every bchannel*/
-int misdn_lib_send_restart(int port, int channel)
-{
-       struct misdn_stack *stack=find_stack_by_port(port);
-       struct misdn_bchannel dummybc;
-       /*default is all channels*/
-       cb_log(0, port, "Sending Restarts on this port.\n");
-
-       misdn_make_dummy(&dummybc, stack->port, MISDN_ID_GLOBAL, stack->nt, 0);
-
-       /*default is all channels*/
-       if (channel <0) {
-               dummybc.channel=-1;
-               cb_log(0, port, "Restarting and all Interfaces\n");
-               misdn_lib_send_event(&dummybc, EVENT_RESTART);
-
-               return 0;
-       }
-
-       /*if a channel is specified we restart only this one*/
-       if (channel >0) {
-               int cnt;
-               dummybc.channel=channel;
-               cb_log(0, port, "Restarting and cleaning channel %d\n",channel);
-               misdn_lib_send_event(&dummybc, EVENT_RESTART);
-               /* clean up chan in stack, to be sure we don't think it's
-                * in use anymore */
-               for (cnt=0; cnt<=stack->b_num; cnt++) {
-                       if (stack->bc[cnt].in_use && stack->bc[cnt].channel == channel) {
-                               empty_bc(&stack->bc[cnt]);
-                               clean_up_bc(&stack->bc[cnt]);
-                               stack->bc[cnt].in_use=0;
-                       }
-               }
-       }
-
-       return 0;
-}
-
-/*reinitializes the L2/L3*/
-int misdn_lib_port_restart(int port)
-{
-       struct misdn_stack *stack=find_stack_by_port(port);
-
-       cb_log(0, port, "Restarting this port.\n");
-       if (stack) {
-               cb_log(0, port, "Stack:%p\n",stack);
-
-               clear_l3(stack);
-               {
-                       msg_t *msg=alloc_msg(MAX_MSG_SIZE);
-                       iframe_t *frm;
-
-                       if (!msg) {
-                               cb_log(0, port, "port_restart: alloc_msg failed\n");
-                               return -1;
-                       }
-
-                       frm=(iframe_t*)msg->data;
-                       /* we must activate if we are deactivated */
-                       /* activate bchannel */
-                       frm->prim = DL_RELEASE | REQUEST;
-                       frm->addr = stack->upper_id | FLG_MSG_DOWN;
-
-                       frm->dinfo = 0;
-                       frm->len = 0;
-                       msg_queue_tail(&glob_mgr->activatequeue, msg);
-                       sem_post(&glob_mgr->new_msg);
-               }
-
-               if (stack->nt)
-                       misdn_lib_reinit_nt_stack(stack->port);
-
-       }
-
-       return 0;
-}
-
-
-
-static sem_t handler_started;
-
-/* This is a thread */
-static void manager_event_handler(void *arg)
-{
-       sem_post(&handler_started);
-       while (1) {
-               struct misdn_stack *stack;
-               msg_t *msg;
-
-               /** wait for events **/
-               sem_wait(&glob_mgr->new_msg);
-
-               for (msg=msg_dequeue(&glob_mgr->activatequeue);
-                    msg;
-                    msg=msg_dequeue(&glob_mgr->activatequeue)
-                       )
-               {
-
-                       iframe_t *frm =  (iframe_t*) msg->data ;
-
-                       switch ( frm->prim) {
-                       case MGR_SETSTACK | REQUEST :
-                               free_msg(msg);
-                               break;
-                       default:
-                               mISDN_write(glob_mgr->midev, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
-                               free_msg(msg);
-                       }
-               }
-
-               for (stack=glob_mgr->stack_list;
-                    stack;
-                    stack=stack->next ) {
-                       /* Here we should check if we really want to
-                               send all the messages we've queued, lets
-                               assume we've queued a Disconnect, but
-                               received it already from the other side!*/
-
-                       while ( (msg=msg_dequeue(&stack->downqueue)) ) {
-                               if (stack->nt ) {
-                                       pthread_mutex_lock(&stack->nstlock);
-                                       if (stack->nst.manager_l3(&stack->nst, msg))
-                                               cb_log(0, stack->port, "Error@ Sending Message in NT-Stack.\n");
-                                       pthread_mutex_unlock(&stack->nstlock);
-                               } else {
-                                       iframe_t *frm = (iframe_t *)msg->data;
-                                       struct misdn_bchannel *bc = find_bc_by_l3id(stack, frm->dinfo);
-                                       if (bc)
-                                               send_msg(glob_mgr->midev, bc, msg);
-                                       else  {
-                                               struct misdn_bchannel dummybc;
-
-                                               misdn_make_dummy(&dummybc, stack->port, frm->dinfo, stack->nt, 0);
-                                               if (frm->dinfo == MISDN_ID_GLOBAL || frm->dinfo == MISDN_ID_DUMMY ) {
-                                                       cb_log(5,0," --> GLOBAL/DUMMY\n");
-                                               } else {
-                                                       /*
-                                                        * We need to be able to at least answer with RELEASE_COMPLETE
-                                                        * on SETUP|INDICATION errors so use a dummy bc.
-                                                        */
-                                                       cb_log(0,0,"No bc for Message.  Using dummy_bc\n");
-                                               }
-                                               send_msg(glob_mgr->midev, &dummybc, msg);
-                                       }
-                               }
-                       }
-               }
-       }
-}
-
-
-int misdn_lib_maxports_get(void)
-{
-       /* BE AWARE WE HAVE NO cb_log() HERE! */
-
-       int i = mISDN_open();
-       int max=0;
-
-       if (i<0)
-               return -1;
-
-       max = mISDN_get_stack_count(i);
-
-       mISDN_close(i);
-
-       return max;
-}
-
-
-void misdn_lib_nt_keepcalls( int kc)
-{
-#ifdef FEATURE_NET_KEEPCALLS
-       if (kc) {
-               struct misdn_stack *stack=get_misdn_stack();
-               for ( ; stack; stack=stack->next) {
-                       stack->nst.feature |= FEATURE_NET_KEEPCALLS;
-               }
-       }
-#endif
-}
-
-void misdn_lib_nt_debug_init( int flags, char *file )
-{
-       static int init=0;
-       char *f;
-
-       if (!flags)
-               f=NULL;
-       else
-               f=file;
-
-       if (!init) {
-               debug_init( flags , f, f, f);
-               init=1;
-       } else {
-               debug_close();
-               debug_init( flags , f, f, f);
-       }
-}
-
-int misdn_lib_init(char *portlist, struct misdn_lib_iface *iface, void *user_data)
-{
-       struct misdn_lib *mgr;
-       char *tok, *tokb;
-       char plist[1024];
-       int midev;
-       int port_count=0;
-
-       cb_log = iface->cb_log;
-       cb_event = iface->cb_event;
-       cb_jb_empty = iface->cb_jb_empty;
-
-       if (!portlist || (*portlist == 0)) {
-               return 1;
-       }
-
-       mgr = calloc(1, sizeof(*mgr));
-       if (!mgr) {
-               return 1;
-       }
-       glob_mgr = mgr;
-
-       msg_init();
-
-       misdn_lib_nt_debug_init(0,NULL);
-
-       init_flip_bits();
-
-       strncpy(plist, portlist, 1024);
-       plist[1023] = 0;
-
-       memcpy(tone_425_flip,tone_425,TONE_425_SIZE);
-       flip_buf_bits(tone_425_flip,TONE_425_SIZE);
-
-       memcpy(tone_silence_flip,tone_SILENCE,TONE_SILENCE_SIZE);
-       flip_buf_bits(tone_silence_flip,TONE_SILENCE_SIZE);
-
-       midev=te_lib_init();
-       if (midev <= 0) {
-               free(glob_mgr);
-               glob_mgr = NULL;
-               return 1;
-       }
-       mgr->midev=midev;
-
-       port_count=mISDN_get_stack_count(midev);
-
-       msg_queue_init(&mgr->activatequeue);
-
-       if (sem_init(&mgr->new_msg, 1, 0)<0)
-               sem_init(&mgr->new_msg, 0, 0);
-
-       for (tok=strtok_r(plist," ,",&tokb );
-            tok;
-            tok=strtok_r(NULL," ,",&tokb)) {
-               int port = atoi(tok);
-               struct misdn_stack *stack;
-               struct misdn_stack *help;
-               int ptp=0;
-               int i;
-               int r;
-
-               if (strstr(tok, "ptp"))
-                       ptp=1;
-
-               if (port > port_count) {
-                       cb_log(0, port, "Couldn't Initialize this port since we have only %d ports\n", port_count);
-                       continue;
-               }
-
-               stack = stack_init(midev, port, ptp);
-               if (!stack) {
-                       cb_log(0, port, "stack_init() failed for this port\n");
-                       continue;
-               }
-
-               /* Initialize the B channel records for real B channels. */
-               for (i = 0; i <= stack->b_num; i++) {
-                       r = init_bc(stack, &stack->bc[i], stack->midev, port, i);
-                       if (r < 0) {
-                               cb_log(0, port, "Got Err @ init_bc :%d\n", r);
-                               break;
-                       }
-               }
-               if (i <= stack->b_num) {
-                       stack_destroy(stack);
-                       free(stack);
-                       continue;
-               }
-#if defined(AST_MISDN_ENHANCEMENTS)
-               /* Initialize the B channel records for REGISTER signaling links. */
-               for (i = MAX_BCHANS + 1; i < ARRAY_LEN(stack->bc); ++i) {
-                       r = init_bc(stack, &stack->bc[i], stack->midev, port, i);
-                       if (r < 0) {
-                               cb_log(0, port, "Got Err @ init_bc :%d\n", r);
-                               break;
-                       }
-                       stack->bc[i].is_register_pool = 1;
-               }
-               if (i < ARRAY_LEN(stack->bc)) {
-                       stack_destroy(stack);
-                       free(stack);
-                       continue;
-               }
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-               /* Add the new stack to the end of the list */
-               help = mgr->stack_list;
-               if (!help) {
-                       mgr->stack_list = stack;
-               } else {
-                       while (help->next) {
-                               help = help->next;
-                       }
-                       help->next = stack;
-               }
-       }
-
-       if (!mgr->stack_list) {
-               /* no stacks were successfully initialized !? */
-               te_lib_destroy(midev);
-               free(glob_mgr);
-               glob_mgr = NULL;
-               return 1;
-       }
-       if (sem_init(&handler_started, 1, 0)<0)
-               sem_init(&handler_started, 0, 0);
-
-       cb_log(8, 0, "Starting Event Handler\n");
-       pthread_create( &mgr->event_handler_thread, NULL,(void*)manager_event_handler, mgr);
-
-       sem_wait(&handler_started) ;
-       cb_log(8, 0, "Starting Event Catcher\n");
-       pthread_create( &mgr->event_thread, NULL, (void*)misdn_lib_isdn_event_catcher, mgr);
-
-       cb_log(8, 0, "Event Catcher started\n");
-
-       global_state= MISDN_INITIALIZED;
-
-       return (mgr == NULL);
-}
-
-void misdn_lib_destroy(void)
-{
-       struct misdn_stack *help;
-       int i;
-
-       for ( help=glob_mgr->stack_list; help; help=help->next ) {
-               for(i=0;i<=help->b_num; i++) {
-                       char buf[1024];
-                       mISDN_write_frame(help->midev, buf, help->bc[i].addr, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
-                       help->bc[i].addr = 0;
-               }
-               cb_log (1, help->port, "Destroying this port.\n");
-               stack_destroy(help);
-       }
-
-       if (global_state == MISDN_INITIALIZED) {
-               cb_log(4, 0, "Killing Handler Thread\n");
-               if ( pthread_cancel(glob_mgr->event_handler_thread) == 0 ) {
-                       cb_log(4, 0, "Joining Handler Thread\n");
-                       pthread_join(glob_mgr->event_handler_thread, NULL);
-               }
-
-               cb_log(4, 0, "Killing Main Thread\n");
-               if ( pthread_cancel(glob_mgr->event_thread) == 0 ) {
-                       cb_log(4, 0, "Joining Main Thread\n");
-                       pthread_join(glob_mgr->event_thread, NULL);
-               }
-       }
-
-       cb_log(1, 0, "Closing mISDN device\n");
-       te_lib_destroy(glob_mgr->midev);
-       while ((help = glob_mgr->stack_list)) {
-               glob_mgr->stack_list = help->next;
-               free(help);
-       }
-       free(glob_mgr);
-       glob_mgr = NULL;
-}
-
-char *manager_isdn_get_info(enum event_e event)
-{
-       return isdn_get_info(msgs_g , event, 0);
-}
-
-void manager_bchannel_activate(struct misdn_bchannel *bc)
-{
-       char buf[128];
-
-       struct misdn_stack *stack=get_stack_by_bc(bc);
-
-       if (!stack) {
-               cb_log(0, bc->port, "bchannel_activate: Stack not found !");
-               return ;
-       }
-
-       /* we must activate if we are deactivated */
-       clear_ibuffer(bc->astbuf);
-
-       cb_log(5, stack->port, "$$$ Bchan Activated addr %x\n", bc->addr);
-
-       mISDN_write_frame(stack->midev, buf, bc->addr | FLG_MSG_DOWN,  DL_ESTABLISH | REQUEST, 0,0, NULL, TIMEOUT_1SEC);
-
-       return ;
-}
-
-
-void manager_bchannel_deactivate(struct misdn_bchannel * bc)
-{
-       struct misdn_stack *stack=get_stack_by_bc(bc);
-       char buf[128];
-
-       switch (bc->bc_state) {
-               case BCHAN_ACTIVATED:
-                       break;
-               case BCHAN_BRIDGED:
-                       misdn_split_conf(bc,bc->conf_id);
-                       break;
-               default:
-                       cb_log( 4, bc->port,"bchan_deactivate: called but not activated\n");
-                       return ;
-
-       }
-
-       cb_log(5, stack->port, "$$$ Bchan deActivated addr %x\n", bc->addr);
-
-       bc->generate_tone=0;
-
-       mISDN_write_frame(stack->midev, buf, bc->addr | FLG_MSG_DOWN, DL_RELEASE|REQUEST,0,0,NULL, TIMEOUT_1SEC);
-
-       clear_ibuffer(bc->astbuf);
-
-       bc_state_change(bc,BCHAN_RELEASE);
-
-       return;
-}
-
-
-int misdn_lib_tx2misdn_frm(struct misdn_bchannel *bc, void *data, int len)
-{
-       struct misdn_stack *stack=get_stack_by_bc(bc);
-       char buf[4096 + mISDN_HEADER_LEN];
-       iframe_t *frm = (iframe_t*)buf;
-
-       switch (bc->bc_state) {
-               case BCHAN_ACTIVATED:
-               case BCHAN_BRIDGED:
-                       break;
-               default:
-                       cb_log(3, bc->port, "BC not yet activated (state:%s)\n",bc_state2str(bc->bc_state));
-                       return -1;
-       }
-
-       frm->prim = DL_DATA|REQUEST;
-       frm->dinfo = 0;
-       frm->addr = bc->addr | FLG_MSG_DOWN ;
-
-       frm->len = len;
-       memcpy(&buf[mISDN_HEADER_LEN], data,len);
-
-       if ( misdn_cap_is_speech(bc->capability) )
-               flip_buf_bits( &buf[mISDN_HEADER_LEN], len);
-       else
-               cb_log(6, stack->port, "Writing %d data bytes\n",len);
-
-       cb_log(9, stack->port, "Writing %d bytes 2 mISDN\n",len);
-       mISDN_write(stack->midev, buf, frm->len + mISDN_HEADER_LEN, TIMEOUT_INFINIT);
-       return 0;
-}
-
-
-
-/*
- * send control information to the channel (dsp-module)
- */
-void manager_ph_control(struct misdn_bchannel *bc, int c1, int c2)
-{
-       unsigned char buffer[mISDN_HEADER_LEN+2*sizeof(int)];
-       iframe_t *ctrl = (iframe_t *)buffer; /* preload data */
-       unsigned int *d = (unsigned int*)&ctrl->data.p;
-       /*struct misdn_stack *stack=get_stack_by_bc(bc);*/
-
-       cb_log(4,bc->port,"ph_control: c1:%x c2:%x\n",c1,c2);
-
-       ctrl->prim = PH_CONTROL | REQUEST;
-       ctrl->addr = bc->addr | FLG_MSG_DOWN;
-       ctrl->dinfo = 0;
-       ctrl->len = sizeof(unsigned int)*2;
-       *d++ = c1;
-       *d++ = c2;
-       mISDN_write(glob_mgr->midev, ctrl, mISDN_HEADER_LEN+ctrl->len, TIMEOUT_1SEC);
-}
-
-/*
- * allow live control of channel parameters
- */
-void isdn_lib_update_rxgain (struct misdn_bchannel *bc)
-{
-       manager_ph_control(bc, VOL_CHANGE_RX, bc->rxgain);
-}
-
-void isdn_lib_update_txgain (struct misdn_bchannel *bc)
-{
-       manager_ph_control(bc, VOL_CHANGE_TX, bc->txgain);
-}
-
-void isdn_lib_update_ec (struct misdn_bchannel *bc)
-{
-#ifdef MISDN_1_2
-       if (*bc->pipeline)
-#else
-       if (bc->ec_enable)
-#endif
-               manager_ec_enable(bc);
-       else
-               manager_ec_disable(bc);
-}
-
-void isdn_lib_stop_dtmf (struct misdn_bchannel *bc)
-{
-       manager_ph_control(bc, DTMF_TONE_STOP, 0);
-}
-
-/*
- * send control information to the channel (dsp-module)
- */
-void manager_ph_control_block(struct misdn_bchannel *bc, int c1, void *c2, int c2_len)
-{
-       unsigned char buffer[mISDN_HEADER_LEN+sizeof(int)+c2_len];
-       iframe_t *ctrl = (iframe_t *)buffer;
-       unsigned int *d = (unsigned int *)&ctrl->data.p;
-       /*struct misdn_stack *stack=get_stack_by_bc(bc);*/
-
-       ctrl->prim = PH_CONTROL | REQUEST;
-       ctrl->addr = bc->addr | FLG_MSG_DOWN;
-       ctrl->dinfo = 0;
-       ctrl->len = sizeof(unsigned int) + c2_len;
-       *d++ = c1;
-       memcpy(d, c2, c2_len);
-       mISDN_write(glob_mgr->midev, ctrl, mISDN_HEADER_LEN+ctrl->len, TIMEOUT_1SEC);
-}
-
-
-
-
-void manager_clean_bc(struct misdn_bchannel *bc )
-{
-       struct misdn_stack *stack=get_stack_by_bc(bc);
-
-       if (stack && bc->channel > 0) {
-               empty_chan_in_stack(stack, bc->channel);
-       }
-       empty_bc(bc);
-       bc->in_use=0;
-
-       cb_event(EVENT_CLEANUP, bc, NULL);
-}
-
-
-void stack_holder_add(struct misdn_stack *stack, struct misdn_bchannel *holder)
-{
-       struct misdn_bchannel *help;
-       cb_log(4,stack->port, "*HOLDER: add %x\n",holder->l3_id);
-
-       holder->stack_holder=1;
-       holder->next=NULL;
-
-       if (!stack->holding) {
-               stack->holding = holder;
-               return;
-       }
-
-       for (help=stack->holding;
-            help;
-            help=help->next) {
-               if (!help->next) {
-                       help->next=holder;
-                       break;
-               }
-       }
-
-}
-
-void stack_holder_remove(struct misdn_stack *stack, struct misdn_bchannel *holder)
-{
-       struct misdn_bchannel *h1;
-
-       if (!holder->stack_holder) return;
-
-       holder->stack_holder=0;
-
-       cb_log(4,stack->port, "*HOLDER: remove %x\n",holder->l3_id);
-       if (!stack || ! stack->holding) return;
-
-       if (holder == stack->holding) {
-               stack->holding = stack->holding->next;
-               return;
-       }
-
-       for (h1=stack->holding;
-            h1;
-            h1=h1->next) {
-               if (h1->next == holder) {
-                       h1->next=h1->next->next;
-                       return ;
-               }
-       }
-}
-
-struct misdn_bchannel *stack_holder_find(struct misdn_stack *stack, unsigned long l3id)
-{
-       struct misdn_bchannel *help;
-
-       cb_log(4, stack->port, "*HOLDER: find %lx\n",l3id);
-
-       for (help=stack->holding;
-            help;
-            help=help->next) {
-               if (help->l3_id == l3id) {
-                       cb_log(4,stack->port, "*HOLDER: found bc\n");
-                       return help;
-               }
-       }
-
-       cb_log(4,stack->port, "*HOLDER: find nothing\n");
-       return NULL;
-}
-
-/*!
- * \brief Find a held call's B channel record.
- *
- * \param port Port the call is on.
- * \param l3_id mISDN Layer 3 ID of held call.
- *
- * \return Found bc-record or NULL.
- */
-struct misdn_bchannel *misdn_lib_find_held_bc(int port, int l3_id)
-{
-       struct misdn_bchannel *bc;
-       struct misdn_stack *stack;
-
-       bc = NULL;
-       for (stack = get_misdn_stack(); stack; stack = stack->next) {
-               if (stack->port == port) {
-                       bc = stack_holder_find(stack, l3_id);
-                       break;
-               }
-       }
-
-       return bc;
-}
-
-void misdn_lib_send_tone(struct misdn_bchannel *bc, enum tone_e tone)
-{
-       char buf[mISDN_HEADER_LEN + 128] = "";
-       iframe_t *frm = (iframe_t*)buf;
-
-       switch(tone) {
-       case TONE_DIAL:
-               manager_ph_control(bc, TONE_PATT_ON, TONE_GERMAN_DIALTONE);
-       break;
-
-       case TONE_ALERTING:
-               manager_ph_control(bc, TONE_PATT_ON, TONE_GERMAN_RINGING);
-       break;
-
-       case TONE_HANGUP:
-               manager_ph_control(bc, TONE_PATT_ON, TONE_GERMAN_HANGUP);
-       break;
-
-       case TONE_NONE:
-       default:
-               manager_ph_control(bc, TONE_PATT_OFF, TONE_GERMAN_HANGUP);
-       }
-
-       frm->prim=DL_DATA|REQUEST;
-       frm->addr=bc->addr|FLG_MSG_DOWN;
-       frm->dinfo=0;
-       frm->len=128;
-
-       mISDN_write(glob_mgr->midev, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
-}
-
-
-void manager_ec_enable(struct misdn_bchannel *bc)
-{
-       struct misdn_stack *stack=get_stack_by_bc(bc);
-
-       cb_log(4, stack?stack->port:0,"ec_enable\n");
-
-       if (!misdn_cap_is_speech(bc->capability)) {
-               cb_log(1, stack?stack->port:0, " --> no speech? cannot enable EC\n");
-       } else {
-
-#ifdef MISDN_1_2
-       if (*bc->pipeline) {
-               cb_log(3, stack?stack->port:0,"Sending Control PIPELINE_CFG %s\n",bc->pipeline);
-               manager_ph_control_block(bc, PIPELINE_CFG, bc->pipeline, strlen(bc->pipeline) + 1);
-       }
-#else
-       int ec_arr[2];
-
-       if (bc->ec_enable) {
-               cb_log(3, stack?stack->port:0,"Sending Control ECHOCAN_ON taps:%d\n",bc->ec_deftaps);
-
-               switch (bc->ec_deftaps) {
-               case 4:
-               case 8:
-               case 16:
-               case 32:
-               case 64:
-               case 128:
-               case 256:
-               case 512:
-               case 1024:
-                       cb_log(4, stack->port, "Taps is %d\n",bc->ec_deftaps);
-                       break;
-               default:
-                       cb_log(0, stack->port, "Taps should be power of 2\n");
-                       bc->ec_deftaps=128;
-               }
-
-               ec_arr[0]=bc->ec_deftaps;
-               ec_arr[1]=0;
-
-               manager_ph_control_block(bc,  ECHOCAN_ON,  ec_arr, sizeof(ec_arr));
-       }
-#endif
-       }
-}
-
-
-
-void manager_ec_disable(struct misdn_bchannel *bc)
-{
-       struct misdn_stack *stack=get_stack_by_bc(bc);
-
-       cb_log(4, stack?stack->port:0," --> ec_disable\n");
-
-       if (!misdn_cap_is_speech(bc->capability)) {
-               cb_log(1, stack?stack->port:0, " --> no speech? cannot disable EC\n");
-               return;
-       }
-
-#ifdef MISDN_1_2
-       manager_ph_control_block(bc, PIPELINE_CFG, "", 0);
-#else
-       if ( ! bc->ec_enable) {
-               cb_log(3, stack?stack->port:0, "Sending Control ECHOCAN_OFF\n");
-               manager_ph_control(bc,  ECHOCAN_OFF, 0);
-       }
-#endif
-}
-
-struct misdn_stack *get_misdn_stack(void)
-{
-       return glob_mgr->stack_list;
-}
-
-
-
-void misdn_join_conf(struct misdn_bchannel *bc, int conf_id)
-{
-       char data[16] = "";
-
-       bc_state_change(bc,BCHAN_BRIDGED);
-       manager_ph_control(bc, CMX_RECEIVE_OFF, 0);
-       manager_ph_control(bc, CMX_CONF_JOIN, conf_id);
-
-       cb_log(3,bc->port, "Joining bc:%x in conf:%d\n",bc->addr,conf_id);
-
-       misdn_lib_tx2misdn_frm(bc, data, sizeof(data) - 1);
-}
-
-
-void misdn_split_conf(struct misdn_bchannel *bc, int conf_id)
-{
-       bc_state_change(bc,BCHAN_ACTIVATED);
-       manager_ph_control(bc, CMX_RECEIVE_ON, 0);
-       manager_ph_control(bc, CMX_CONF_SPLIT, conf_id);
-
-       cb_log(4,bc->port, "Splitting bc:%x in conf:%d\n",bc->addr,conf_id);
-}
-
-void misdn_lib_bridge( struct misdn_bchannel * bc1, struct misdn_bchannel *bc2)
-{
-       int conf_id = bc1->pid + 1;
-       struct misdn_bchannel *bc_list[] = { bc1, bc2, NULL };
-       struct misdn_bchannel **bc;
-
-       cb_log(4, bc1->port, "I Send: BRIDGE from:%d to:%d\n",bc1->port,bc2->port);
-
-       for (bc=bc_list; *bc;  bc++) {
-               (*bc)->conf_id=conf_id;
-               cb_log(4, (*bc)->port, " --> bc_addr:%x\n",(*bc)->addr);
-
-               switch((*bc)->bc_state) {
-                       case BCHAN_ACTIVATED:
-                               misdn_join_conf(*bc,conf_id);
-                               break;
-                       default:
-                               bc_next_state_change(*bc,BCHAN_BRIDGED);
-                               break;
-               }
-       }
-}
-
-void misdn_lib_split_bridge( struct misdn_bchannel * bc1, struct misdn_bchannel *bc2)
-{
-
-       struct misdn_bchannel *bc_list[]={
-               bc1,bc2,NULL
-       };
-       struct misdn_bchannel **bc;
-
-       for (bc=bc_list; *bc;  bc++) {
-               if ( (*bc)->bc_state == BCHAN_BRIDGED){
-                       misdn_split_conf( *bc, (*bc)->conf_id);
-               } else {
-                       cb_log( 2, (*bc)->port, "BC not bridged (state:%s) so not splitting it\n",bc_state2str((*bc)->bc_state));
-               }
-       }
-
-}
-
-
-
-void misdn_lib_echo(struct misdn_bchannel *bc, int onoff)
-{
-       cb_log(3,bc->port, " --> ECHO %s\n", onoff?"ON":"OFF");
-       manager_ph_control(bc, onoff?CMX_ECHO_ON:CMX_ECHO_OFF, 0);
-}
-
-
-
-void misdn_lib_reinit_nt_stack(int port)
-{
-       struct misdn_stack *stack=find_stack_by_port(port);
-
-       if (stack) {
-               stack->l2link=0;
-               stack->blocked=0;
-
-               cleanup_Isdnl3(&stack->nst);
-               cleanup_Isdnl2(&stack->nst);
-
-
-               memset(&stack->nst, 0, sizeof(net_stack_t));
-               memset(&stack->mgr, 0, sizeof(manager_t));
-
-               stack->mgr.nst = &stack->nst;
-               stack->nst.manager = &stack->mgr;
-
-               stack->nst.l3_manager = handle_event_nt;
-               stack->nst.device = glob_mgr->midev;
-               stack->nst.cardnr = port;
-               stack->nst.d_stid = stack->d_stid;
-
-               stack->nst.feature = FEATURE_NET_HOLD;
-               if (stack->ptp)
-                       stack->nst.feature |= FEATURE_NET_PTP;
-               if (stack->pri)
-                       stack->nst.feature |= FEATURE_NET_CRLEN2 | FEATURE_NET_EXTCID;
-
-               stack->nst.l1_id = stack->lower_id; /* never used */
-               stack->nst.l2_id = stack->upper_id;
-
-               msg_queue_init(&stack->nst.down_queue);
-
-               Isdnl2Init(&stack->nst);
-               Isdnl3Init(&stack->nst);
-
-               if (!stack->ptp)
-                       misdn_lib_get_l1_up(stack);
-       }
-}
diff --git a/channels/misdn/isdn_lib.h b/channels/misdn/isdn_lib.h
deleted file mode 100644 (file)
index 62e80d6..0000000
+++ /dev/null
@@ -1,833 +0,0 @@
-/*
- * Chan_Misdn -- Channel Driver for Asterisk
- *
- * Interface to mISDN
- *
- * Copyright (C) 2004, Christian Richter
- *
- * Christian Richter <crich@beronet.com>
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License
- */
-
-/*! \file
- * \brief Interface to mISDN
- *
- * \author Christian Richter <crich@beronet.com>
- */
-
-#ifndef TE_LIB
-#define TE_LIB
-
-#include <mISDNuser/suppserv.h>
-
-/** For initialization usage **/
-/* typedef int ie_nothing_t ;*/
-/** end of init usage **/
-
-
-/*
- * uncomment the following to make chan_misdn create
- * record files in /tmp/misdn-{rx|tx}-PortChannel format
- * */
-
-/*#define MISDN_SAVE_DATA*/
-
-#ifdef WITH_BEROEC
-typedef int beroec_t;
-
-
-enum beroec_type {
-       BEROEC_FULLBAND=0,
-       BEROEC_SUBBAND,
-       BEROEC_FASTSUBBAND
-};
-
-void beroec_init(void);
-void beroec_exit(void);
-beroec_t *beroec_new(int tail, enum beroec_type type, int anti_howl,
-                    int tonedisable, int zerocoeff, int adapt, int nlp);
-
-void beroec_destroy(beroec_t *ec);
-int beroec_cancel_alaw_chunk(beroec_t *ec,
-       char *send,
-       char *receive,
-       int len);
-
-int beroec_version(void);
-#endif
-
-
-
-enum tone_e {
-       TONE_NONE=0,
-       TONE_DIAL,
-       TONE_ALERTING,
-       TONE_FAR_ALERTING,
-       TONE_BUSY,
-       TONE_HANGUP,
-       TONE_CUSTOM,
-       TONE_FILE
-};
-
-
-
-#define MAX_BCHANS 31
-
-enum bchannel_state {
-       BCHAN_CLEANED=0,
-       BCHAN_EMPTY,
-       BCHAN_ACTIVATED,
-       BCHAN_BRIDGED,
-       BCHAN_RELEASE,
-       BCHAN_ERROR
-};
-
-
-enum misdn_err_e {
-       ENOCHAN=1
-};
-
-enum mISDN_NUMBER_PLAN {
-       NUMPLAN_UNKNOWN = 0x0,
-       NUMPLAN_ISDN = 0x1,             /* ISDN/Telephony numbering plan E.164 */
-       NUMPLAN_DATA = 0x3,             /* Data numbering plan X.121 */
-       NUMPLAN_TELEX = 0x4,    /* Telex numbering plan F.69 */
-       NUMPLAN_NATIONAL = 0x8,
-       NUMPLAN_PRIVATE = 0x9
-};
-
-enum mISDN_NUMBER_TYPE {
-       NUMTYPE_UNKNOWN = 0x0,
-       NUMTYPE_INTERNATIONAL = 0x1,
-       NUMTYPE_NATIONAL = 0x2,
-       NUMTYPE_NETWORK_SPECIFIC = 0x3,
-       NUMTYPE_SUBSCRIBER = 0x4,
-       NUMTYPE_ABBREVIATED = 0x5
-};
-
-enum event_response_e {
-       RESPONSE_IGNORE_SETUP_WITHOUT_CLOSE,
-       RESPONSE_IGNORE_SETUP,
-       RESPONSE_RELEASE_SETUP,
-       RESPONSE_ERR,
-       RESPONSE_OK
-};
-
-
-enum event_e {
-       EVENT_NOTHING,
-       EVENT_TONE_GENERATE,
-       EVENT_BCHAN_DATA,
-       EVENT_BCHAN_ACTIVATED,
-       EVENT_BCHAN_ERROR,
-       EVENT_CLEANUP,
-       EVENT_PROCEEDING,
-       EVENT_PROGRESS,
-       EVENT_SETUP,
-       EVENT_REGISTER,
-       EVENT_ALERTING,
-       EVENT_CONNECT,
-       EVENT_SETUP_ACKNOWLEDGE,
-       EVENT_CONNECT_ACKNOWLEDGE ,
-       EVENT_USER_INFORMATION,
-       EVENT_SUSPEND_REJECT,
-       EVENT_RESUME_REJECT,
-       EVENT_HOLD,
-       EVENT_SUSPEND,
-       EVENT_RESUME,
-       EVENT_HOLD_ACKNOWLEDGE,
-       EVENT_SUSPEND_ACKNOWLEDGE,
-       EVENT_RESUME_ACKNOWLEDGE,
-       EVENT_HOLD_REJECT,
-       EVENT_RETRIEVE,
-       EVENT_RETRIEVE_ACKNOWLEDGE,
-       EVENT_RETRIEVE_REJECT,
-       EVENT_DISCONNECT,
-       EVENT_RESTART,
-       EVENT_RELEASE,
-       EVENT_RELEASE_COMPLETE,
-       EVENT_FACILITY,
-       EVENT_NOTIFY,
-       EVENT_STATUS_ENQUIRY,
-       EVENT_INFORMATION,
-       EVENT_STATUS,
-       EVENT_TIMEOUT,
-       EVENT_DTMF_TONE,
-       EVENT_NEW_L3ID,
-       EVENT_NEW_BC,
-       EVENT_PORT_ALARM,
-       EVENT_NEW_CHANNEL,
-       EVENT_UNKNOWN
-};
-
-
-enum ie_name_e {
-       IE_DUMMY,
-       IE_LAST
-};
-
-enum { /* bearer capability */
-       INFO_CAPABILITY_SPEECH=0,
-       INFO_CAPABILITY_AUDIO_3_1K=0x10 ,
-       INFO_CAPABILITY_AUDIO_7K=0x11 ,
-       INFO_CAPABILITY_VIDEO =0x18,
-       INFO_CAPABILITY_DIGITAL_UNRESTRICTED =0x8,
-       INFO_CAPABILITY_DIGITAL_RESTRICTED =0x09,
-       INFO_CAPABILITY_DIGITAL_UNRESTRICTED_TONES
-};
-
-enum { /* progress indicators */
-       INFO_PI_CALL_NOT_E2E_ISDN =0x01,
-       INFO_PI_CALLED_NOT_ISDN =0x02,
-       INFO_PI_CALLER_NOT_ISDN =0x03,
-       INFO_PI_CALLER_RETURNED_TO_ISDN =0x04,
-       INFO_PI_INBAND_AVAILABLE =0x08,
-       INFO_PI_DELAY_AT_INTERF =0x0a,
-       INFO_PI_INTERWORKING_WITH_PUBLIC =0x10,
-       INFO_PI_INTERWORKING_NO_RELEASE =0x11,
-       INFO_PI_INTERWORKING_NO_RELEASE_PRE_ANSWER =0x12,
-       INFO_PI_INTERWORKING_NO_RELEASE_POST_ANSWER =0x13
-};
-
-/*!
- * \brief Q.931 encoded redirecting reason
- */
-enum mISDN_REDIRECTING_REASON {
-       mISDN_REDIRECTING_REASON_UNKNOWN = 0x0,
-       /*! Call forwarding busy or called DTE busy */
-       mISDN_REDIRECTING_REASON_CALL_FWD_BUSY = 0x1,
-       /*! Call forwarding no reply */
-       mISDN_REDIRECTING_REASON_NO_REPLY = 0x2,
-       /*! Call deflection */
-       mISDN_REDIRECTING_REASON_DEFLECTION = 0x4,
-       /*! Called DTE out of order */
-       mISDN_REDIRECTING_REASON_OUT_OF_ORDER = 0x9,
-       /*! Call forwarding by the called DTE */
-       mISDN_REDIRECTING_REASON_CALL_FWD_DTE = 0xA,
-       /*! Call forwarding unconditional or systematic call redirection */
-       mISDN_REDIRECTING_REASON_CALL_FWD = 0xF
-};
-
-/*!
- * \brief Notification description code enumeration
- */
-enum mISDN_NOTIFY_CODE {
-       mISDN_NOTIFY_CODE_INVALID = -1,
-       /*! Call is placed on hold (Q.931) */
-       mISDN_NOTIFY_CODE_USER_SUSPEND = 0x00,
-       /*! Call is taken off of hold (Q.931) */
-       mISDN_NOTIFY_CODE_USER_RESUME = 0x01,
-       /*! Call is diverting (EN 300 207-1 Section 7.2.1) */
-       mISDN_NOTIFY_CODE_CALL_IS_DIVERTING = 0x7B,
-       /*! Call diversion is enabled (cfu, cfb, cfnr) (EN 300 207-1 Section 7.2.1) */
-       mISDN_NOTIFY_CODE_DIVERSION_ACTIVATED = 0x68,
-       /*! Call transfer, alerting (EN 300 369-1 Section 7.2) */
-       mISDN_NOTIFY_CODE_CALL_TRANSFER_ALERTING = 0x69,
-       /*! Call transfer, active(answered) (EN 300 369-1 Section 7.2) */
-       mISDN_NOTIFY_CODE_CALL_TRANSFER_ACTIVE = 0x6A,
-};
-
-enum { /*CODECS*/
-       INFO_CODEC_ULAW=2,
-       INFO_CODEC_ALAW=3
-};
-
-
-enum layer_e {
-       L3,
-       L2,
-       L1,
-       UNKNOWN
-};
-
-/*! Maximum phone number (address) length plus null terminator */
-#define MISDN_MAX_NUMBER_LEN           (31 + 1)
-
-/*! Maximum name length plus null terminator (From ECMA-164) */
-#define MISDN_MAX_NAME_LEN                     (50 + 1)
-
-/*! Maximum subaddress length plus null terminator */
-#define MISDN_MAX_SUBADDRESS_LEN       (23 + 1)
-
-/*! Maximum keypad facility content length plus null terminator */
-#define MISDN_MAX_KEYPAD_LEN           (31 + 1)
-
-/*! \brief Dialed/Called information struct */
-struct misdn_party_dialing {
-       /*! \brief Type-of-number in ISDN terms for the dialed/called number */
-       enum mISDN_NUMBER_TYPE number_type;
-
-       /*! \brief Type-of-number numbering plan. */
-       enum mISDN_NUMBER_PLAN number_plan;
-
-       /*! \brief Dialed/Called Phone Number (Address) */
-       char number[MISDN_MAX_NUMBER_LEN];
-
-       /*! \brief Dialed/Called Subaddress number */
-       char subaddress[MISDN_MAX_SUBADDRESS_LEN];
-};
-
-/*! \brief Connected-Line/Calling/Redirecting ID info struct */
-struct misdn_party_id {
-       /*! \brief Number presentation restriction code
-        * 0=Allowed, 1=Restricted, 2=Unavailable
-        */
-       int presentation;
-
-       /*! \brief Number screening code
-        * 0=Unscreened, 1=Passed Screen, 2=Failed Screen, 3=Network Number
-        */
-       int screening;
-
-       /*! \brief Type-of-number in ISDN terms for the number */
-       enum mISDN_NUMBER_TYPE number_type;
-
-       /*! \brief Type-of-number numbering plan. */
-       enum mISDN_NUMBER_PLAN number_plan;
-
-       /*! \brief Subscriber Name
-        * \note The name is currently obtained from Asterisk for
-        * potential use in display ie's since basic ISDN does
-        * not support names directly.
-        */
-       char name[MISDN_MAX_NAME_LEN];
-
-       /*! \brief Phone number (Address) */
-       char number[MISDN_MAX_NUMBER_LEN];
-
-       /*! \brief Subaddress number */
-       char subaddress[MISDN_MAX_SUBADDRESS_LEN];
-};
-
-/*! \brief Redirecting information struct */
-struct misdn_party_redirecting {
-       /*! \brief Who is redirecting the call (Sent to the party the call is redirected toward) */
-       struct misdn_party_id from;
-
-       /*! \brief Where the call is being redirected toward (Sent to the calling party) */
-       struct misdn_party_id to;
-
-       /*! \brief Reason a call is being redirected (Q.931 field value) */
-       enum mISDN_REDIRECTING_REASON reason;
-
-       /*! \brief Number of times the call has been redirected */
-       int count;
-
-       /*! \brief TRUE if the redirecting.to information has changed */
-       int to_changed;
-};
-
-
-/*! \brief B channel control structure */
-struct misdn_bchannel {
-       /*! \brief B channel send locking structure */
-       struct send_lock *send_lock;
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-       /*! \brief The BC, HLC (optional) and LLC (optional) contents from the SETUP message. */
-       struct Q931_Bc_Hlc_Llc setup_bc_hlc_llc;
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-       /*!
-        * \brief Dialed/Called information struct
-        * \note The number_type element is set to "dialplan" in /etc/asterisk/misdn.conf for outgoing calls
-        */
-       struct misdn_party_dialing dialed;
-
-       /*! \brief Originating/Caller ID information struct
-        * \note The number_type element can be set to "localdialplan" in /etc/asterisk/misdn.conf for outgoing calls
-        * \note The number element can be set to "callerid" in /etc/asterisk/misdn.conf for outgoing calls
-        */
-       struct misdn_party_id caller;
-
-       /*! \brief  Incoming Caller ID string tag for special purpose
-        * \note The element can be set to "incoming_cid_tag" in /etc/asterisk/misdn.conf for incoming calls
-        */
-       char incoming_cid_tag[MISDN_MAX_NAME_LEN];
-
-       /*! \brief Connected-Party/Connected-Line ID information struct
-        * \note The number_type element can be set to "cpndialplan" in /etc/asterisk/misdn.conf for outgoing calls
-        */
-       struct misdn_party_id connected;
-
-       /*! \brief Redirecting information struct (Where a call diversion or transfer was invoked)
-        * \note The redirecting subaddress is not defined in Q.931 so it is not used.
-        */
-       struct misdn_party_redirecting redirecting;
-
-       /*! \brief TRUE if this is a dummy BC record */
-       int dummy;
-
-       /*! \brief TRUE if NT side of protocol (TE otherwise) */
-       int nt;
-
-       /*! \brief TRUE if ISDN-PRI (ISDN-BRI otherwise) */
-       int pri;
-
-       /*! \brief Logical Layer 1 port associated with this B channel */
-       int port;
-
-       /** init stuff **/
-       /*! \brief B Channel mISDN driver stack ID */
-       int b_stid;
-
-       /* int b_addr; */
-
-       /*! \brief B Channel mISDN driver layer ID from mISDN_new_layer() */
-       int layer_id;
-
-       /*! \brief B channel layer; set to 3 or 4 */
-       int layer;
-
-       /* state stuff */
-       /*! \brief TRUE if DISCONNECT needs to be sent to clear a call */
-       int need_disconnect;
-
-       /*! \brief TRUE if RELEASE needs to be sent to clear a call */
-       int need_release;
-
-       /*! \brief TRUE if RELEASE_COMPLETE needs to be sent to clear a call */
-       int need_release_complete;
-
-       /*! \brief TRUE if allocate higher B channels first */
-       int dec;
-
-       /* var stuff */
-       /*! \brief Layer 3 process ID */
-       int l3_id;
-
-       /*! \brief B channel process ID (1-5000) */
-       int pid;
-
-       /*! \brief Not used. Saved mISDN stack CONNECT_t ces value */
-       int ces;
-
-       /*! \brief B channel to restart if received a RESTART message */
-       int restart_channel;
-
-       /*! \brief Assigned B channel number B1, B2... 0 if not assigned */
-       int channel;
-
-       /*! \brief TRUE if the B channel number is preselected */
-       int channel_preselected;
-
-       /*! \brief TRUE if the B channel is allocated from the REGISTER pool */
-       int is_register_pool;
-
-       /*! \brief TRUE if B channel record is in use */
-       int in_use;
-
-       /*! \brief Time when empty_bc() last called on this record */
-       struct timeval last_used;
-
-       /*! \brief TRUE if call waiting */
-       int cw;
-
-       /*! \brief B Channel mISDN driver layer ID from mISDN_get_layerid() */
-       int addr;
-
-       /*! \brief B channel speech sample data buffer */
-       char *bframe;
-
-       /*! \brief B channel speech sample data buffer size */
-       int bframe_len;
-       int time_usec;  /* Not used */
-
-       /*! \brief Not used. Contents are setup but not used. */
-       void *astbuf;
-
-       /*! \brief TRUE if the TE side should choose the B channel to use
-        * \note This value is user configurable in /etc/asterisk/misdn.conf
-        */
-       int te_choose_channel;
-
-       /*! \brief TRUE if the call progress indicators can indicate an inband audio message for the user to listen to
-        * \note This value is user configurable in /etc/asterisk/misdn.conf
-        */
-       int early_bconnect;
-
-       /*! \brief Last decoded DTMF digit from mISDN driver */
-       int dtmf;
-
-       /*! \brief TRUE if we should produce DTMF tones ourselves
-        * \note This value is user configurable in /etc/asterisk/misdn.conf
-        */
-       int send_dtmf;
-
-       /*! \brief TRUE if we send SETUP_ACKNOWLEDGE on incoming calls anyway (instead of PROCEEDING).
-        *
-        * This requests additional INFORMATION messages, so we can
-        * wait for digits without issues.
-        * \note This value is user configurable in /etc/asterisk/misdn.conf
-        */
-       int need_more_infos;
-
-       /*! \brief TRUE if all digits necessary to complete the call are available.
-        * No more INFORMATION messages are needed.
-        */
-       int sending_complete;
-
-
-       /*! \brief TRUE if we will not use jollys dsp */
-       int nodsp;
-
-       /*! \brief TRUE if we will not use the jitter buffer system */
-       int nojitter;
-
-       /*! \brief Progress Indicator IE coding standard field.
-        * \note Collected from the incoming messages but not used.
-        */
-       int progress_coding;
-
-       /*! \brief Progress Indicator IE location field.
-        * \note Collected from the incoming messages but not used.
-        */
-       int progress_location;
-
-       /*! \brief Progress Indicator IE progress description field.
-        * Used to determine if there is an inband audio message present.
-        */
-       int progress_indicator;
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-       /*!
-        * \brief TRUE if waiting for DivertingLegInformation3 to queue redirecting update.
-        */
-       int div_leg_3_rx_wanted;
-
-       /*!
-        * \brief TRUE if a DivertingLegInformation3 needs to be sent with CONNECT.
-        */
-       int div_leg_3_tx_pending;
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-       /*! \brief Inbound FACILITY message function type and contents */
-       struct FacParm fac_in;
-
-       /*! \brief Outbound FACILITY message function type and contents.
-        * \note Filled in by misdn facility commands before FACILITY message sent.
-        */
-       struct FacParm fac_out;
-
-       /* storing the current AOCD info here */
-       enum FacFunction AOCDtype;
-       union {
-               struct FacAOCDCurrency currency;
-               struct FacAOCDChargingUnit chargingUnit;
-       } AOCD;
-       /*! \brief TRUE if AOCDtype and AOCD data are ready to export to Asterisk */
-       int AOCD_need_export;
-
-       /*** CRYPTING STUFF ***/
-       int crypt;              /* Initialized, Not used */
-       int curprx;             /* Initialized, Not used */
-       int curptx;             /* Initialized, Not used */
-
-       /*! \brief Blowfish encryption key string (secret) */
-       char crypt_key[255];
-
-       int crypt_state;        /* Not used */
-       /*** CRYPTING STUFF END***/
-
-       /*! \brief Seems to have been intended for something to do with the jitter buffer.
-        * \note Used as a boolean.  Only initialized to 0 and referenced in a couple places
-        */
-       int active;
-       int upset;      /* Not used */
-
-       /*! \brief TRUE if tone generator allowed to start */
-       int generate_tone;
-
-       /*! \brief Number of tone samples to generate */
-       int tone_cnt;
-
-       /*! \brief Current B Channel state */
-       enum bchannel_state bc_state;
-
-       /*! \brief This is used as a pending bridge join request for when bc_state becomes BCHAN_ACTIVATED */
-       enum bchannel_state next_bc_state;
-
-       /*! \brief Bridging conference ID */
-       int conf_id;
-
-       /*! \brief TRUE if this channel is on hold */
-       int holded;
-
-       /*! \brief TRUE if this channel is on the misdn_stack->holding list
-        * \note If TRUE this implies that the structure is also malloced.
-        */
-       int stack_holder;
-
-       /*!
-        * \brief Put a display ie in the CONNECT message
-        * \details
-        * Put a display ie in the CONNECT message containing the following
-        * information if it is available (nt port only):
-        * 0 - Do not put the connected line information in the display ie.
-        * 1 - Put the available connected line name in the display ie.
-        * 2 - Put the available connected line number in the display ie.
-        * 3 - Put the available connected line name and number in the display ie.
-        */
-       int display_connected;
-
-       /*!
-        * \brief Put a display ie in the SETUP message
-        * \details
-        * Put a display ie in the SETUP message containing the following
-        * information if it is available (nt port only):
-        * 0 - Do not put the caller information in the display ie.
-        * 1 - Put the available caller name in the display ie.
-        * 2 - Put the available caller number in the display ie.
-        * 3 - Put the available caller name and number in the display ie.
-        */
-       int display_setup;
-
-       /*!
-        * \brief Select what to do with outgoing COLP information.
-        * \details
-        * 0 - pass (Send out COLP information unaltered.)
-        * 1 - restricted (Force COLP to restricted on all outgoing COLP information.)
-        * 2 - block (Do not send COLP information.)
-        */
-       int outgoing_colp;
-
-       /*! \brief User set presentation restriction code
-        * 0=Allowed, 1=Restricted, 2=Unavailable
-        * \note It is settable by the misdn_set_opt() application.
-        */
-       int presentation;
-
-       /*! \brief TRUE if the user set the presentation restriction code */
-       int set_presentation;
-
-       /*! \brief Notification indicator ie description code */
-       enum mISDN_NOTIFY_CODE notify_description_code;
-
-       /*! \brief SETUP message bearer capability field code value */
-       int capability;
-
-       /*! \brief Companding ALaw/uLaw encoding (INFO_CODEC_ALAW / INFO_CODEC_ULAW) */
-       int law;
-
-       /* V110 Stuff */
-       /*! \brief Q.931 Bearer Capability IE Information Transfer Rate field. Initialized to 0x10 (64kbit). Altered by incoming SETUP messages. */
-       int rate;
-
-       /*! \brief Q.931 Bearer Capability IE Transfer Mode field. Initialized to 0 (Circuit). Altered by incoming SETUP messages. */
-       int mode;
-
-       /*! \brief Q.931 Bearer Capability IE User Information Layer 1 Protocol field code.
-        * \note Collected from the incoming SETUP message but not used.
-        */
-       int user1;
-
-       /*! \brief Q.931 Bearer Capability IE Layer 1 User Rate field.
-        * \note Collected from the incoming SETUP message and exported to Asterisk variable MISDN_URATE.
-        */
-       int urate;
-
-       /*! \brief TRUE if call made in digital HDLC mode
-        * \note This value is user configurable in /etc/asterisk/misdn.conf.
-        * It is also settable by the misdn_set_opt() application.
-        */
-       int hdlc;
-       /* V110 */
-
-       /*! \brief Display message that can be displayed by the user phone.
-        * \note Maximum displayable length is 34 or 82 octets.
-        * It is also settable by the misdn_set_opt() application.
-        */
-       char display[84];
-
-       /*! \brief Q.931 Keypad Facility IE contents
-        * \note Contents exported and imported to Asterisk variable MISDN_KEYPAD
-        */
-       char keypad[MISDN_MAX_KEYPAD_LEN];
-
-       /*! \brief Current overlap dialing digits to/from INFORMATION messages */
-       char info_dad[MISDN_MAX_NUMBER_LEN];
-
-       /*! \brief Collected digits to go into info_dad[] while waiting for a SETUP_ACKNOWLEDGE to come in. */
-       char infos_pending[MISDN_MAX_NUMBER_LEN];
-
-/*     unsigned char info_keypad[MISDN_MAX_KEYPAD_LEN]; */
-/*     unsigned char clisub[24]; */
-/*     unsigned char cldsub[24]; */
-
-       /*! \brief User-User information string.
-        * \note Contents exported and imported to Asterisk variable MISDN_USERUSER
-        * \note We only support ASCII strings (IA5 characters).
-        */
-       char uu[256];
-
-       /*! \brief User-User information string length in uu[] */
-       int uulen;
-
-       /*! \brief Q.931 Cause for disconnection code (received)
-        * \note Need to use the AST_CAUSE_xxx code definitions in causes.h
-        */
-       int cause;
-
-       /*! \brief Q.931 Cause for disconnection code (sent)
-        * \note Need to use the AST_CAUSE_xxx code definitions in causes.h
-        * \note -1 is used to suppress including the cause code in the RELEASE message.
-        */
-       int out_cause;
-
-       /* struct misdn_bchannel hold_bc; */
-
-       /** list stuf **/
-
-#ifdef MISDN_1_2
-       /*! \brief The configuration string for the mISDN dsp pipeline in /etc/asterisk/misdn.conf. */
-       char pipeline[128];
-#else
-       /*! \brief TRUE if the echo cancellor is enabled */
-       int ec_enable;
-
-       /*! \brief Number of taps in the echo cancellor when enabled.
-        * \note This value is user configurable in /etc/asterisk/misdn.conf (echocancel)
-        */
-       int ec_deftaps;
-#endif
-
-       /*! \brief TRUE if the channel was allocated from the available B channels */
-       int channel_found;
-
-       /*! \brief Who originated the call (ORG_AST, ORG_MISDN)
-        * \note Set but not used when the misdn_set_opt() application enables echo cancellation.
-        */
-       int orig;
-
-       /*! \brief Tx gain setting (range -8 to 8)
-        * \note This value is user configurable in /etc/asterisk/misdn.conf.
-        * It is also settable by the misdn_set_opt() application.
-        */
-       int txgain;
-
-       /*! \brief Rx gain setting (range -8 to 8)
-        * \note This value is user configurable in /etc/asterisk/misdn.conf.
-        * It is also settable by the misdn_set_opt() application.
-        */
-       int rxgain;
-
-       /*! \brief Next node in the misdn_stack.holding list */
-       struct misdn_bchannel *next;
-};
-
-
-extern enum event_response_e (*cb_event) (enum event_e event, struct misdn_bchannel *bc, void *user_data);
-
-extern void (*cb_log) (int level, int port, char *tmpl, ...)
-       __attribute__ ((format (printf, 3, 4)));
-
-extern int (*cb_jb_empty)(struct misdn_bchannel *bc, char *buffer, int len);
-
-struct misdn_lib_iface {
-       enum event_response_e (*cb_event)(enum event_e event, struct misdn_bchannel *bc, void *user_data);
-       void (*cb_log)(int level, int port, char *tmpl, ...)
-               __attribute__ ((format (printf, 3, 4)));
-       int (*cb_jb_empty)(struct misdn_bchannel *bc, char *buffer, int len);
-};
-
-/***** USER IFACE **********/
-
-void misdn_lib_nt_keepcalls(int kc);
-
-void misdn_lib_nt_debug_init( int flags, char *file );
-
-int misdn_lib_init(char *portlist, struct misdn_lib_iface* iface, void *user_data);
-int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event );
-void misdn_lib_destroy(void);
-
-void misdn_lib_isdn_l1watcher(int port);
-
-void misdn_lib_log_ies(struct misdn_bchannel *bc);
-
-char *manager_isdn_get_info(enum event_e event);
-
-struct misdn_bchannel* misdn_lib_get_free_bc(int port, int channel, int inout, int dec);
-#if defined(AST_MISDN_ENHANCEMENTS)
-struct misdn_bchannel *misdn_lib_get_register_bc(int port);
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-void manager_bchannel_activate(struct misdn_bchannel *bc);
-void manager_bchannel_deactivate(struct misdn_bchannel * bc);
-
-int misdn_lib_tx2misdn_frm(struct misdn_bchannel *bc, void *data, int len);
-
-void manager_ph_control(struct misdn_bchannel *bc, int c1, int c2);
-
-void isdn_lib_update_rxgain (struct misdn_bchannel *bc);
-void isdn_lib_update_txgain (struct misdn_bchannel *bc);
-void isdn_lib_update_ec (struct misdn_bchannel *bc);
-void isdn_lib_stop_dtmf (struct misdn_bchannel *bc);
-
-int misdn_lib_port_restart(int port);
-int misdn_lib_pid_restart(int pid);
-int misdn_lib_send_restart(int port, int channel);
-
-int misdn_lib_get_port_info(int port);
-
-int misdn_lib_is_port_blocked(int port);
-int misdn_lib_port_block(int port);
-int misdn_lib_port_unblock(int port);
-
-int misdn_lib_port_is_pri(int port);
-int misdn_lib_port_is_nt(int port);
-
-int misdn_lib_port_up(int port, int notcheck);
-
-int misdn_lib_get_port_down(int port);
-
-int misdn_lib_get_port_up (int port) ;
-
-int misdn_lib_maxports_get(void) ;
-
-struct misdn_bchannel *misdn_lib_find_held_bc(int port, int l3_id);
-void misdn_lib_release(struct misdn_bchannel *bc);
-
-int misdn_cap_is_speech(int cap);
-int misdn_inband_avail(struct misdn_bchannel *bc);
-
-void manager_ec_enable(struct misdn_bchannel *bc);
-void manager_ec_disable(struct misdn_bchannel *bc);
-
-void misdn_lib_send_tone(struct misdn_bchannel *bc, enum tone_e tone);
-
-void get_show_stack_details(int port, char *buf);
-
-
-void misdn_lib_tone_generator_start(struct misdn_bchannel *bc);
-void misdn_lib_tone_generator_stop(struct misdn_bchannel *bc);
-
-
-void misdn_lib_bridge( struct misdn_bchannel * bc1, struct misdn_bchannel *bc2);
-void misdn_lib_split_bridge( struct misdn_bchannel * bc1, struct misdn_bchannel *bc2);
-
-void misdn_lib_echo(struct misdn_bchannel *bc, int onoff);
-
-int misdn_lib_is_ptp(int port);
-int misdn_lib_get_maxchans(int port);
-
-void misdn_lib_reinit_nt_stack(int port);
-
-#define PRI_TRANS_CAP_SPEECH                                    0x0
-#define PRI_TRANS_CAP_DIGITAL                                   0x08
-#define PRI_TRANS_CAP_RESTRICTED_DIGITAL                        0x09
-#define PRI_TRANS_CAP_3_1K_AUDIO                                0x10
-#define PRI_TRANS_CAP_7K_AUDIO                                  0x11
-
-
-
-char *bc_state2str(enum bchannel_state state);
-void bc_state_change(struct misdn_bchannel *bc, enum bchannel_state state);
-
-void misdn_dump_chanlist(void);
-
-void misdn_make_dummy(struct misdn_bchannel *dummybc, int port, int l3id, int nt, int channel);
-
-
-#endif /* TE_LIB */
diff --git a/channels/misdn/isdn_lib_intern.h b/channels/misdn/isdn_lib_intern.h
deleted file mode 100644 (file)
index d811f80..0000000
+++ /dev/null
@@ -1,159 +0,0 @@
-#ifndef ISDN_LIB_INTERN
-#define ISDN_LIB_INTERN
-
-
-#include <mISDNuser/mISDNlib.h>
-#include <mISDNuser/isdn_net.h>
-#include <mISDNuser/l3dss1.h>
-#include <mISDNuser/net_l3.h>
-
-#include <pthread.h>
-
-#include "isdn_lib.h"
-
-#ifndef MISDNUSER_VERSION_CODE
-#error "You need a newer version of mISDNuser ..."
-#elif MISDNUSER_VERSION_CODE < MISDNUSER_VERSION(1, 0, 3)
-#error "You need a newer version of mISDNuser ..."
-#endif
-
-
-#define QI_ELEMENT(a) a.off
-
-
-#ifndef mISDNUSER_HEAD_SIZE
-
-#define mISDNUSER_HEAD_SIZE (sizeof(mISDNuser_head_t))
-/*#define mISDNUSER_HEAD_SIZE (sizeof(mISDN_head_t))*/
-#endif
-
-
-#if 0
-ibuffer_t *astbuf;             /* Not used */
-ibuffer_t *misdnbuf;   /* Not used */
-#endif
-
-struct send_lock {
-       pthread_mutex_t lock;
-};
-
-
-struct isdn_msg {
-       unsigned long misdn_msg;
-
-       enum event_e event;
-
-       void (*msg_parser)(struct isdn_msg *msgs, msg_t *msg, struct misdn_bchannel *bc, int nt);
-       msg_t *(*msg_builder)(struct isdn_msg *msgs, struct misdn_bchannel *bc, int nt);
-       char *info;
-} ;
-
-/* for isdn_msg_parser.c */
-msg_t *create_l3msg(int prim, int mt, int dinfo , int size, int nt);
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-/* Max call-completion REGISTER signaling links per stack/port */
-#define MISDN_MAX_REGISTER_LINKS       MAX_BCHANS
-#else
-/* Max call-completion REGISTER signaling links per stack/port */
-#define MISDN_MAX_REGISTER_LINKS       0
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#define MAXPROCS 0x100
-
-struct misdn_stack {
-       /** is first element because &nst equals &mISDNlist **/
-       net_stack_t nst;
-       manager_t mgr;
-       pthread_mutex_t nstlock;
-
-       /*! \brief Stack struct critical section lock. */
-       pthread_mutex_t st_lock;
-
-       /*! \brief D Channel mISDN driver stack ID (Parent stack ID) */
-       int d_stid;
-
-       /*! /brief Number of B channels supported by this port */
-       int b_num;
-
-       /*! \brief B Channel mISDN driver stack IDs (Child stack IDs) */
-       int b_stids[MAX_BCHANS + 1];
-
-       /*! \brief TRUE if Point-To-Point(PTP) (Point-To-Multipoint(PTMP) otherwise) */
-       int ptp;
-
-       /*! \brief Number of consecutive times PTP Layer 2 declared down */
-       int l2upcnt;
-
-       int l2_id;      /* Not used */
-
-       /*! \brief Lower layer mISDN ID (addr) (Layer 1/3) */
-       int lower_id;
-
-       /*! \brief Upper layer mISDN ID (addr) (Layer 2/4) */
-       int upper_id;
-
-       /*! \brief TRUE if port is blocked */
-       int blocked;
-
-       /*! \brief TRUE if Layer 2 is UP */
-       int l2link;
-
-       /*! \brief TRUE if Layer 1 is UP */
-       int l1link;
-
-       /*! \brief TRUE if restart has been sent to the other side after stack startup */
-       int restart_sent;
-
-       /*! \brief mISDN device handle returned by mISDN_open() */
-       int midev;
-
-       /*! \brief TRUE if NT side of protocol (TE otherwise) */
-       int nt;
-
-       /*! \brief TRUE if ISDN-PRI (ISDN-BRI otherwise) */
-       int pri;
-
-       /*! \brief CR Process ID allocation table.  TRUE if ID allocated */
-       int procids[MAXPROCS];
-
-       /*! \brief Queue of Event messages to send to mISDN */
-       msg_queue_t downqueue;
-       msg_queue_t upqueue;    /* No code puts anything on this queue */
-       int busy;       /* Not used */
-
-       /*! \brief Logical Layer 1 port associated with this stack */
-       int port;
-
-       /*!
-        * \brief B Channel record pool array
-        * (Must be dimensioned the same as struct misdn_stack.channels[])
-        */
-       struct misdn_bchannel bc[MAX_BCHANS + 1 + MISDN_MAX_REGISTER_LINKS];
-
-       /*!
-        * \brief Array of B channels in use (a[0] = B1).  TRUE if B channel in use.
-        * (Must be dimensioned the same as struct misdn_stack.bc[])
-        */
-       char channels[MAX_BCHANS + 1 + MISDN_MAX_REGISTER_LINKS];
-
-       /*! \brief List of held channels */
-       struct misdn_bchannel *holding;
-
-       /*! \brief Next stack in the list of stacks */
-       struct misdn_stack *next;
-};
-
-
-struct misdn_stack* get_stack_by_bc(struct misdn_bchannel *bc);
-
-int isdn_msg_get_index(struct isdn_msg msgs[], msg_t *frm, int nt);
-enum event_e isdn_msg_get_event(struct isdn_msg msgs[], msg_t *frm, int nt);
-int isdn_msg_parse_event(struct isdn_msg msgs[], msg_t *frm, struct misdn_bchannel *bc, int nt);
-char * isdn_get_info(struct isdn_msg msgs[], enum event_e event, int nt);
-msg_t * isdn_msg_build_event(struct isdn_msg msgs[], struct misdn_bchannel *bc, enum event_e event, int nt);
-int isdn_msg_get_index_by_event(struct isdn_msg msgs[], enum event_e event, int nt);
-char * isdn_msg_get_info(struct isdn_msg msgs[], msg_t *msg, int nt);
-
-
-#endif
diff --git a/channels/misdn/isdn_msg_parser.c b/channels/misdn/isdn_msg_parser.c
deleted file mode 100644 (file)
index 0e0ceea..0000000
+++ /dev/null
@@ -1,1769 +0,0 @@
-/*
- * Chan_Misdn -- Channel Driver for Asterisk
- *
- * Interface to mISDN
- *
- * Copyright (C) 2004, Christian Richter
- *
- * Christian Richter <crich@beronet.com>
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License
- */
-
-/*! \file
- * \brief Interface to mISDN - message parser
- * \author Christian Richter <crich@beronet.com>
- */
-
-/*** MODULEINFO
-       <support_level>extended</support_level>
- ***/
-
-#include "isdn_lib_intern.h"
-
-
-#include "isdn_lib.h"
-
-#include "ie.c"
-
-/*!
- * \internal
- * \brief Build the name, number, name/number display message string
- *
- * \param display Display buffer to fill in
- * \param display_length Length of the display buffer to fill in
- * \param display_format Display format enumeration
- * \param name Name string to use
- * \param number Number string to use
- *
- * \return Nothing
- */
-static void build_display_str(char *display, size_t display_length, int display_format, const char *name, const char *number)
-{
-       display[0] = 0;
-       switch (display_format) {
-       default:
-       case 0:         /* none */
-               break;
-
-       case 1:         /* name */
-               snprintf(display, display_length, "%s", name);
-               break;
-
-       case 2:         /* number */
-               snprintf(display, display_length, "%s", number);
-               break;
-
-       case 3:         /* both */
-               if (name[0] || number[0]) {
-                       snprintf(display, display_length, "\"%s\" <%s>", name, number);
-               }
-               break;
-       }
-}
-
-/*!
- * \internal
- * \brief Encode the Facility IE and put it into the message structure.
- *
- * \param ntmode Where the encoded facility was put when in NT mode.
- * \param msg General message structure
- * \param fac Data to encode into the facility ie.
- * \param nt TRUE if in NT mode.
- *
- * \return Nothing
- */
-static void enc_ie_facility(unsigned char **ntmode, msg_t *msg, struct FacParm *fac, int nt)
-{
-       int len;
-       Q931_info_t *qi;
-       unsigned char *p;
-       unsigned char buf[256];
-
-       len = encodeFac(buf, fac);
-       if (len <= 0) {
-               /*
-                * mISDN does not know how to build the requested facility structure
-                * Clear facility information
-                */
-               fac->Function = Fac_None;
-               return;
-       }
-
-       p = msg_put(msg, len);
-       if (nt) {
-               *ntmode = p + 1;
-       } else {
-               qi = (Q931_info_t *) (msg->data + mISDN_HEADER_LEN);
-               qi->QI_ELEMENT(facility) = p - (unsigned char *) qi - sizeof(Q931_info_t);
-       }
-
-       memcpy(p, buf, len);
-
-       /* Clear facility information */
-       fac->Function = Fac_None;
-}
-
-/*!
- * \internal
- * \brief Decode the Facility IE.
- *
- * \param p Encoded facility ie data to decode. (NT mode)
- * \param qi Encoded facility ie data to decode. (TE mode)
- * \param fac Where to put the decoded facility ie data if it is available.
- * \param nt TRUE if in NT mode.
- * \param bc Associated B channel
- *
- * \return Nothing
- */
-static void dec_ie_facility(unsigned char *p, Q931_info_t *qi, struct FacParm *fac, int nt, struct misdn_bchannel *bc)
-{
-       fac->Function = Fac_None;
-
-       if (!nt) {
-               p = NULL;
-               if (qi->QI_ELEMENT(facility)) {
-                       p = (unsigned char *) qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(facility) + 1;
-               }
-       }
-       if (!p) {
-               return;
-       }
-
-       if (decodeFac(p, fac)) {
-               cb_log(3, bc->port, "Decoding facility ie failed! Unrecognized facility message?\n");
-       }
-}
-
-
-
-static void set_channel(struct misdn_bchannel *bc, int channel)
-{
-
-       cb_log(3,bc->port,"set_channel: bc->channel:%d channel:%d\n", bc->channel, channel);
-
-
-       if (channel==0xff) {
-               /* any channel */
-               channel=-1;
-       }
-
-       /*  ALERT: is that everytime true ?  */
-       if (channel > 0 && bc->nt ) {
-
-               if (bc->channel && ( bc->channel != 0xff) ) {
-                       cb_log(0,bc->port,"We already have a channel (%d)\n", bc->channel);
-               } else {
-                       bc->channel = channel;
-                       cb_event(EVENT_NEW_CHANNEL,bc,NULL);
-               }
-       }
-
-       if (channel > 0 && !bc->nt ) {
-               bc->channel = channel;
-               cb_event(EVENT_NEW_CHANNEL,bc,NULL);
-       }
-}
-
-static void parse_proceeding (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
-       int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
-       CALL_PROCEEDING_t *proceeding = (CALL_PROCEEDING_t *) (msg->data + HEADER_LEN);
-       //struct misdn_stack *stack=get_stack_by_bc(bc);
-
-       {
-               int  exclusive, channel;
-               dec_ie_channel_id(proceeding->CHANNEL_ID, (Q931_info_t *)proceeding, &exclusive, &channel, nt,bc);
-
-               set_channel(bc,channel);
-
-       }
-
-       dec_ie_progress(proceeding->PROGRESS, (Q931_info_t *)proceeding, &bc->progress_coding, &bc->progress_location, &bc->progress_indicator, nt, bc);
-
-       dec_ie_facility(proceeding->FACILITY, (Q931_info_t *) proceeding, &bc->fac_in, nt, bc);
-
-       /* dec_ie_redir_dn */
-
-#ifdef DEBUG
-       printf("Parsing PROCEEDING Msg\n");
-#endif
-}
-static msg_t *build_proceeding (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
-       int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
-       CALL_PROCEEDING_t *proceeding;
-       msg_t *msg =(msg_t*)create_l3msg(CC_PROCEEDING | REQUEST, MT_CALL_PROCEEDING,  bc?bc->l3_id:-1, sizeof(CALL_PROCEEDING_t) ,nt);
-
-       proceeding=(CALL_PROCEEDING_t*)((msg->data+HEADER_LEN));
-
-       enc_ie_channel_id(&proceeding->CHANNEL_ID, msg, 1,bc->channel, nt,bc);
-
-       if (nt)
-               enc_ie_progress(&proceeding->PROGRESS, msg, 0, nt?1:5, 8, nt,bc);
-
-       if (bc->fac_out.Function != Fac_None) {
-               enc_ie_facility(&proceeding->FACILITY, msg, &bc->fac_out, nt);
-       }
-
-       /* enc_ie_redir_dn */
-
-#ifdef DEBUG
-       printf("Building PROCEEDING Msg\n");
-#endif
-       return msg;
-}
-
-static void parse_alerting (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
-       int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
-       ALERTING_t *alerting = (ALERTING_t *) (msg->data + HEADER_LEN);
-       //Q931_info_t *qi=(Q931_info_t*)(msg->data+HEADER_LEN);
-
-       dec_ie_facility(alerting->FACILITY, (Q931_info_t *) alerting, &bc->fac_in, nt, bc);
-
-       /* dec_ie_redir_dn */
-
-       dec_ie_progress(alerting->PROGRESS, (Q931_info_t *)alerting, &bc->progress_coding, &bc->progress_location, &bc->progress_indicator, nt, bc);
-
-#ifdef DEBUG
-       printf("Parsing ALERTING Msg\n");
-#endif
-
-
-}
-
-static msg_t *build_alerting (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
-       int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
-       ALERTING_t *alerting;
-       msg_t *msg =(msg_t*)create_l3msg(CC_ALERTING | REQUEST, MT_ALERTING,  bc?bc->l3_id:-1, sizeof(ALERTING_t) ,nt);
-
-       alerting=(ALERTING_t*)((msg->data+HEADER_LEN));
-
-       enc_ie_channel_id(&alerting->CHANNEL_ID, msg, 1,bc->channel, nt,bc);
-
-       if (nt)
-               enc_ie_progress(&alerting->PROGRESS, msg, 0, nt?1:5, 8, nt,bc);
-
-       if (bc->fac_out.Function != Fac_None) {
-               enc_ie_facility(&alerting->FACILITY, msg, &bc->fac_out, nt);
-       }
-
-       /* enc_ie_redir_dn */
-
-#ifdef DEBUG
-       printf("Building ALERTING Msg\n");
-#endif
-       return msg;
-}
-
-
-static void parse_progress (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
-       int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
-       PROGRESS_t *progress = (PROGRESS_t *) (msg->data + HEADER_LEN);
-       //Q931_info_t *qi=(Q931_info_t*)(msg->data+HEADER_LEN);
-
-       dec_ie_progress(progress->PROGRESS, (Q931_info_t *)progress, &bc->progress_coding, &bc->progress_location, &bc->progress_indicator, nt, bc);
-
-       dec_ie_facility(progress->FACILITY, (Q931_info_t *) progress, &bc->fac_in, nt, bc);
-
-#ifdef DEBUG
-       printf("Parsing PROGRESS Msg\n");
-#endif
-}
-
-static msg_t *build_progress (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
-       int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
-       PROGRESS_t *progress;
-       msg_t *msg =(msg_t*)create_l3msg(CC_PROGRESS | REQUEST, MT_PROGRESS,  bc?bc->l3_id:-1, sizeof(PROGRESS_t) ,nt);
-
-       progress=(PROGRESS_t*)((msg->data+HEADER_LEN));
-
-       enc_ie_progress(&progress->PROGRESS, msg, 0, nt ? 1 : 5, 8, nt, bc);
-
-       if (bc->fac_out.Function != Fac_None) {
-               enc_ie_facility(&progress->FACILITY, msg, &bc->fac_out, nt);
-       }
-
-#ifdef DEBUG
-       printf("Building PROGRESS Msg\n");
-#endif
-       return msg;
-}
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-/*!
- * \internal
- * \brief Extract the SETUP message's BC, HLC, and LLC encoded ie contents.
- *
- * \param setup Indexed setup message contents
- * \param nt TRUE if in NT mode.
- * \param bc Associated B channel
- *
- * \return Nothing
- */
-static void extract_setup_Bc_Hlc_Llc(SETUP_t *setup, int nt, struct misdn_bchannel *bc)
-{
-       __u8 *p;
-       Q931_info_t *qi;
-
-       qi = (Q931_info_t *) setup;
-
-       /* Extract Bearer Capability */
-       if (nt) {
-               p = (__u8 *) setup->BEARER;
-       } else {
-               if (qi->QI_ELEMENT(bearer_capability)) {
-                       p = (__u8 *) qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(bearer_capability) + 1;
-               } else {
-                       p = NULL;
-               }
-       }
-       if (!p || *p == 0 || sizeof(bc->setup_bc_hlc_llc.Bc.Contents) < *p) {
-               bc->setup_bc_hlc_llc.Bc.Length = 0;
-       } else {
-               bc->setup_bc_hlc_llc.Bc.Length = *p;
-               memcpy(bc->setup_bc_hlc_llc.Bc.Contents, p + 1, *p);
-       }
-
-       /* Extract Low Layer Compatibility */
-       if (nt) {
-               p = (__u8 *) setup->LLC;
-       } else {
-               if (qi->QI_ELEMENT(llc)) {
-                       p = (__u8 *) qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(llc) + 1;
-               } else {
-                       p = NULL;
-               }
-       }
-       if (!p || *p == 0 || sizeof(bc->setup_bc_hlc_llc.Llc.Contents) < *p) {
-               bc->setup_bc_hlc_llc.Llc.Length = 0;
-       } else {
-               bc->setup_bc_hlc_llc.Llc.Length = *p;
-               memcpy(bc->setup_bc_hlc_llc.Llc.Contents, p + 1, *p);
-       }
-
-       /* Extract High Layer Compatibility */
-       if (nt) {
-               p = (__u8 *) setup->HLC;
-       } else {
-               if (qi->QI_ELEMENT(hlc)) {
-                       p = (__u8 *) qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(hlc) + 1;
-               } else {
-                       p = NULL;
-               }
-       }
-       if (!p || *p == 0 || sizeof(bc->setup_bc_hlc_llc.Hlc.Contents) < *p) {
-               bc->setup_bc_hlc_llc.Hlc.Length = 0;
-       } else {
-               bc->setup_bc_hlc_llc.Hlc.Length = *p;
-               memcpy(bc->setup_bc_hlc_llc.Hlc.Contents, p + 1, *p);
-       }
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-static void parse_setup (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
-       int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
-       SETUP_t *setup = (SETUP_t *) (msg->data + HEADER_LEN);
-       Q931_info_t *qi = (Q931_info_t *) (msg->data + HEADER_LEN);
-       int type;
-       int plan;
-       int present;
-       int screen;
-       int reason;
-
-#ifdef DEBUG
-       printf("Parsing SETUP Msg\n");
-#endif
-
-       dec_ie_calling_pn(setup->CALLING_PN, qi, &type, &plan, &present, &screen, bc->caller.number, sizeof(bc->caller.number), nt, bc);
-       bc->caller.number_type = type;
-       bc->caller.number_plan = plan;
-       switch (present) {
-       default:
-       case 0:
-               bc->caller.presentation = 0;    /* presentation allowed */
-               break;
-       case 1:
-               bc->caller.presentation = 1;    /* presentation restricted */
-               break;
-       case 2:
-               bc->caller.presentation = 2;    /* Number not available */
-               break;
-       }
-       if (0 <= screen) {
-               bc->caller.screening = screen;
-       } else {
-               bc->caller.screening = 0;       /* Unscreened */
-       }
-
-       dec_ie_facility(setup->FACILITY, (Q931_info_t *) setup, &bc->fac_in, nt, bc);
-
-       dec_ie_called_pn(setup->CALLED_PN, (Q931_info_t *) setup, &type, &plan, bc->dialed.number, sizeof(bc->dialed.number), nt, bc);
-       bc->dialed.number_type = type;
-       bc->dialed.number_plan = plan;
-
-       dec_ie_keypad(setup->KEYPAD, (Q931_info_t *) setup, bc->keypad, sizeof(bc->keypad), nt, bc);
-
-       dec_ie_complete(setup->COMPLETE, (Q931_info_t *) setup, &bc->sending_complete, nt, bc);
-
-       dec_ie_redir_nr(setup->REDIR_NR, (Q931_info_t *) setup, &type, &plan, &present, &screen, &reason, bc->redirecting.from.number, sizeof(bc->redirecting.from.number), nt, bc);
-       bc->redirecting.from.number_type = type;
-       bc->redirecting.from.number_plan = plan;
-       switch (present) {
-       default:
-       case 0:
-               bc->redirecting.from.presentation = 0;  /* presentation allowed */
-               break;
-       case 1:
-               bc->redirecting.from.presentation = 1;  /* presentation restricted */
-               break;
-       case 2:
-               bc->redirecting.from.presentation = 2;  /* Number not available */
-               break;
-       }
-       if (0 <= screen) {
-               bc->redirecting.from.screening = screen;
-       } else {
-               bc->redirecting.from.screening = 0;     /* Unscreened */
-       }
-       if (0 <= reason) {
-               bc->redirecting.reason = reason;
-       } else {
-               bc->redirecting.reason = mISDN_REDIRECTING_REASON_UNKNOWN;
-       }
-
-       {
-               int  coding, capability, mode, rate, multi, user, async, urate, stopbits, dbits, parity;
-
-               dec_ie_bearer(setup->BEARER, (Q931_info_t *)setup, &coding, &capability, &mode, &rate, &multi, &user, &async, &urate, &stopbits, &dbits, &parity, nt,bc);
-               switch (capability) {
-               case -1: bc->capability=INFO_CAPABILITY_DIGITAL_UNRESTRICTED;
-                       break;
-               case 0: bc->capability=INFO_CAPABILITY_SPEECH;
-                       break;
-               case 18: bc->capability=INFO_CAPABILITY_VIDEO;
-                       break;
-               case 8: bc->capability=INFO_CAPABILITY_DIGITAL_UNRESTRICTED;
-                       bc->user1 = user;
-                       bc->urate = urate;
-
-                       bc->rate = rate;
-                       bc->mode = mode;
-                       break;
-               case 9: bc->capability=INFO_CAPABILITY_DIGITAL_RESTRICTED;
-                       break;
-               default:
-                       break;
-               }
-
-               switch(user) {
-               case 2:
-                       bc->law=INFO_CODEC_ULAW;
-                       break;
-               case 3:
-                       bc->law=INFO_CODEC_ALAW;
-                       break;
-               default:
-                       bc->law=INFO_CODEC_ALAW;
-
-               }
-
-               bc->capability=capability;
-       }
-       {
-               int  exclusive, channel;
-               dec_ie_channel_id(setup->CHANNEL_ID, (Q931_info_t *)setup, &exclusive, &channel, nt,bc);
-
-               set_channel(bc,channel);
-       }
-
-       {
-               int  protocol ;
-               dec_ie_useruser(setup->USER_USER, (Q931_info_t *)setup, &protocol, bc->uu, &bc->uulen, nt,bc);
-               if (bc->uulen) cb_log(1, bc->port, "USERUSERINFO:%s\n", bc->uu);
-               else
-               cb_log(1, bc->port, "NO USERUSERINFO\n");
-       }
-
-       dec_ie_progress(setup->PROGRESS, (Q931_info_t *)setup, &bc->progress_coding, &bc->progress_location, &bc->progress_indicator, nt, bc);
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-       extract_setup_Bc_Hlc_Llc(setup, nt, bc);
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-}
-
-#define ANY_CHANNEL 0xff /* IE attribute for 'any channel' */
-static msg_t *build_setup (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
-       int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
-       SETUP_t *setup;
-       msg_t *msg =(msg_t*)create_l3msg(CC_SETUP | REQUEST, MT_SETUP,  bc?bc->l3_id:-1, sizeof(SETUP_t) ,nt);
-       int is_ptp;
-       enum FacFunction fac_type;
-
-       setup=(SETUP_t*)((msg->data+HEADER_LEN));
-
-       if (bc->channel == 0 || bc->channel == ANY_CHANNEL || bc->channel==-1)
-               enc_ie_channel_id(&setup->CHANNEL_ID, msg, 0, bc->channel, nt,bc);
-       else
-               enc_ie_channel_id(&setup->CHANNEL_ID, msg, 1, bc->channel, nt,bc);
-
-       fac_type = bc->fac_out.Function;
-       if (fac_type != Fac_None) {
-               enc_ie_facility(&setup->FACILITY, msg, &bc->fac_out, nt);
-       }
-
-       enc_ie_calling_pn(&setup->CALLING_PN, msg, bc->caller.number_type, bc->caller.number_plan,
-               bc->caller.presentation, bc->caller.screening, bc->caller.number, nt, bc);
-
-       if (bc->dialed.number[0]) {
-               enc_ie_called_pn(&setup->CALLED_PN, msg, bc->dialed.number_type, bc->dialed.number_plan, bc->dialed.number, nt, bc);
-       }
-
-       switch (bc->outgoing_colp) {
-       case 0:/* pass */
-       case 1:/* restricted */
-               is_ptp = misdn_lib_is_ptp(bc->port);
-               if (bc->redirecting.from.number[0]
-                       && ((!is_ptp && nt)
-                               || (is_ptp
-#if defined(AST_MISDN_ENHANCEMENTS)
-                                       /*
-                                        * There is no need to send out this ie when we are also sending
-                                        * a Fac_DivertingLegInformation2 as well.  The
-                                        * Fac_DivertingLegInformation2 supercedes the information in
-                                        * this ie.
-                                        */
-                                       && fac_type != Fac_DivertingLegInformation2
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-                       ))) {
-#if 1
-                       /* ETSI and Q.952 do not define the screening field */
-                       enc_ie_redir_nr(&setup->REDIR_NR, msg, bc->redirecting.from.number_type,
-                               bc->redirecting.from.number_plan, bc->redirecting.from.presentation, 0,
-                               bc->redirecting.reason, bc->redirecting.from.number, nt, bc);
-#else
-                       /* Q.931 defines the screening field */
-                       enc_ie_redir_nr(&setup->REDIR_NR, msg, bc->redirecting.from.number_type,
-                               bc->redirecting.from.number_plan, bc->redirecting.from.presentation,
-                               bc->redirecting.from.screening, bc->redirecting.reason,
-                               bc->redirecting.from.number, nt, bc);
-#endif
-               }
-               break;
-       default:
-               break;
-       }
-
-       if (bc->keypad[0]) {
-               enc_ie_keypad(&setup->KEYPAD, msg, bc->keypad, nt,bc);
-       }
-
-
-
-       if (*bc->display) {
-               enc_ie_display(&setup->DISPLAY, msg, bc->display, nt, bc);
-       } else if (nt && bc->caller.presentation == 0) {
-               char display[sizeof(bc->display)];
-
-               /* Presentation is allowed */
-               build_display_str(display, sizeof(display), bc->display_setup, bc->caller.name, bc->caller.number);
-               if (display[0]) {
-                       enc_ie_display(&setup->DISPLAY, msg, display, nt, bc);
-               }
-       }
-
-       {
-               int coding = 0;
-               int capability;
-               int mode = 0;   /* 2 for packet! */
-               int user;
-               int rate = 0x10;
-
-               switch (bc->law) {
-               case INFO_CODEC_ULAW: user=2;
-                       break;
-               case INFO_CODEC_ALAW: user=3;
-                       break;
-               default:
-                       user=3;
-               }
-
-               switch (bc->capability) {
-               case INFO_CAPABILITY_SPEECH: capability = 0;
-                       break;
-               case INFO_CAPABILITY_DIGITAL_UNRESTRICTED: capability = 8;
-                       user=-1;
-                       mode=bc->mode;
-                       rate=bc->rate;
-                       break;
-               case INFO_CAPABILITY_DIGITAL_RESTRICTED: capability = 9;
-                       user=-1;
-                       break;
-               default:
-                       capability=bc->capability;
-               }
-
-               enc_ie_bearer(&setup->BEARER, msg, coding, capability, mode, rate, -1, user, nt,bc);
-       }
-
-       if (bc->sending_complete) {
-               enc_ie_complete(&setup->COMPLETE,msg, bc->sending_complete, nt, bc);
-       }
-
-       if (bc->uulen) {
-               int  protocol=4;
-               enc_ie_useruser(&setup->USER_USER, msg, protocol, bc->uu, bc->uulen, nt,bc);
-               cb_log(1, bc->port, "ENCODING USERUSERINFO:%s\n", bc->uu);
-       }
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-       extract_setup_Bc_Hlc_Llc(setup, nt, bc);
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#ifdef DEBUG
-       printf("Building SETUP Msg\n");
-#endif
-       return msg;
-}
-
-static void parse_connect (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
-       int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
-       CONNECT_t *connect = (CONNECT_t *) (msg->data + HEADER_LEN);
-       int type;
-       int plan;
-       int pres;
-       int screen;
-
-       bc->ces = connect->ces;
-
-       dec_ie_progress(connect->PROGRESS, (Q931_info_t *)connect, &bc->progress_coding, &bc->progress_location, &bc->progress_indicator, nt, bc);
-
-       dec_ie_connected_pn(connect->CONNECT_PN, (Q931_info_t *) connect, &type, &plan,
-               &pres, &screen, bc->connected.number, sizeof(bc->connected.number), nt, bc);
-       bc->connected.number_type = type;
-       bc->connected.number_plan = plan;
-       switch (pres) {
-       default:
-       case 0:
-               bc->connected.presentation = 0; /* presentation allowed */
-               break;
-       case 1:
-               bc->connected.presentation = 1; /* presentation restricted */
-               break;
-       case 2:
-               bc->connected.presentation = 2; /* Number not available */
-               break;
-       }
-       if (0 <= screen) {
-               bc->connected.screening = screen;
-       } else {
-               bc->connected.screening = 0;    /* Unscreened */
-       }
-
-       dec_ie_facility(connect->FACILITY, (Q931_info_t *) connect, &bc->fac_in, nt, bc);
-
-       /*
-               cb_log(1,bc->port,"CONNETED PN: %s cpn_dialplan:%d\n", connected_pn, type);
-       */
-
-#ifdef DEBUG
-       printf("Parsing CONNECT Msg\n");
-#endif
-}
-
-static msg_t *build_connect (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
-       int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
-       CONNECT_t *connect;
-       msg_t *msg =(msg_t*)create_l3msg(CC_CONNECT | REQUEST, MT_CONNECT,  bc?bc->l3_id:-1, sizeof(CONNECT_t) ,nt);
-
-       cb_log(6,bc->port,"BUILD_CONNECT: bc:%p bc->l3id:%d, nt:%d\n",bc,bc->l3_id,nt);
-
-       connect=(CONNECT_t*)((msg->data+HEADER_LEN));
-
-       if (nt) {
-               time_t now;
-               time(&now);
-               enc_ie_date(&connect->DATE, msg, now, nt,bc);
-       }
-
-       switch (bc->outgoing_colp) {
-       case 0:/* pass */
-       case 1:/* restricted */
-               enc_ie_connected_pn(&connect->CONNECT_PN, msg, bc->connected.number_type,
-                       bc->connected.number_plan, bc->connected.presentation,
-                       bc->connected.screening, bc->connected.number, nt, bc);
-               break;
-       default:
-               break;
-       }
-
-       if (nt && bc->connected.presentation == 0) {
-               char display[sizeof(bc->display)];
-
-               /* Presentation is allowed */
-               build_display_str(display, sizeof(display), bc->display_connected, bc->connected.name, bc->connected.number);
-               if (display[0]) {
-                       enc_ie_display(&connect->DISPLAY, msg, display, nt, bc);
-               }
-       }
-
-       if (bc->fac_out.Function != Fac_None) {
-               enc_ie_facility(&connect->FACILITY, msg, &bc->fac_out, nt);
-       }
-
-#ifdef DEBUG
-       printf("Building CONNECT Msg\n");
-#endif
-       return msg;
-}
-
-static void parse_setup_acknowledge (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
-       int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
-       SETUP_ACKNOWLEDGE_t *setup_acknowledge = (SETUP_ACKNOWLEDGE_t *) (msg->data + HEADER_LEN);
-
-       {
-               int  exclusive, channel;
-               dec_ie_channel_id(setup_acknowledge->CHANNEL_ID, (Q931_info_t *)setup_acknowledge, &exclusive, &channel, nt,bc);
-
-
-               set_channel(bc, channel);
-       }
-
-       dec_ie_progress(setup_acknowledge->PROGRESS, (Q931_info_t *)setup_acknowledge, &bc->progress_coding, &bc->progress_location, &bc->progress_indicator, nt, bc);
-
-       dec_ie_facility(setup_acknowledge->FACILITY, (Q931_info_t *) setup_acknowledge, &bc->fac_in, nt, bc);
-
-#ifdef DEBUG
-       printf("Parsing SETUP_ACKNOWLEDGE Msg\n");
-#endif
-
-
-}
-
-static msg_t *build_setup_acknowledge (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
-       int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
-       SETUP_ACKNOWLEDGE_t *setup_acknowledge;
-       msg_t *msg =(msg_t*)create_l3msg(CC_SETUP_ACKNOWLEDGE | REQUEST, MT_SETUP_ACKNOWLEDGE,  bc?bc->l3_id:-1, sizeof(SETUP_ACKNOWLEDGE_t) ,nt);
-
-       setup_acknowledge=(SETUP_ACKNOWLEDGE_t*)((msg->data+HEADER_LEN));
-
-       enc_ie_channel_id(&setup_acknowledge->CHANNEL_ID, msg, 1,bc->channel, nt,bc);
-
-       if (nt)
-               enc_ie_progress(&setup_acknowledge->PROGRESS, msg, 0, nt?1:5, 8, nt,bc);
-
-       if (bc->fac_out.Function != Fac_None) {
-               enc_ie_facility(&setup_acknowledge->FACILITY, msg, &bc->fac_out, nt);
-       }
-
-#ifdef DEBUG
-       printf("Building SETUP_ACKNOWLEDGE Msg\n");
-#endif
-       return msg;
-}
-
-static void parse_connect_acknowledge (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
-#ifdef DEBUG
-       printf("Parsing CONNECT_ACKNOWLEDGE Msg\n");
-#endif
-
-
-}
-
-static msg_t *build_connect_acknowledge (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
-       int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
-       CONNECT_ACKNOWLEDGE_t *connect_acknowledge;
-       msg_t *msg =(msg_t*)create_l3msg(CC_CONNECT | RESPONSE, MT_CONNECT,  bc?bc->l3_id:-1, sizeof(CONNECT_ACKNOWLEDGE_t) ,nt);
-
-       connect_acknowledge=(CONNECT_ACKNOWLEDGE_t*)((msg->data+HEADER_LEN));
-
-       enc_ie_channel_id(&connect_acknowledge->CHANNEL_ID, msg, 1, bc->channel, nt,bc);
-
-#ifdef DEBUG
-       printf("Building CONNECT_ACKNOWLEDGE Msg\n");
-#endif
-       return msg;
-}
-
-static void parse_user_information (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
-#ifdef DEBUG
-       printf("Parsing USER_INFORMATION Msg\n");
-#endif
-
-
-}
-
-static msg_t *build_user_information (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
-       msg_t *msg =(msg_t*)create_l3msg(CC_USER_INFORMATION | REQUEST, MT_USER_INFORMATION,  bc?bc->l3_id:-1, sizeof(USER_INFORMATION_t) ,nt);
-
-#ifdef DEBUG
-       printf("Building USER_INFORMATION Msg\n");
-#endif
-       return msg;
-}
-
-static void parse_suspend_reject (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
-#ifdef DEBUG
-       printf("Parsing SUSPEND_REJECT Msg\n");
-#endif
-
-
-}
-
-static msg_t *build_suspend_reject (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
-       msg_t *msg =(msg_t*)create_l3msg(CC_SUSPEND_REJECT | REQUEST, MT_SUSPEND_REJECT,  bc?bc->l3_id:-1, sizeof(SUSPEND_REJECT_t) ,nt);
-
-#ifdef DEBUG
-       printf("Building SUSPEND_REJECT Msg\n");
-#endif
-       return msg;
-}
-
-static void parse_resume_reject (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
-#ifdef DEBUG
-       printf("Parsing RESUME_REJECT Msg\n");
-#endif
-
-
-}
-
-static msg_t *build_resume_reject (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
-       msg_t *msg =(msg_t*)create_l3msg(CC_RESUME_REJECT | REQUEST, MT_RESUME_REJECT,  bc?bc->l3_id:-1, sizeof(RESUME_REJECT_t) ,nt);
-
-#ifdef DEBUG
-       printf("Building RESUME_REJECT Msg\n");
-#endif
-       return msg;
-}
-
-static void parse_hold (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
-#ifdef DEBUG
-       printf("Parsing HOLD Msg\n");
-#endif
-
-
-}
-
-static msg_t *build_hold (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
-       msg_t *msg =(msg_t*)create_l3msg(CC_HOLD | REQUEST, MT_HOLD,  bc?bc->l3_id:-1, sizeof(HOLD_t) ,nt);
-
-#ifdef DEBUG
-       printf("Building HOLD Msg\n");
-#endif
-       return msg;
-}
-
-static void parse_suspend (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
-#ifdef DEBUG
-       printf("Parsing SUSPEND Msg\n");
-#endif
-
-
-}
-
-static msg_t *build_suspend (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
-       msg_t *msg =(msg_t*)create_l3msg(CC_SUSPEND | REQUEST, MT_SUSPEND,  bc?bc->l3_id:-1, sizeof(SUSPEND_t) ,nt);
-
-#ifdef DEBUG
-       printf("Building SUSPEND Msg\n");
-#endif
-       return msg;
-}
-
-static void parse_resume (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
-#ifdef DEBUG
-       printf("Parsing RESUME Msg\n");
-#endif
-
-
-}
-
-static msg_t *build_resume (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
-       msg_t *msg =(msg_t*)create_l3msg(CC_RESUME | REQUEST, MT_RESUME,  bc?bc->l3_id:-1, sizeof(RESUME_t) ,nt);
-
-#ifdef DEBUG
-       printf("Building RESUME Msg\n");
-#endif
-       return msg;
-}
-
-static void parse_hold_acknowledge (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
-#ifdef DEBUG
-       printf("Parsing HOLD_ACKNOWLEDGE Msg\n");
-#endif
-
-
-}
-
-static msg_t *build_hold_acknowledge (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
-       msg_t *msg =(msg_t*)create_l3msg(CC_HOLD_ACKNOWLEDGE | REQUEST, MT_HOLD_ACKNOWLEDGE,  bc?bc->l3_id:-1, sizeof(HOLD_ACKNOWLEDGE_t) ,nt);
-
-#ifdef DEBUG
-       printf("Building HOLD_ACKNOWLEDGE Msg\n");
-#endif
-       return msg;
-}
-
-static void parse_suspend_acknowledge (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
-#ifdef DEBUG
-       printf("Parsing SUSPEND_ACKNOWLEDGE Msg\n");
-#endif
-
-
-}
-
-static msg_t *build_suspend_acknowledge (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
-       msg_t *msg =(msg_t*)create_l3msg(CC_SUSPEND_ACKNOWLEDGE | REQUEST, MT_SUSPEND_ACKNOWLEDGE,  bc?bc->l3_id:-1, sizeof(SUSPEND_ACKNOWLEDGE_t) ,nt);
-
-#ifdef DEBUG
-       printf("Building SUSPEND_ACKNOWLEDGE Msg\n");
-#endif
-       return msg;
-}
-
-static void parse_resume_acknowledge (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
-#ifdef DEBUG
-       printf("Parsing RESUME_ACKNOWLEDGE Msg\n");
-#endif
-
-
-}
-
-static msg_t *build_resume_acknowledge (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
-       msg_t *msg =(msg_t*)create_l3msg(CC_RESUME_ACKNOWLEDGE | REQUEST, MT_RESUME_ACKNOWLEDGE,  bc?bc->l3_id:-1, sizeof(RESUME_ACKNOWLEDGE_t) ,nt);
-
-#ifdef DEBUG
-       printf("Building RESUME_ACKNOWLEDGE Msg\n");
-#endif
-       return msg;
-}
-
-static void parse_hold_reject (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
-#ifdef DEBUG
-       printf("Parsing HOLD_REJECT Msg\n");
-#endif
-
-
-}
-
-static msg_t *build_hold_reject (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
-       msg_t *msg =(msg_t*)create_l3msg(CC_HOLD_REJECT | REQUEST, MT_HOLD_REJECT,  bc?bc->l3_id:-1, sizeof(HOLD_REJECT_t) ,nt);
-
-#ifdef DEBUG
-       printf("Building HOLD_REJECT Msg\n");
-#endif
-       return msg;
-}
-
-static void parse_retrieve (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
-#ifdef DEBUG
-       printf("Parsing RETRIEVE Msg\n");
-#endif
-
-
-}
-
-static msg_t *build_retrieve (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
-       msg_t *msg =(msg_t*)create_l3msg(CC_RETRIEVE | REQUEST, MT_RETRIEVE,  bc?bc->l3_id:-1, sizeof(RETRIEVE_t) ,nt);
-
-#ifdef DEBUG
-       printf("Building RETRIEVE Msg\n");
-#endif
-       return msg;
-}
-
-static void parse_retrieve_acknowledge (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
-#ifdef DEBUG
-       printf("Parsing RETRIEVE_ACKNOWLEDGE Msg\n");
-#endif
-
-
-}
-
-static msg_t *build_retrieve_acknowledge (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
-       int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
-       RETRIEVE_ACKNOWLEDGE_t *retrieve_acknowledge;
-       msg_t *msg =(msg_t*)create_l3msg(CC_RETRIEVE_ACKNOWLEDGE | REQUEST, MT_RETRIEVE_ACKNOWLEDGE,  bc?bc->l3_id:-1, sizeof(RETRIEVE_ACKNOWLEDGE_t) ,nt);
-
-       retrieve_acknowledge=(RETRIEVE_ACKNOWLEDGE_t*)((msg->data+HEADER_LEN));
-
-       enc_ie_channel_id(&retrieve_acknowledge->CHANNEL_ID, msg, 1, bc->channel, nt,bc);
-#ifdef DEBUG
-       printf("Building RETRIEVE_ACKNOWLEDGE Msg\n");
-#endif
-       return msg;
-}
-
-static void parse_retrieve_reject (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
-#ifdef DEBUG
-       printf("Parsing RETRIEVE_REJECT Msg\n");
-#endif
-
-
-}
-
-static msg_t *build_retrieve_reject (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
-       msg_t *msg =(msg_t*)create_l3msg(CC_RETRIEVE_REJECT | REQUEST, MT_RETRIEVE_REJECT,  bc?bc->l3_id:-1, sizeof(RETRIEVE_REJECT_t) ,nt);
-
-#ifdef DEBUG
-       printf("Building RETRIEVE_REJECT Msg\n");
-#endif
-       return msg;
-}
-
-static void parse_disconnect (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
-       int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
-       DISCONNECT_t *disconnect = (DISCONNECT_t *) (msg->data + HEADER_LEN);
-       int location;
-       int cause;
-       dec_ie_cause(disconnect->CAUSE, (Q931_info_t *)(disconnect), &location, &cause, nt,bc);
-       if (cause>0) bc->cause=cause;
-
-       dec_ie_facility(disconnect->FACILITY, (Q931_info_t *) disconnect, &bc->fac_in, nt, bc);
-
-       dec_ie_progress(disconnect->PROGRESS, (Q931_info_t *)disconnect, &bc->progress_coding, &bc->progress_location, &bc->progress_indicator, nt, bc);
-#ifdef DEBUG
-       printf("Parsing DISCONNECT Msg\n");
-#endif
-
-
-}
-
-static msg_t *build_disconnect (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
-       int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
-       DISCONNECT_t *disconnect;
-       msg_t *msg =(msg_t*)create_l3msg(CC_DISCONNECT | REQUEST, MT_DISCONNECT,  bc?bc->l3_id:-1, sizeof(DISCONNECT_t) ,nt);
-
-       disconnect=(DISCONNECT_t*)((msg->data+HEADER_LEN));
-
-       enc_ie_cause(&disconnect->CAUSE, msg, (nt)?1:0, bc->out_cause,nt,bc);
-       if (nt) {
-               enc_ie_progress(&disconnect->PROGRESS, msg, 0, nt ? 1 : 5, 8, nt, bc);
-       }
-
-       if (bc->fac_out.Function != Fac_None) {
-               enc_ie_facility(&disconnect->FACILITY, msg, &bc->fac_out, nt);
-       }
-
-       if (bc->uulen) {
-               int  protocol=4;
-               enc_ie_useruser(&disconnect->USER_USER, msg, protocol, bc->uu, bc->uulen, nt,bc);
-               cb_log(1, bc->port, "ENCODING USERUSERINFO:%s\n", bc->uu);
-       }
-
-#ifdef DEBUG
-       printf("Building DISCONNECT Msg\n");
-#endif
-       return msg;
-}
-
-static void parse_restart (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
-       int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
-       RESTART_t *restart = (RESTART_t *) (msg->data + HEADER_LEN);
-
-       struct misdn_stack *stack=get_stack_by_bc(bc);
-
-#ifdef DEBUG
-       printf("Parsing RESTART Msg\n");
-#endif
-
-       {
-               int  exclusive;
-               dec_ie_channel_id(restart->CHANNEL_ID, (Q931_info_t *)restart, &exclusive, &bc->restart_channel, nt,bc);
-               cb_log(3, stack->port, "CC_RESTART Request on channel:%d on this port.\n", bc->restart_channel);
-       }
-
-}
-
-static msg_t *build_restart (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
-       int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
-       RESTART_t *restart;
-       msg_t *msg =(msg_t*)create_l3msg(CC_RESTART | REQUEST, MT_RESTART,  bc?bc->l3_id:-1, sizeof(RESTART_t) ,nt);
-
-       restart=(RESTART_t*)((msg->data+HEADER_LEN));
-
-#ifdef DEBUG
-       printf("Building RESTART Msg\n");
-#endif
-
-       if (bc->channel > 0) {
-               enc_ie_channel_id(&restart->CHANNEL_ID, msg, 1,bc->channel, nt,bc);
-               enc_ie_restart_ind(&restart->RESTART_IND, msg, 0x80, nt, bc);
-       } else {
-               enc_ie_restart_ind(&restart->RESTART_IND, msg, 0x87, nt, bc);
-       }
-
-       cb_log(0,bc->port, "Restarting channel %d\n", bc->channel);
-       return msg;
-}
-
-static void parse_release (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
-       int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
-       RELEASE_t *release = (RELEASE_t *) (msg->data + HEADER_LEN);
-       int location;
-       int cause;
-
-       dec_ie_cause(release->CAUSE, (Q931_info_t *)(release), &location, &cause, nt,bc);
-       if (cause>0) bc->cause=cause;
-
-       dec_ie_facility(release->FACILITY, (Q931_info_t *) release, &bc->fac_in, nt, bc);
-
-#ifdef DEBUG
-       printf("Parsing RELEASE Msg\n");
-#endif
-
-
-}
-
-static msg_t *build_release (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
-       int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
-       RELEASE_t *release;
-       msg_t *msg =(msg_t*)create_l3msg(CC_RELEASE | REQUEST, MT_RELEASE,  bc?bc->l3_id:-1, sizeof(RELEASE_t) ,nt);
-
-       release=(RELEASE_t*)((msg->data+HEADER_LEN));
-
-       if (bc->out_cause>= 0)
-               enc_ie_cause(&release->CAUSE, msg, nt?1:0, bc->out_cause, nt,bc);
-
-       if (bc->fac_out.Function != Fac_None) {
-               enc_ie_facility(&release->FACILITY, msg, &bc->fac_out, nt);
-       }
-
-       if (bc->uulen) {
-               int  protocol=4;
-               enc_ie_useruser(&release->USER_USER, msg, protocol, bc->uu, bc->uulen, nt,bc);
-               cb_log(1, bc->port, "ENCODING USERUSERINFO:%s\n", bc->uu);
-       }
-
-#ifdef DEBUG
-       printf("Building RELEASE Msg\n");
-#endif
-       return msg;
-}
-
-static void parse_release_complete (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
-       int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
-       RELEASE_COMPLETE_t *release_complete = (RELEASE_COMPLETE_t *) (msg->data + HEADER_LEN);
-       int location;
-       int cause;
-       iframe_t *frm = (iframe_t*) msg->data;
-
-       struct misdn_stack *stack=get_stack_by_bc(bc);
-       mISDNuser_head_t *hh;
-       hh=(mISDNuser_head_t*)msg->data;
-
-       /*hh=(mISDN_head_t*)msg->data;
-       mISDN_head_t *hh;*/
-
-       if (nt) {
-               if (hh->prim == (CC_RELEASE_COMPLETE|CONFIRM)) {
-                       cb_log(0, stack->port, "CC_RELEASE_COMPLETE|CONFIRM [NT] \n");
-                       return;
-               }
-       } else {
-               if (frm->prim == (CC_RELEASE_COMPLETE|CONFIRM)) {
-                       cb_log(0, stack->port, "CC_RELEASE_COMPLETE|CONFIRM [TE] \n");
-                       return;
-               }
-       }
-       dec_ie_cause(release_complete->CAUSE, (Q931_info_t *)(release_complete), &location, &cause, nt,bc);
-       if (cause>0) bc->cause=cause;
-
-       dec_ie_facility(release_complete->FACILITY, (Q931_info_t *) release_complete, &bc->fac_in, nt, bc);
-
-#ifdef DEBUG
-       printf("Parsing RELEASE_COMPLETE Msg\n");
-#endif
-}
-
-static msg_t *build_release_complete (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
-       int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
-       RELEASE_COMPLETE_t *release_complete;
-       msg_t *msg =(msg_t*)create_l3msg(CC_RELEASE_COMPLETE | REQUEST, MT_RELEASE_COMPLETE,  bc?bc->l3_id:-1, sizeof(RELEASE_COMPLETE_t) ,nt);
-
-       release_complete=(RELEASE_COMPLETE_t*)((msg->data+HEADER_LEN));
-
-       enc_ie_cause(&release_complete->CAUSE, msg, nt?1:0, bc->out_cause, nt,bc);
-
-       if (bc->fac_out.Function != Fac_None) {
-               enc_ie_facility(&release_complete->FACILITY, msg, &bc->fac_out, nt);
-       }
-
-       if (bc->uulen) {
-               int  protocol=4;
-               enc_ie_useruser(&release_complete->USER_USER, msg, protocol, bc->uu, bc->uulen, nt,bc);
-               cb_log(1, bc->port, "ENCODING USERUSERINFO:%s\n", bc->uu);
-       }
-
-#ifdef DEBUG
-       printf("Building RELEASE_COMPLETE Msg\n");
-#endif
-       return msg;
-}
-
-static void parse_facility (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
-       int HEADER_LEN = nt ? mISDNUSER_HEAD_SIZE : mISDN_HEADER_LEN;
-       FACILITY_t *facility = (FACILITY_t*)(msg->data+HEADER_LEN);
-       Q931_info_t *qi = (Q931_info_t*)(msg->data+HEADER_LEN);
-       unsigned char *p = NULL;
-#if defined(AST_MISDN_ENHANCEMENTS)
-       int description_code;
-       int type;
-       int plan;
-       int present;
-       char number[sizeof(bc->redirecting.to.number)];
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#ifdef DEBUG
-       printf("Parsing FACILITY Msg\n");
-#endif
-
-       bc->fac_in.Function = Fac_None;
-
-       if (!bc->nt) {
-               if (qi->QI_ELEMENT(facility))
-                       p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(facility) + 1;
-       } else {
-               p = facility->FACILITY;
-       }
-       if (!p)
-               return;
-
-       if (decodeFac(p, &bc->fac_in)) {
-               cb_log(3, bc->port, "Decoding facility ie failed! Unrecognized facility message?\n");
-       }
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-       dec_ie_notify(facility->NOTIFY, qi, &description_code, nt, bc);
-       if (description_code < 0) {
-               bc->notify_description_code = mISDN_NOTIFY_CODE_INVALID;
-       } else {
-               bc->notify_description_code = description_code;
-       }
-
-       dec_ie_redir_dn(facility->REDIR_DN, qi, &type, &plan, &present, number, sizeof(number), nt, bc);
-       if (0 <= type) {
-               bc->redirecting.to_changed = 1;
-
-               bc->redirecting.to.number_type = type;
-               bc->redirecting.to.number_plan = plan;
-               switch (present) {
-               default:
-               case 0:
-                       bc->redirecting.to.presentation = 0;    /* presentation allowed */
-                       break;
-               case 1:
-                       bc->redirecting.to.presentation = 1;    /* presentation restricted */
-                       break;
-               case 2:
-                       bc->redirecting.to.presentation = 2;    /* Number not available */
-                       break;
-               }
-               bc->redirecting.to.screening = 0;       /* Unscreened */
-               strcpy(bc->redirecting.to.number, number);
-       }
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-}
-
-static msg_t *build_facility (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
-       int len;
-       int HEADER_LEN;
-       unsigned char *ie_fac;
-       unsigned char fac_tmp[256];
-       msg_t *msg;
-       FACILITY_t *facility;
-       Q931_info_t *qi;
-
-#ifdef DEBUG
-       printf("Building FACILITY Msg\n");
-#endif
-
-       len = encodeFac(fac_tmp, &(bc->fac_out));
-       if (len <= 0) {
-               /*
-                * mISDN does not know how to build the requested facility structure
-                * Clear facility information
-                */
-               bc->fac_out.Function = Fac_None;
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-               /* Clear other one shot information. */
-               bc->notify_description_code = mISDN_NOTIFY_CODE_INVALID;
-               bc->redirecting.to_changed = 0;
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-               return NULL;
-       }
-
-       msg = (msg_t *) create_l3msg(CC_FACILITY | REQUEST, MT_FACILITY, bc ? bc->l3_id : -1, sizeof(FACILITY_t), nt);
-       HEADER_LEN = nt ? mISDNUSER_HEAD_SIZE : mISDN_HEADER_LEN;
-       facility = (FACILITY_t *) (msg->data + HEADER_LEN);
-
-       ie_fac = msg_put(msg, len);
-       if (bc->nt) {
-               facility->FACILITY = ie_fac + 1;
-       } else {
-               qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
-               qi->QI_ELEMENT(facility) = ie_fac - (unsigned char *)qi - sizeof(Q931_info_t);
-       }
-
-       memcpy(ie_fac, fac_tmp, len);
-
-       /* Clear facility information */
-       bc->fac_out.Function = Fac_None;
-
-       if (*bc->display) {
-#ifdef DEBUG
-               printf("Sending %s as Display\n", bc->display);
-#endif
-               enc_ie_display(&facility->DISPLAY, msg, bc->display, nt,bc);
-       }
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-       if (bc->notify_description_code != mISDN_NOTIFY_CODE_INVALID) {
-               enc_ie_notify(&facility->NOTIFY, msg, bc->notify_description_code, nt, bc);
-               bc->notify_description_code = mISDN_NOTIFY_CODE_INVALID;
-       }
-
-       if (bc->redirecting.to_changed) {
-               bc->redirecting.to_changed = 0;
-               switch (bc->outgoing_colp) {
-               case 0:/* pass */
-               case 1:/* restricted */
-                       enc_ie_redir_dn(&facility->REDIR_DN, msg, bc->redirecting.to.number_type,
-                               bc->redirecting.to.number_plan, bc->redirecting.to.presentation,
-                               bc->redirecting.to.number, nt, bc);
-                       break;
-               default:
-                       break;
-               }
-       }
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-       return msg;
-}
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-/*!
- * \internal
- * \brief Parse a received REGISTER message
- *
- * \param msgs Search table entry that called us.
- * \param msg Received message contents
- * \param bc Associated B channel
- * \param nt TRUE if in NT mode.
- *
- * \return Nothing
- */
-static void parse_register(struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
-       int HEADER_LEN;
-       REGISTER_t *reg;
-
-       HEADER_LEN = nt ? mISDNUSER_HEAD_SIZE : mISDN_HEADER_LEN;
-       reg = (REGISTER_t *) (msg->data + HEADER_LEN);
-
-       /*
-        * A facility ie is optional.
-        * The peer may just be establishing a connection to send
-        * messages later.
-        */
-       dec_ie_facility(reg->FACILITY, (Q931_info_t *) reg, &bc->fac_in, nt, bc);
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-/*!
- * \internal
- * \brief Construct a REGISTER message
- *
- * \param msgs Search table entry that called us.
- * \param bc Associated B channel
- * \param nt TRUE if in NT mode.
- *
- * \return Allocated built message
- */
-static msg_t *build_register(struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
-       int HEADER_LEN;
-       REGISTER_t *reg;
-       msg_t *msg;
-
-       msg = (msg_t *) create_l3msg(CC_REGISTER | REQUEST, MT_REGISTER,  bc ? bc->l3_id : -1, sizeof(REGISTER_t), nt);
-       HEADER_LEN = nt ? mISDNUSER_HEAD_SIZE : mISDN_HEADER_LEN;
-       reg = (REGISTER_t *) (msg->data + HEADER_LEN);
-
-       if (bc->fac_out.Function != Fac_None) {
-               enc_ie_facility(&reg->FACILITY, msg, &bc->fac_out, nt);
-       }
-
-       return msg;
-}
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-
-static void parse_notify (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
-       int HEADER_LEN = nt ? mISDNUSER_HEAD_SIZE : mISDN_HEADER_LEN;
-       NOTIFY_t *notify = (NOTIFY_t *) (msg->data + HEADER_LEN);
-       int description_code;
-       int type;
-       int plan;
-       int present;
-       char number[sizeof(bc->redirecting.to.number)];
-
-#ifdef DEBUG
-       printf("Parsing NOTIFY Msg\n");
-#endif
-
-       dec_ie_notify(notify->NOTIFY, (Q931_info_t *) notify, &description_code, nt, bc);
-       if (description_code < 0) {
-               bc->notify_description_code = mISDN_NOTIFY_CODE_INVALID;
-       } else {
-               bc->notify_description_code = description_code;
-       }
-
-       dec_ie_redir_dn(notify->REDIR_DN, (Q931_info_t *) notify, &type, &plan, &present, number, sizeof(number), nt, bc);
-       if (0 <= type) {
-               bc->redirecting.to_changed = 1;
-
-               bc->redirecting.to.number_type = type;
-               bc->redirecting.to.number_plan = plan;
-               switch (present) {
-               default:
-               case 0:
-                       bc->redirecting.to.presentation = 0;    /* presentation allowed */
-                       break;
-               case 1:
-                       bc->redirecting.to.presentation = 1;    /* presentation restricted */
-                       break;
-               case 2:
-                       bc->redirecting.to.presentation = 2;    /* Number not available */
-                       break;
-               }
-               bc->redirecting.to.screening = 0;       /* Unscreened */
-               strcpy(bc->redirecting.to.number, number);
-       }
-}
-
-static msg_t *build_notify (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
-       int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
-       NOTIFY_t *notify;
-       msg_t *msg =(msg_t*)create_l3msg(CC_NOTIFY | REQUEST, MT_NOTIFY,  bc?bc->l3_id:-1, sizeof(NOTIFY_t) ,nt);
-
-#ifdef DEBUG
-       printf("Building NOTIFY Msg\n");
-#endif
-
-       notify = (NOTIFY_t *) (msg->data + HEADER_LEN);
-
-       enc_ie_notify(&notify->NOTIFY, msg, bc->notify_description_code, nt, bc);
-       bc->notify_description_code = mISDN_NOTIFY_CODE_INVALID;
-
-       if (bc->redirecting.to_changed) {
-               bc->redirecting.to_changed = 0;
-               switch (bc->outgoing_colp) {
-               case 0:/* pass */
-               case 1:/* restricted */
-                       enc_ie_redir_dn(&notify->REDIR_DN, msg, bc->redirecting.to.number_type,
-                               bc->redirecting.to.number_plan, bc->redirecting.to.presentation,
-                               bc->redirecting.to.number, nt, bc);
-                       break;
-               default:
-                       break;
-               }
-       }
-       return msg;
-}
-
-static void parse_status_enquiry (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
-#ifdef DEBUG
-       printf("Parsing STATUS_ENQUIRY Msg\n");
-#endif
-}
-
-static msg_t *build_status_enquiry (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
-       msg_t *msg =(msg_t*)create_l3msg(CC_STATUS_ENQUIRY | REQUEST, MT_STATUS_ENQUIRY,  bc?bc->l3_id:-1, sizeof(STATUS_ENQUIRY_t) ,nt);
-
-#ifdef DEBUG
-       printf("Building STATUS_ENQUIRY Msg\n");
-#endif
-       return msg;
-}
-
-static void parse_information (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
-       int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
-       INFORMATION_t *information = (INFORMATION_t *) (msg->data + HEADER_LEN);
-       int type, plan;
-
-       dec_ie_called_pn(information->CALLED_PN, (Q931_info_t *) information, &type, &plan, bc->info_dad, sizeof(bc->info_dad), nt, bc);
-       dec_ie_keypad(information->KEYPAD, (Q931_info_t *) information, bc->keypad, sizeof(bc->keypad), nt, bc);
-
-#ifdef DEBUG
-       printf("Parsing INFORMATION Msg\n");
-#endif
-}
-
-static msg_t *build_information (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
-       int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
-       INFORMATION_t *information;
-       msg_t *msg =(msg_t*)create_l3msg(CC_INFORMATION | REQUEST, MT_INFORMATION,  bc?bc->l3_id:-1, sizeof(INFORMATION_t) ,nt);
-
-       information=(INFORMATION_t*)((msg->data+HEADER_LEN));
-
-       enc_ie_called_pn(&information->CALLED_PN, msg, 0, 1, bc->info_dad, nt,bc);
-
-       {
-               if (*bc->display) {
-#ifdef DEBUG
-                       printf("Sending %s as Display\n", bc->display);
-#endif
-                       enc_ie_display(&information->DISPLAY, msg, bc->display, nt,bc);
-               }
-       }
-
-#ifdef DEBUG
-       printf("Building INFORMATION Msg\n");
-#endif
-       return msg;
-}
-
-static void parse_status (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
-       int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
-       STATUS_t *status = (STATUS_t *) (msg->data + HEADER_LEN);
-       int location;
-       int cause;
-
-       dec_ie_cause(status->CAUSE, (Q931_info_t *)(status), &location, &cause, nt,bc);
-       if (cause>0) bc->cause=cause;
-
-#ifdef DEBUG
-       printf("Parsing STATUS Msg\n");
-#endif
-}
-
-static msg_t *build_status (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
-       msg_t *msg =(msg_t*)create_l3msg(CC_STATUS | REQUEST, MT_STATUS,  bc?bc->l3_id:-1, sizeof(STATUS_t) ,nt);
-
-#ifdef DEBUG
-       printf("Building STATUS Msg\n");
-#endif
-       return msg;
-}
-
-static void parse_timeout (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
-#ifdef DEBUG
-       printf("Parsing STATUS Msg\n");
-#endif
-}
-
-static msg_t *build_timeout (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
-{
-       msg_t *msg =(msg_t*)create_l3msg(CC_STATUS | REQUEST, MT_STATUS,  bc?bc->l3_id:-1, sizeof(STATUS_t) ,nt);
-
-#ifdef DEBUG
-       printf("Building STATUS Msg\n");
-#endif
-       return msg;
-}
-
-
-/************************************/
-
-
-
-
-/** Msg Array **/
-
-struct isdn_msg msgs_g[] = {
-/* *INDENT-OFF* */
-       /* misdn_msg,               event,                      msg_parser,                 msg_builder,                info */
-       { CC_PROCEEDING,            EVENT_PROCEEDING,           parse_proceeding,           build_proceeding,           "PROCEEDING" },
-       { CC_ALERTING,              EVENT_ALERTING,             parse_alerting,             build_alerting,             "ALERTING" },
-       { CC_PROGRESS,              EVENT_PROGRESS,             parse_progress,             build_progress,             "PROGRESS" },
-       { CC_SETUP,                 EVENT_SETUP,                parse_setup,                build_setup,                "SETUP" },
-#if defined(AST_MISDN_ENHANCEMENTS)
-       { CC_REGISTER,              EVENT_REGISTER,             parse_register,             build_register,             "REGISTER" },
-#endif /* defined(AST_MISDN_ENHANCEMENTS) */
-       { CC_CONNECT,               EVENT_CONNECT,              parse_connect,              build_connect,              "CONNECT" },
-       { CC_SETUP_ACKNOWLEDGE,     EVENT_SETUP_ACKNOWLEDGE,    parse_setup_acknowledge,    build_setup_acknowledge,    "SETUP_ACKNOWLEDGE" },
-       { CC_CONNECT_ACKNOWLEDGE,   EVENT_CONNECT_ACKNOWLEDGE,  parse_connect_acknowledge,  build_connect_acknowledge,  "CONNECT_ACKNOWLEDGE " },
-       { CC_USER_INFORMATION,      EVENT_USER_INFORMATION,     parse_user_information,     build_user_information,     "USER_INFORMATION" },
-       { CC_SUSPEND_REJECT,        EVENT_SUSPEND_REJECT,       parse_suspend_reject,       build_suspend_reject,       "SUSPEND_REJECT" },
-       { CC_RESUME_REJECT,         EVENT_RESUME_REJECT,        parse_resume_reject,        build_resume_reject,        "RESUME_REJECT" },
-       { CC_HOLD,                  EVENT_HOLD,                 parse_hold,                 build_hold,                 "HOLD" },
-       { CC_SUSPEND,               EVENT_SUSPEND,              parse_suspend,              build_suspend,              "SUSPEND" },
-       { CC_RESUME,                EVENT_RESUME,               parse_resume,               build_resume,               "RESUME" },
-       { CC_HOLD_ACKNOWLEDGE,      EVENT_HOLD_ACKNOWLEDGE,     parse_hold_acknowledge,     build_hold_acknowledge,     "HOLD_ACKNOWLEDGE" },
-       { CC_SUSPEND_ACKNOWLEDGE,   EVENT_SUSPEND_ACKNOWLEDGE,  parse_suspend_acknowledge,  build_suspend_acknowledge,  "SUSPEND_ACKNOWLEDGE" },
-       { CC_RESUME_ACKNOWLEDGE,    EVENT_RESUME_ACKNOWLEDGE,   parse_resume_acknowledge,   build_resume_acknowledge,   "RESUME_ACKNOWLEDGE" },
-       { CC_HOLD_REJECT,           EVENT_HOLD_REJECT,          parse_hold_reject,          build_hold_reject,          "HOLD_REJECT" },
-       { CC_RETRIEVE,              EVENT_RETRIEVE,             parse_retrieve,             build_retrieve,             "RETRIEVE" },
-       { CC_RETRIEVE_ACKNOWLEDGE,  EVENT_RETRIEVE_ACKNOWLEDGE, parse_retrieve_acknowledge, build_retrieve_acknowledge, "RETRIEVE_ACKNOWLEDGE" },
-       { CC_RETRIEVE_REJECT,       EVENT_RETRIEVE_REJECT,      parse_retrieve_reject,      build_retrieve_reject,      "RETRIEVE_REJECT" },
-       { CC_DISCONNECT,            EVENT_DISCONNECT,           parse_disconnect,           build_disconnect,           "DISCONNECT" },
-       { CC_RESTART,               EVENT_RESTART,              parse_restart,              build_restart,              "RESTART" },
-       { CC_RELEASE,               EVENT_RELEASE,              parse_release,              build_release,              "RELEASE" },
-       { CC_RELEASE_COMPLETE,      EVENT_RELEASE_COMPLETE,     parse_release_complete,     build_release_complete,     "RELEASE_COMPLETE" },
-       { CC_FACILITY,              EVENT_FACILITY,             parse_facility,             build_facility,             "FACILITY" },
-       { CC_NOTIFY,                EVENT_NOTIFY,               parse_notify,               build_notify,               "NOTIFY" },
-       { CC_STATUS_ENQUIRY,        EVENT_STATUS_ENQUIRY,       parse_status_enquiry,       build_status_enquiry,       "STATUS_ENQUIRY" },
-       { CC_INFORMATION,           EVENT_INFORMATION,          parse_information,          build_information,          "INFORMATION" },
-       { CC_STATUS,                EVENT_STATUS,               parse_status,               build_status,               "STATUS" },
-       { CC_TIMEOUT,               EVENT_TIMEOUT,              parse_timeout,              build_timeout,              "TIMEOUT" },
-       { 0, 0, NULL, NULL, NULL }
-/* *INDENT-ON* */
-};
-
-#define msgs_max (sizeof(msgs_g)/sizeof(struct isdn_msg))
-
-/** INTERFACE FCTS ***/
-int isdn_msg_get_index(struct isdn_msg msgs[], msg_t *msg, int nt)
-{
-       int i;
-
-       if (nt){
-               mISDNuser_head_t *hh = (mISDNuser_head_t*)msg->data;
-
-               for (i=0; i< msgs_max -1; i++) {
-                       if ( (hh->prim&COMMAND_MASK)==(msgs[i].misdn_msg&COMMAND_MASK)) return i;
-               }
-
-       } else {
-               iframe_t *frm = (iframe_t*)msg->data;
-
-               for (i=0; i< msgs_max -1; i++)
-                       if ( (frm->prim&COMMAND_MASK)==(msgs[i].misdn_msg&COMMAND_MASK)) return i;
-       }
-
-       return -1;
-}
-
-int isdn_msg_get_index_by_event(struct isdn_msg msgs[], enum event_e event, int nt)
-{
-       int i;
-       for (i=0; i< msgs_max; i++)
-               if ( event == msgs[i].event) return i;
-
-       cb_log(10,0, "get_index: event not found!\n");
-
-       return -1;
-}
-
-enum event_e isdn_msg_get_event(struct isdn_msg msgs[], msg_t *msg, int nt)
-{
-       int i=isdn_msg_get_index(msgs, msg, nt);
-       if(i>=0) return msgs[i].event;
-       return EVENT_UNKNOWN;
-}
-
-char * isdn_msg_get_info(struct isdn_msg msgs[], msg_t *msg, int nt)
-{
-       int i=isdn_msg_get_index(msgs, msg, nt);
-       if(i>=0) return msgs[i].info;
-       return NULL;
-}
-
-
-char EVENT_CLEAN_INFO[] = "CLEAN_UP";
-char EVENT_DTMF_TONE_INFO[] = "DTMF_TONE";
-char EVENT_NEW_L3ID_INFO[] = "NEW_L3ID";
-char EVENT_NEW_BC_INFO[] = "NEW_BC";
-char EVENT_PORT_ALARM_INFO[] = "ALARM";
-char EVENT_NEW_CHANNEL_INFO[] = "NEW_CHANNEL";
-char EVENT_BCHAN_DATA_INFO[] = "BCHAN_DATA";
-char EVENT_BCHAN_ACTIVATED_INFO[] = "BCHAN_ACTIVATED";
-char EVENT_TONE_GENERATE_INFO[] = "TONE_GENERATE";
-char EVENT_BCHAN_ERROR_INFO[] = "BCHAN_ERROR";
-
-char * isdn_get_info(struct isdn_msg msgs[], enum event_e event, int nt)
-{
-       int i=isdn_msg_get_index_by_event(msgs, event, nt);
-
-       if(i>=0) return msgs[i].info;
-
-       if (event == EVENT_CLEANUP) return EVENT_CLEAN_INFO;
-       if (event == EVENT_DTMF_TONE) return EVENT_DTMF_TONE_INFO;
-       if (event == EVENT_NEW_L3ID) return EVENT_NEW_L3ID_INFO;
-       if (event == EVENT_NEW_BC) return EVENT_NEW_BC_INFO;
-       if (event == EVENT_NEW_CHANNEL) return EVENT_NEW_CHANNEL_INFO;
-       if (event == EVENT_BCHAN_DATA) return EVENT_BCHAN_DATA_INFO;
-       if (event == EVENT_BCHAN_ACTIVATED) return EVENT_BCHAN_ACTIVATED_INFO;
-       if (event == EVENT_TONE_GENERATE) return EVENT_TONE_GENERATE_INFO;
-       if (event == EVENT_PORT_ALARM) return EVENT_PORT_ALARM_INFO;
-       if (event == EVENT_BCHAN_ERROR) return EVENT_BCHAN_ERROR_INFO;
-
-       return NULL;
-}
-
-int isdn_msg_parse_event(struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
-{
-       int i=isdn_msg_get_index(msgs, msg, nt);
-       if(i<0) return -1;
-
-       msgs[i].msg_parser(msgs, msg, bc, nt);
-       return 0;
-}
-
-msg_t * isdn_msg_build_event(struct isdn_msg msgs[], struct misdn_bchannel *bc, enum event_e event, int nt)
-{
-       int i=isdn_msg_get_index_by_event(msgs, event, nt);
-       if(i<0) return NULL;
-
-       return  msgs[i].msg_builder(msgs, bc, nt);
-}
diff --git a/channels/misdn/portinfo.c b/channels/misdn/portinfo.c
deleted file mode 100644 (file)
index f6af398..0000000
+++ /dev/null
@@ -1,205 +0,0 @@
-/*! \file
- * \brief Interface to mISDN - port info
- * \author Christian Richter <crich@beronet.com>
- */
-
-/*** MODULEINFO
-       <support_level>extended</support_level>
- ***/
-
-#include "isdn_lib.h"
-#include "isdn_lib_intern.h"
-
-
-/*
- * global function to show all available isdn ports
- */
-void isdn_port_info(void)
-{
-       int err;
-       int i, ii, p;
-       int useable, nt, pri;
-       unsigned char buff[1025];
-       iframe_t *frm = (iframe_t *)buff;
-       stack_info_t *stinf;
-       int device;
-
-       /* open mISDN */
-       if ((device = mISDN_open()) < 0)
-       {
-               fprintf(stderr, "mISDN_open() failed: ret=%d errno=%d (%s) Check for mISDN modules and device.\n", device, errno, strerror(errno));
-               exit(-1);
-       }
-
-       /* get number of stacks */
-       i = 1;
-       ii = mISDN_get_stack_count(device);
-       printf("\n");
-       if (ii <= 0)
-       {
-               printf("Found no card. Please be sure to load card drivers.\n");
-       }
-
-       /* loop the number of cards and get their info */
-       while(i <= ii)
-       {
-               err = mISDN_get_stack_info(device, i, buff, sizeof(buff));
-               if (err <= 0)
-               {
-                       fprintf(stderr, "mISDN_get_stack_info() failed: port=%d err=%d\n", i, err);
-                       break;
-               }
-               stinf = (stack_info_t *)&frm->data.p;
-
-               nt = pri = 0;
-               useable = 1;
-
-               /* output the port info */
-               printf("Port %2d: ", i);
-               switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK)
-               {
-                       case ISDN_PID_L0_TE_S0:
-                       printf("TE-mode BRI S/T interface line (for phone lines)");
-#if 0
-                       if (stinf->pid.protocol[0] & ISDN_PID_L0_TE_S0_HFC & ISDN_PID_FEATURE_MASK)
-                               printf(" HFC multiport card");
-#endif
-                       break;
-                       case ISDN_PID_L0_NT_S0:
-                       nt = 1;
-                       printf("NT-mode BRI S/T interface port (for phones)");
-#if 0
-                       if (stinf->pid.protocol[0] & ISDN_PID_L0_NT_S0_HFC & ISDN_PID_FEATURE_MASK)
-                               printf(" HFC multiport card");
-#endif
-                       break;
-                       case ISDN_PID_L0_TE_U:
-                       printf("TE-mode BRI U   interface line");
-                       break;
-                       case ISDN_PID_L0_NT_U:
-                       nt = 1;
-                       printf("NT-mode BRI U   interface port");
-                       break;
-                       case ISDN_PID_L0_TE_UP2:
-                       printf("TE-mode BRI Up2 interface line");
-                       break;
-                       case ISDN_PID_L0_NT_UP2:
-                       nt = 1;
-                       printf("NT-mode BRI Up2 interface port");
-                       break;
-                       case ISDN_PID_L0_TE_E1:
-                       pri = 1;
-                       printf("TE-mode PRI E1  interface line (for phone lines)");
-#if 0
-                       if (stinf->pid.protocol[0] & ISDN_PID_L0_TE_E1_HFC & ISDN_PID_FEATURE_MASK)
-                               printf(" HFC-E1 card");
-#endif
-                       break;
-                       case ISDN_PID_L0_NT_E1:
-                       nt = 1;
-                       pri = 1;
-                       printf("NT-mode PRI E1  interface port (for phones)");
-#if 0
-                       if (stinf->pid.protocol[0] & ISDN_PID_L0_NT_E1_HFC & ISDN_PID_FEATURE_MASK)
-                               printf(" HFC-E1 card");
-#endif
-                       break;
-                       default:
-                       useable = 0;
-                       printf("unknown type 0x%08x",stinf->pid.protocol[0]);
-               }
-               printf("\n");
-
-               if (nt)
-               {
-                       if (stinf->pid.protocol[1] == 0)
-                       {
-                               useable = 0;
-                               printf(" -> Missing layer 1 NT-mode protocol.\n");
-                       }
-                       p = 2;
-                       while(p <= MAX_LAYER_NR) {
-                               if (stinf->pid.protocol[p])
-                               {
-                                       useable = 0;
-                                       printf(" -> Layer %d protocol 0x%08x is detected, but not allowed for NT lib.\n", p, stinf->pid.protocol[p]);
-                               }
-                               p++;
-                       }
-                       if (useable)
-                       {
-                               if (pri)
-                                       printf(" -> Interface is Point-To-Point (PRI).\n");
-                               else
-                                       printf(" -> Interface can be Poin-To-Point/Multipoint.\n");
-                       }
-               } else
-               {
-                       if (stinf->pid.protocol[1] == 0)
-                       {
-                               useable = 0;
-                               printf(" -> Missing layer 1 protocol.\n");
-                       }
-                       if (stinf->pid.protocol[2] == 0)
-                       {
-                               useable = 0;
-                               printf(" -> Missing layer 2 protocol.\n");
-                       }
-                       if (stinf->pid.protocol[2] & ISDN_PID_L2_DF_PTP)
-                       {
-                               printf(" -> Interface is Poin-To-Point.\n");
-                       }
-                       if (stinf->pid.protocol[3] == 0)
-                       {
-                               useable = 0;
-                               printf(" -> Missing layer 3 protocol.\n");
-                       } else
-                       {
-                               printf(" -> Protocol: ");
-                               switch(stinf->pid.protocol[3] & ~ISDN_PID_FEATURE_MASK)
-                               {
-                                       case ISDN_PID_L3_DSS1USER:
-                                       printf("DSS1 (Euro ISDN)");
-                                       break;
-
-                                       default:
-                                       useable = 0;
-                                       printf("unknown protocol 0x%08x",stinf->pid.protocol[3]);
-                               }
-                               printf("\n");
-                       }
-                       p = 4;
-                       while(p <= MAX_LAYER_NR) {
-                               if (stinf->pid.protocol[p])
-                               {
-                                       useable = 0;
-                                       printf(" -> Layer %d protocol 0x%08x is detected, but not allowed for TE lib.\n", p, stinf->pid.protocol[p]);
-                               }
-                               p++;
-                       }
-                       printf(" -> childcnt: %d\n",stinf->childcnt);
-               }
-
-               if (!useable)
-                       printf(" * Port NOT useable for PBX\n");
-
-               printf("--------\n");
-
-               i++;
-       }
-       printf("\n");
-
-       /* close mISDN */
-       if ((err = mISDN_close(device)))
-       {
-               fprintf(stderr, "mISDN_close() failed: err=%d '%s'\n", err, strerror(err));
-               exit(-1);
-       }
-}
-
-
-int main()
-{
-  isdn_port_info();
-  return 0;
-}
diff --git a/channels/misdn_config.c b/channels/misdn_config.c
deleted file mode 100644 (file)
index bfb3e32..0000000
+++ /dev/null
@@ -1,1273 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2005, Christian Richter
- *
- * Christian Richter <crich@beronet.com>
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- *
- */
-
-/*!
- * \file
- *
- * \brief chan_misdn configuration management
- * \author Christian Richter <crich@beronet.com>
- *
- * \ingroup channel_drivers
- */
-
-/*** MODULEINFO
-       <support_level>extended</support_level>
- ***/
-
-#include "asterisk.h"
-
-#include "chan_misdn_config.h"
-
-#include "asterisk/config.h"
-#include "asterisk/channel.h"
-#include "asterisk/lock.h"
-#include "asterisk/pbx.h"
-#include "asterisk/strings.h"
-#include "asterisk/utils.h"
-
-#define NO_DEFAULT "<>"
-#define NONE 0
-
-#define GEN_CFG 1
-#define PORT_CFG 2
-#define NUM_GEN_ELEMENTS (sizeof(gen_spec) / sizeof(struct misdn_cfg_spec))
-#define NUM_PORT_ELEMENTS (sizeof(port_spec) / sizeof(struct misdn_cfg_spec))
-
-/*! Global jitterbuffer configuration - by default, jb is disabled
- *  \note Values shown here match the defaults shown in misdn.conf.sample */
-static struct ast_jb_conf default_jbconf =
-{
-       .flags = 0,
-       .max_size = 200,
-       .resync_threshold = 1000,
-       .impl = "fixed",
-       .target_extra = 40,
-};
-
-static struct ast_jb_conf global_jbconf;
-
-enum misdn_cfg_type {
-       MISDN_CTYPE_STR,
-       MISDN_CTYPE_INT,
-       MISDN_CTYPE_BOOL,
-       MISDN_CTYPE_BOOLINT,
-       MISDN_CTYPE_MSNLIST,
-       MISDN_CTYPE_ASTGROUP,
-       MISDN_CTYPE_ASTNAMEDGROUP
-};
-
-struct msn_list {
-       char *msn;
-       struct msn_list *next;
-};
-
-union misdn_cfg_pt {
-       char *str;
-       int *num;
-       struct msn_list *ml;
-       ast_group_t *grp;
-       struct ast_namedgroups *namgrp;
-       void *any;
-};
-
-struct misdn_cfg_spec {
-       char name[BUFFERSIZE];
-       enum misdn_cfg_elements elem;
-       enum misdn_cfg_type type;
-       char def[BUFFERSIZE];
-       int boolint_def;
-       char desc[BUFFERSIZE];
-};
-
-
-static const char ports_description[] =
-       "Define your ports, e.g. 1,2 (depends on mISDN-driver loading order).";
-
-static const struct misdn_cfg_spec port_spec[] = {
-       { "name", MISDN_CFG_GROUPNAME, MISDN_CTYPE_STR, "default", NONE,
-               "Name of the portgroup." },
-       { "allowed_bearers", MISDN_CFG_ALLOWED_BEARERS, MISDN_CTYPE_STR, "all", NONE,
-               "Here you can list which bearer capabilities should be allowed:\n"
-               "\t  all                  - allow any bearer capability\n"
-               "\t  speech               - allow speech\n"
-               "\t  3_1khz               - allow 3.1KHz audio\n"
-               "\t  digital_unrestricted - allow unrestricted digital\n"
-               "\t  digital_restricted   - allow restricted digital\n"
-               "\t  video                - allow video" },
-       { "rxgain", MISDN_CFG_RXGAIN, MISDN_CTYPE_INT, "0", NONE,
-               "Set this between -8 and 8 to change the RX Gain." },
-       { "txgain", MISDN_CFG_TXGAIN, MISDN_CTYPE_INT, "0", NONE,
-               "Set this between -8 and 8 to change the TX Gain." },
-       { "te_choose_channel", MISDN_CFG_TE_CHOOSE_CHANNEL, MISDN_CTYPE_BOOL, "no", NONE,
-               "Some telcos especially in NL seem to need this set to yes,\n"
-               "\talso in Switzerland this seems to be important." },
-       { "far_alerting", MISDN_CFG_FAR_ALERTING, MISDN_CTYPE_BOOL, "no", NONE,
-               "If we should generate ringing for chan_sip and others." },
-       { "pmp_l1_check", MISDN_CFG_PMP_L1_CHECK, MISDN_CTYPE_BOOL, "no", NONE,
-               "This option defines, if chan_misdn should check the L1 on a PMP\n"
-               "\tbefore making a group call on it. The L1 may go down for PMP Ports\n"
-               "\tso we might need this.\n"
-               "\tBut be aware! a broken or plugged off cable might be used for a group call\n"
-               "\tas well, since chan_misdn has no chance to distinguish if the L1 is down\n"
-               "\tbecause of a lost Link or because the Provider shut it down..." },
-       { "block_on_alarm", MISDN_CFG_ALARM_BLOCK, MISDN_CTYPE_BOOL, "no", NONE ,
-         "Block this port if we have an alarm on it." },
-       { "hdlc", MISDN_CFG_HDLC, MISDN_CTYPE_BOOL, "no", NONE,
-               "Set this to yes, if you want to bridge a mISDN data channel to\n"
-               "\tanother channel type or to an application." },
-       { "context", MISDN_CFG_CONTEXT, MISDN_CTYPE_STR, "default", NONE,
-               "Context to use for incoming calls." },
-       { "language", MISDN_CFG_LANGUAGE, MISDN_CTYPE_STR, "en", NONE,
-               "Language." },
-       { "musicclass", MISDN_CFG_MUSICCLASS, MISDN_CTYPE_STR, "default", NONE,
-               "Sets the musiconhold class." },
-       { "callerid", MISDN_CFG_CALLERID, MISDN_CTYPE_STR, "", NONE,
-               "Set the outgoing caller id to the value." },
-       { "incoming_cid_tag", MISDN_CFG_INCOMING_CALLERID_TAG, MISDN_CTYPE_STR, "", NONE,
-               "Set the incoming caller id string tag to the value." },
-       { "append_msn_to_cid_tag", MISDN_CFG_APPEND_MSN_TO_CALLERID_TAG, MISDN_CTYPE_BOOL, "no", NONE,
-               "Automatically appends incoming or outgoing MSN to the incoming caller\n"
-               "\tid string tag. An underscore '_' is used as delimiter. Incoming calls\n"
-               "\twill have the dialed number appended, and outgoing calls will have the\n"
-               "\tcaller number appended to the tag." },
-       { "method", MISDN_CFG_METHOD, MISDN_CTYPE_STR, "standard", NONE,
-               "Set the method to use for channel selection:\n"
-               "\t  standard     - Use the first free channel starting from the lowest number.\n"
-               "\t  standard_dec - Use the first free channel starting from the highest number.\n"
-               "\t  round_robin  - Use the round robin algorithm to select a channel. Use this\n"
-               "\t                 if you want to balance your load." },
-       { "dialplan", MISDN_CFG_DIALPLAN, MISDN_CTYPE_INT, "0", NONE,
-               "Dialplan means Type Of Number in ISDN Terms\n"
-               "\tThere are different types of the dialplan:\n"
-               "\n"
-               "\tdialplan -> for outgoing call's dialed number\n"
-               "\tlocaldialplan -> for outgoing call's callerid\n"
-               "\t      (if -1 is set use the value from the asterisk channel)\n"
-               "\tcpndialplan -> for incoming call's connected party number sent to caller\n"
-               "\t      (if -1 is set use the value from the asterisk channel)\n"
-               "\n"
-               "\tdialplan options:\n"
-               "\n"
-               "\t0 - unknown\n"
-               "\t1 - International\n"
-               "\t2 - National\n"
-               "\t4 - Subscriber" },
-       { "localdialplan", MISDN_CFG_LOCALDIALPLAN, MISDN_CTYPE_INT, "0", NONE,
-               "Dialplan means Type Of Number in ISDN Terms\n"
-               "\tThere are different types of the dialplan:\n"
-               "\n"
-               "\tdialplan -> for outgoing call's dialed number\n"
-               "\tlocaldialplan -> for outgoing call's callerid\n"
-               "\t      (if -1 is set use the value from the asterisk channel)\n"
-               "\tcpndialplan -> for incoming call's connected party number sent to caller\n"
-               "\t      (if -1 is set use the value from the asterisk channel)\n"
-               "\n"
-               "\tdialplan options:\n"
-               "\n"
-               "\t0 - unknown\n"
-               "\t1 - International\n"
-               "\t2 - National\n"
-               "\t4 - Subscriber" },
-       { "cpndialplan", MISDN_CFG_CPNDIALPLAN, MISDN_CTYPE_INT, "0", NONE,
-               "Dialplan means Type Of Number in ISDN Terms\n"
-               "\tThere are different types of the dialplan:\n"
-               "\n"
-               "\tdialplan -> for outgoing call's dialed number\n"
-               "\tlocaldialplan -> for outgoing call's callerid\n"
-               "\t      (if -1 is set use the value from the asterisk channel)\n"
-               "\tcpndialplan -> for incoming call's connected party number sent to caller\n"
-               "\t      (if -1 is set use the value from the asterisk channel)\n"
-               "\n"
-               "\tdialplan options:\n"
-               "\n"
-               "\t0 - unknown\n"
-               "\t1 - International\n"
-               "\t2 - National\n"
-               "\t4 - Subscriber" },
-       { "unknownprefix", MISDN_CFG_TON_PREFIX_UNKNOWN, MISDN_CTYPE_STR, "", NONE,
-               "Prefix for unknown numbers, this is put before an incoming number\n"
-               "\tif its type-of-number is unknown." },
-       { "internationalprefix", MISDN_CFG_TON_PREFIX_INTERNATIONAL, MISDN_CTYPE_STR, "00", NONE,
-               "Prefix for international numbers, this is put before an incoming number\n"
-               "\tif its type-of-number is international." },
-       { "nationalprefix", MISDN_CFG_TON_PREFIX_NATIONAL, MISDN_CTYPE_STR, "0", NONE,
-               "Prefix for national numbers, this is put before an incoming number\n"
-               "\tif its type-of-number is national." },
-       { "netspecificprefix", MISDN_CFG_TON_PREFIX_NETWORK_SPECIFIC, MISDN_CTYPE_STR, "", NONE,
-               "Prefix for network-specific numbers, this is put before an incoming number\n"
-               "\tif its type-of-number is network-specific." },
-       { "subscriberprefix", MISDN_CFG_TON_PREFIX_SUBSCRIBER, MISDN_CTYPE_STR, "", NONE,
-               "Prefix for subscriber numbers, this is put before an incoming number\n"
-               "\tif its type-of-number is subscriber." },
-       { "abbreviatedprefix", MISDN_CFG_TON_PREFIX_ABBREVIATED, MISDN_CTYPE_STR, "", NONE,
-               "Prefix for abbreviated numbers, this is put before an incoming number\n"
-               "\tif its type-of-number is abbreviated." },
-       { "presentation", MISDN_CFG_PRES, MISDN_CTYPE_INT, "-1", NONE,
-               "These (presentation and screen) are the exact isdn screening and presentation\n"
-               "\tindicators.\n"
-               "\tIf -1 is given for either value, the presentation indicators are used from\n"
-               "\tAsterisk's CALLERPRES function.\n"
-               "\n"
-               "\tscreen=0, presentation=0 -> callerid presented\n"
-               "\tscreen=1, presentation=1 -> callerid restricted (the remote end doesn't see it!)" },
-       { "screen", MISDN_CFG_SCREEN, MISDN_CTYPE_INT, "-1", NONE,
-               "These (presentation and screen) are the exact isdn screening and presentation\n"
-               "\tindicators.\n"
-               "\tIf -1 is given for either value, the presentation indicators are used from\n"
-               "\tAsterisk's CALLERPRES function.\n"
-               "\n"
-               "\tscreen=0, presentation=0 -> callerid presented\n"
-               "\tscreen=1, presentation=1 -> callerid restricted (the remote end doesn't see it!)" },
-       { "outgoing_colp", MISDN_CFG_OUTGOING_COLP, MISDN_CTYPE_INT, "0", NONE,
-               "Select what to do with outgoing COLP information on this port.\n"
-               "\n"
-               "\t0 - Send out COLP information unaltered.\n"
-               "\t1 - Force COLP to restricted on all outgoing COLP information.\n"
-               "\t2 - Do not send COLP information." },
-       { "display_connected", MISDN_CFG_DISPLAY_CONNECTED, MISDN_CTYPE_INT, "0", NONE,
-               "Put a display ie in the CONNECT message containing the following\n"
-               "\tinformation if it is available (nt port only):\n"
-               "\n"
-               "\t0 - Do not put the connected line information in the display ie.\n"
-               "\t1 - Put the available connected line name in the display ie.\n"
-               "\t2 - Put the available connected line number in the display ie.\n"
-               "\t3 - Put the available connected line name and number in the display ie." },
-       { "display_setup", MISDN_CFG_DISPLAY_SETUP, MISDN_CTYPE_INT, "0", NONE,
-               "Put a display ie in the SETUP message containing the following\n"
-               "\tinformation if it is available (nt port only):\n"
-               "\n"
-               "\t0 - Do not put the caller information in the display ie.\n"
-               "\t1 - Put the available caller name in the display ie.\n"
-               "\t2 - Put the available caller number in the display ie.\n"
-               "\t3 - Put the available caller name and number in the display ie." },
-       { "always_immediate", MISDN_CFG_ALWAYS_IMMEDIATE, MISDN_CTYPE_BOOL, "no", NONE,
-               "Enable this to get into the s dialplan-extension.\n"
-               "\tThere you can use DigitTimeout if you can't or don't want to use\n"
-               "\tisdn overlap dial.\n"
-               "\tNOTE: This will jump into the s extension for every exten!" },
-       { "nodialtone", MISDN_CFG_NODIALTONE, MISDN_CTYPE_BOOL, "no", NONE,
-               "Enable this to prevent chan_misdn to generate the dialtone\n"
-               "\tThis makes only sense together with the always_immediate=yes option\n"
-               "\tto generate your own dialtone with Playtones or so." },
-       { "immediate", MISDN_CFG_IMMEDIATE, MISDN_CTYPE_BOOL, "no", NONE,
-               "Enable this if you want callers which called exactly the base\n"
-               "\tnumber (so no extension is set) to jump into the s extension.\n"
-               "\tIf the user dials something more, it jumps to the correct extension\n"
-               "\tinstead." },
-       { "senddtmf", MISDN_CFG_SENDDTMF, MISDN_CTYPE_BOOL, "no", NONE,
-               "Enable this if we should produce DTMF Tones ourselves." },
-       { "astdtmf", MISDN_CFG_ASTDTMF, MISDN_CTYPE_BOOL, "no", NONE,
-               "Enable this if you want to use the Asterisk dtmf detector\n"
-               "instead of the mISDN_dsp/hfcmulti one."
-               },
-       { "hold_allowed", MISDN_CFG_HOLD_ALLOWED, MISDN_CTYPE_BOOL, "no", NONE,
-               "Enable this to have support for hold and retrieve." },
-       { "early_bconnect", MISDN_CFG_EARLY_BCONNECT, MISDN_CTYPE_BOOL, "yes", NONE,
-               "Disable this if you don't mind correct handling of Progress Indicators." },
-       { "incoming_early_audio", MISDN_CFG_INCOMING_EARLY_AUDIO, MISDN_CTYPE_BOOL, "no", NONE,
-               "Turn this on if you like to send Tone Indications to a Incoming\n"
-               "\tisdn channel on a TE Port. Rarely used, only if the Telco allows\n"
-               "\tyou to send indications by yourself, normally the Telco sends the\n"
-               "\tindications to the remote party." },
-       { "echocancel", MISDN_CFG_ECHOCANCEL, MISDN_CTYPE_BOOLINT, "0", 128,
-               "This enables echo cancellation with the given number of taps.\n"
-               "\tBe aware: Move this setting only to outgoing portgroups!\n"
-               "\tA value of zero turns echo cancellation off.\n"
-               "\n"
-               "\tPossible values are: 0,32,64,128,256,yes(=128),no(=0)" },
-#ifdef MISDN_1_2
-       { "pipeline", MISDN_CFG_PIPELINE, MISDN_CTYPE_STR, NO_DEFAULT, NONE,
-               "Set the configuration string for the mISDN dsp pipeline.\n"
-               "\n"
-               "\tExample for enabling the mg2 echo cancellation module with deftaps\n"
-               "\tset to 128:\n"
-               "\t\tmg2ec(deftaps=128)" },
-#endif
-#ifdef WITH_BEROEC
-       { "bnechocancel", MISDN_CFG_BNECHOCANCEL, MISDN_CTYPE_BOOLINT, "yes", 64,
-               "echotail in ms (1-200)" },
-       { "bnec_antihowl", MISDN_CFG_BNEC_ANTIHOWL, MISDN_CTYPE_INT, "0", NONE,
-               "Use antihowl" },
-       { "bnec_nlp", MISDN_CFG_BNEC_NLP, MISDN_CTYPE_BOOL, "yes", NONE,
-               "Nonlinear Processing (much faster adaption)" },
-       { "bnec_zerocoeff", MISDN_CFG_BNEC_ZEROCOEFF, MISDN_CTYPE_BOOL, "no", NONE,
-               "ZeroCoeffeciens" },
-       { "bnec_tonedisabler", MISDN_CFG_BNEC_TD, MISDN_CTYPE_BOOL, "no", NONE,
-               "Disable Tone" },
-       { "bnec_adaption", MISDN_CFG_BNEC_ADAPT, MISDN_CTYPE_INT, "1", NONE,
-               "Adaption mode (0=no,1=full,2=fast)" },
-#endif
-       { "need_more_infos", MISDN_CFG_NEED_MORE_INFOS, MISDN_CTYPE_BOOL, "0", NONE,
-               "Send Setup_Acknowledge on incoming calls anyway (instead of PROCEEDING),\n"
-               "\tthis requests additional Infos, so we can waitfordigits without much\n"
-               "\tissues. This works only for PTP Ports" },
-       { "noautorespond_on_setup", MISDN_CFG_NOAUTORESPOND_ON_SETUP, MISDN_CTYPE_BOOL, "0", NONE,
-               "Do not send SETUP_ACKNOWLEDGE or PROCEEDING automatically to the calling Party.\n"
-               "Instead we directly jump into the dialplan. This might be useful for fast call\n"
-               "rejection, or for some broken switches, that need hangup causes like busy in the.\n"
-               "RELEASE_COMPLETE Message, instead of the DISCONNECT Message."},
-       { "jitterbuffer", MISDN_CFG_JITTERBUFFER, MISDN_CTYPE_INT, "4000", NONE,
-               "The jitterbuffer." },
-       { "jitterbuffer_upper_threshold", MISDN_CFG_JITTERBUFFER_UPPER_THRESHOLD, MISDN_CTYPE_INT, "0", NONE,
-               "Change this threshold to enable dejitter functionality." },
-       { "callgroup", MISDN_CFG_CALLGROUP, MISDN_CTYPE_ASTGROUP, NO_DEFAULT, NONE,
-               "Callgroup." },
-       { "pickupgroup", MISDN_CFG_PICKUPGROUP, MISDN_CTYPE_ASTGROUP, NO_DEFAULT, NONE,
-               "Pickupgroup." },
-       { "namedcallgroup", MISDN_CFG_NAMEDCALLGROUP, MISDN_CTYPE_ASTNAMEDGROUP, NO_DEFAULT, NONE,
-               "Named callgroup." },
-       { "namedpickupgroup", MISDN_CFG_NAMEDPICKUPGROUP, MISDN_CTYPE_ASTNAMEDGROUP, NO_DEFAULT, NONE,
-               "Named pickupgroup." },
-       { "max_incoming", MISDN_CFG_MAX_IN, MISDN_CTYPE_INT, "-1", NONE,
-               "Defines the maximum amount of incoming calls per port for this group.\n"
-               "\tCalls which exceed the maximum will be marked with the channel variable\n"
-               "\tMAX_OVERFLOW. It will contain the amount of overflowed calls" },
-       { "max_outgoing", MISDN_CFG_MAX_OUT, MISDN_CTYPE_INT, "-1", NONE,
-               "Defines the maximum amount of outgoing calls per port for this group\n"
-               "\texceeding calls will be rejected" },
-
-       { "reject_cause", MISDN_CFG_REJECT_CAUSE, MISDN_CTYPE_INT, "21", NONE,
-               "Defines the cause with which a 3. call is rejected on PTMP BRI."},
-       { "faxdetect", MISDN_CFG_FAXDETECT, MISDN_CTYPE_STR, "no", NONE,
-               "Setup fax detection:\n"
-               "\t    no        - no fax detection\n"
-               "\t    incoming  - fax detection for incoming calls\n"
-               "\t    outgoing  - fax detection for outgoing calls\n"
-               "\t    both      - fax detection for incoming and outgoing calls\n"
-               "\tAdd +nojump to your value (i.e. faxdetect=both+nojump) if you don't want to jump into the\n"
-               "\tfax-extension but still want to detect the fax and prepare the channel for fax transfer." },
-       { "faxdetect_timeout", MISDN_CFG_FAXDETECT_TIMEOUT, MISDN_CTYPE_INT, "5", NONE,
-               "Number of seconds the fax detection should do its job. After the given period of time,\n"
-               "\twe assume that it's not a fax call and save some CPU time by turning off fax detection.\n"
-               "\tSet this to 0 if you don't want a timeout (never stop detecting)." },
-       { "faxdetect_context", MISDN_CFG_FAXDETECT_CONTEXT, MISDN_CTYPE_STR, NO_DEFAULT, NONE,
-               "Context to jump into if we detect a fax. Don't set this if you want to stay in the current context." },
-       { "l1watcher_timeout", MISDN_CFG_L1_TIMEOUT, MISDN_CTYPE_BOOLINT, "0", 4,
-               "Monitors L1 of the port.  If L1 is down it tries\n"
-               "\tto bring it up.  The polling timeout is given in seconds.\n"
-               "\tSetting the value to 0 disables monitoring L1 of the port.\n"
-               "\n"
-               "\tThis option is only read at chan_misdn loading time.\n"
-               "\tYou need to unload and load chan_misdn to change the\n"
-               "\tvalue.  An asterisk restart will also do the trick." },
-       { "overlapdial", MISDN_CFG_OVERLAP_DIAL, MISDN_CTYPE_BOOLINT, "0", 4,
-               "Enables overlap dial for the given amount of seconds.\n"
-               "\tPossible values are positive integers or:\n"
-               "\t   yes (= 4 seconds)\n"
-               "\t   no  (= 0 seconds = disabled)" },
-       { "nttimeout", MISDN_CFG_NTTIMEOUT, MISDN_CTYPE_BOOL, "no", NONE ,
-               "Set this to yes if you want calls disconnected in overlap mode\n"
-               "\twhen a timeout happens." },
-       { "bridging", MISDN_CFG_BRIDGING, MISDN_CTYPE_BOOL, "yes", NONE,
-               "Set this to yes/no, default is yes.\n"
-               "This can be used to have bridging enabled in general and to\n"
-               "disable it for specific ports. It makes sense to disable\n"
-               "bridging on NT Port where you plan to use the HOLD/RETRIEVE\n"
-               "features with ISDN phones." },
-       { "msns", MISDN_CFG_MSNS, MISDN_CTYPE_MSNLIST, "*", NONE,
-               "MSN's for TE ports, listen on those numbers on the above ports, and\n"
-               "\tindicate the incoming calls to Asterisk.\n"
-               "\tHere you can give a comma separated list, or simply an '*' for any msn." },
-       { "cc_request_retention", MISDN_CFG_CC_REQUEST_RETENTION, MISDN_CTYPE_BOOL, "yes", NONE,
-               "Enable/Disable call-completion request retention support (ptp)." },
-};
-
-static const struct misdn_cfg_spec gen_spec[] = {
-       { "debug", MISDN_GEN_DEBUG, MISDN_CTYPE_INT, "0", NONE,
-               "Sets the debugging flag:\n"
-               "\t0 - No Debug\n"
-               "\t1 - mISDN Messages and * - Messages, and * - State changes\n"
-               "\t2 - Messages + Message specific Informations (e.g. bearer capability)\n"
-               "\t3 - very Verbose, the above + lots of Driver specific infos\n"
-               "\t4 - even more Verbose than 3" },
-#ifndef MISDN_1_2
-       { "misdn_init", MISDN_GEN_MISDN_INIT, MISDN_CTYPE_STR, "/etc/misdn-init.conf", NONE,
-               "Set the path to the misdn-init.conf (for nt_ptp mode checking)." },
-#endif
-       { "tracefile", MISDN_GEN_TRACEFILE, MISDN_CTYPE_STR, "/var/log/asterisk/misdn.log", NONE,
-               "Set the path to the massively growing trace file, if you want that." },
-       { "bridging", MISDN_GEN_BRIDGING, MISDN_CTYPE_BOOL, "yes", NONE,
-               "Set this to yes if you want mISDN_dsp to bridge the calls in HW." },
-       { "stop_tone_after_first_digit", MISDN_GEN_STOP_TONE, MISDN_CTYPE_BOOL, "yes", NONE,
-               "Stops dialtone after getting first digit on NT Port." },
-       { "append_digits2exten", MISDN_GEN_APPEND_DIGITS2EXTEN, MISDN_CTYPE_BOOL, "yes", NONE,
-               "Whether to append overlapdialed Digits to Extension or not." },
-       { "dynamic_crypt", MISDN_GEN_DYNAMIC_CRYPT, MISDN_CTYPE_BOOL, "no", NONE,
-               "Whether to look out for dynamic crypting attempts." },
-       { "crypt_prefix", MISDN_GEN_CRYPT_PREFIX, MISDN_CTYPE_STR, NO_DEFAULT, NONE,
-               "What is used for crypting Protocol." },
-       { "crypt_keys", MISDN_GEN_CRYPT_KEYS, MISDN_CTYPE_STR, NO_DEFAULT, NONE,
-               "Keys for cryption, you reference them in the dialplan\n"
-               "\tLater also in dynamic encr." },
-       { "ntkeepcalls", MISDN_GEN_NTKEEPCALLS, MISDN_CTYPE_BOOL, "no", NONE,
-               "avoid dropping calls if the L2 goes down. some Nortel pbx\n"
-               "do put down the L2/L1 for some milliseconds even if there\n"
-               "are running calls. with this option you can avoid dropping them" },
-       { "ntdebugflags", MISDN_GEN_NTDEBUGFLAGS, MISDN_CTYPE_INT, "0", NONE,
-               "No description yet."},
-       { "ntdebugfile", MISDN_GEN_NTDEBUGFILE, MISDN_CTYPE_STR, "/var/log/misdn-nt.log", NONE,
-               "No description yet." }
-};
-
-
-/* array of port configs, default is at position 0. */
-static union misdn_cfg_pt **port_cfg;
-/* max number of available ports, is set on init */
-static int max_ports;
-/* general config */
-static union misdn_cfg_pt *general_cfg;
-/* storing the ptp flag separated to save memory */
-static int *ptp;
-/* maps enum config elements to array positions */
-static int *map;
-
-static ast_mutex_t config_mutex;
-
-#define CLI_ERROR(name, value, section) ({ \
-       ast_log(LOG_WARNING, "misdn.conf: \"%s=%s\" (section: %s) invalid or out of range. " \
-               "Please edit your misdn.conf and then do a \"misdn reload\".\n", name, value, section); \
-})
-
-static int _enum_array_map (void)
-{
-       int i, j, ok;
-
-       for (i = MISDN_CFG_FIRST + 1; i < MISDN_CFG_LAST; ++i) {
-               if (i == MISDN_CFG_PTP)
-                       continue;
-               ok = 0;
-               for (j = 0; j < NUM_PORT_ELEMENTS; ++j) {
-                       if (port_spec[j].elem == i) {
-                               map[i] = j;
-                               ok = 1;
-                               break;
-                       }
-               }
-               if (!ok) {
-                       ast_log(LOG_WARNING, "Enum element %d in misdn_cfg_elements (port section) has no corresponding element in the config struct!\n", i);
-                       return -1;
-               }
-       }
-       for (i = MISDN_GEN_FIRST + 1; i < MISDN_GEN_LAST; ++i) {
-               ok = 0;
-               for (j = 0; j < NUM_GEN_ELEMENTS; ++j) {
-                       if (gen_spec[j].elem == i) {
-                               map[i] = j;
-                               ok = 1;
-                               break;
-                       }
-               }
-               if (!ok) {
-                       ast_log(LOG_WARNING, "Enum element %d in misdn_cfg_elements (general section) has no corresponding element in the config struct!\n", i);
-                       return -1;
-               }
-       }
-       return 0;
-}
-
-static int get_cfg_position (const char *name, int type)
-{
-       int i;
-
-       switch (type) {
-       case PORT_CFG:
-               for (i = 0; i < NUM_PORT_ELEMENTS; ++i) {
-                       if (!strcasecmp(name, port_spec[i].name))
-                               return i;
-               }
-               break;
-       case GEN_CFG:
-               for (i = 0; i < NUM_GEN_ELEMENTS; ++i) {
-                       if (!strcasecmp(name, gen_spec[i].name))
-                               return i;
-               }
-       }
-
-       return -1;
-}
-
-static inline void misdn_cfg_lock (void)
-{
-       ast_mutex_lock(&config_mutex);
-}
-
-static inline void misdn_cfg_unlock (void)
-{
-       ast_mutex_unlock(&config_mutex);
-}
-
-static void _free_msn_list (struct msn_list* iter)
-{
-       if (iter->next)
-               _free_msn_list(iter->next);
-       if (iter->msn)
-               ast_free(iter->msn);
-       ast_free(iter);
-}
-
-static void _free_port_cfg (void)
-{
-       int i, j;
-       int gn = map[MISDN_CFG_GROUPNAME];
-       union misdn_cfg_pt* free_list[max_ports + 2];
-
-       memset(free_list, 0, sizeof(free_list));
-       free_list[0] = port_cfg[0];
-       for (i = 1; i <= max_ports; ++i) {
-               if (port_cfg[i][gn].str) {
-                       /* we always have a groupname in the non-default case, so this is fine */
-                       for (j = 1; j <= max_ports; ++j) {
-                               if (free_list[j] && free_list[j][gn].str == port_cfg[i][gn].str)
-                                       break;
-                               else if (!free_list[j]) {
-                                       free_list[j] = port_cfg[i];
-                                       break;
-                               }
-                       }
-               }
-       }
-       for (j = 0; free_list[j]; ++j) {
-               for (i = 0; i < NUM_PORT_ELEMENTS; ++i) {
-                       if (free_list[j][i].any) {
-                               if (port_spec[i].type == MISDN_CTYPE_MSNLIST) {
-                                       _free_msn_list(free_list[j][i].ml);
-                               } else if (port_spec[i].type == MISDN_CTYPE_ASTNAMEDGROUP) {
-                                       ast_unref_namedgroups(free_list[j][i].namgrp);
-                               } else {
-                                       ast_free(free_list[j][i].any);
-                               }
-                       }
-               }
-       }
-}
-
-static void _free_general_cfg (void)
-{
-       int i;
-
-       for (i = 0; i < NUM_GEN_ELEMENTS; i++)
-               if (general_cfg[i].any)
-                       ast_free(general_cfg[i].any);
-}
-
-void misdn_cfg_get(int port, enum misdn_cfg_elements elem, void *buf, int bufsize)
-{
-       int place;
-
-       if ((elem < MISDN_CFG_LAST) && !misdn_cfg_is_port_valid(port)) {
-               memset(buf, 0, bufsize);
-               ast_log(LOG_WARNING, "Invalid call to misdn_cfg_get! Port number %d is not valid.\n", port);
-               return;
-       }
-
-       misdn_cfg_lock();
-       if (elem == MISDN_CFG_PTP) {
-               if (!memcpy(buf, &ptp[port], (bufsize > ptp[port]) ? sizeof(ptp[port]) : bufsize))
-                       memset(buf, 0, bufsize);
-       } else {
-               if ((place = map[elem]) < 0) {
-                       memset(buf, 0, bufsize);
-                       ast_log(LOG_WARNING, "Invalid call to misdn_cfg_get! Invalid element (%d) requested.\n", elem);
-               } else {
-                       if (elem < MISDN_CFG_LAST) {
-                               switch (port_spec[place].type) {
-                               case MISDN_CTYPE_STR:
-                                       if (port_cfg[port][place].str) {
-                                               ast_copy_string(buf, port_cfg[port][place].str, bufsize);
-                                       } else if (port_cfg[0][place].str) {
-                                               ast_copy_string(buf, port_cfg[0][place].str, bufsize);
-                                       } else
-                                               memset(buf, 0, bufsize);
-                                       break;
-                               case MISDN_CTYPE_ASTNAMEDGROUP:
-                                       if (bufsize >= sizeof(struct ast_namedgroups *)) {
-                                               if (port_cfg[port][place].namgrp) {
-                                                       *(struct ast_namedgroups **)buf = port_cfg[port][place].namgrp;
-                                               } else if (port_cfg[0][place].namgrp) {
-                                                       *(struct ast_namedgroups **)buf = port_cfg[0][place].namgrp;
-                                               } else {
-                                                       *(struct ast_namedgroups **)buf = NULL;
-                                               }
-                                       }
-                                       break;
-                               default:
-                                       if (port_cfg[port][place].any)
-                                               memcpy(buf, port_cfg[port][place].any, bufsize);
-                                       else if (port_cfg[0][place].any)
-                                               memcpy(buf, port_cfg[0][place].any, bufsize);
-                                       else
-                                               memset(buf, 0, bufsize);
-                               }
-                       } else {
-                               switch (gen_spec[place].type) {
-                               case MISDN_CTYPE_STR:
-                                       ast_copy_string(buf, S_OR(general_cfg[place].str, ""), bufsize);
-                                       break;
-                               default:
-                                       if (general_cfg[place].any)
-                                               memcpy(buf, general_cfg[place].any, bufsize);
-                                       else
-                                               memset(buf, 0, bufsize);
-                               }
-                       }
-               }
-       }
-       misdn_cfg_unlock();
-}
-
-enum misdn_cfg_elements misdn_cfg_get_elem(const char *name)
-{
-       int pos;
-
-       /* here comes a hack to replace the (not existing) "name" element with the "ports" element */
-       if (!strcmp(name, "ports"))
-               return MISDN_CFG_GROUPNAME;
-       if (!strcmp(name, "name"))
-               return MISDN_CFG_FIRST;
-
-       pos = get_cfg_position(name, PORT_CFG);
-       if (pos >= 0)
-               return port_spec[pos].elem;
-
-       pos = get_cfg_position(name, GEN_CFG);
-       if (pos >= 0)
-               return gen_spec[pos].elem;
-
-       return MISDN_CFG_FIRST;
-}
-
-void misdn_cfg_get_name(enum misdn_cfg_elements elem, void *buf, int bufsize)
-{
-       struct misdn_cfg_spec *spec = NULL;
-       int place = map[elem];
-
-       /* the ptp hack */
-       if (elem == MISDN_CFG_PTP) {
-               memset(buf, 0, 1);
-               return;
-       }
-
-       /* here comes a hack to replace the (not existing) "name" element with the "ports" element */
-       if (elem == MISDN_CFG_GROUPNAME) {
-               if (!snprintf(buf, bufsize, "ports"))
-                       memset(buf, 0, 1);
-               return;
-       }
-
-       if ((elem > MISDN_CFG_FIRST) && (elem < MISDN_CFG_LAST))
-               spec = (struct misdn_cfg_spec *)port_spec;
-       else if ((elem > MISDN_GEN_FIRST) && (elem < MISDN_GEN_LAST))
-               spec = (struct misdn_cfg_spec *)gen_spec;
-
-       ast_copy_string(buf, spec ? spec[place].name : "", bufsize);
-}
-
-void misdn_cfg_get_desc (enum misdn_cfg_elements elem, void *buf, int bufsize, void *buf_default, int bufsize_default)
-{
-       int place = map[elem];
-       struct misdn_cfg_spec *spec = NULL;
-
-       /* here comes a hack to replace the (not existing) "name" element with the "ports" element */
-       if (elem == MISDN_CFG_GROUPNAME) {
-               ast_copy_string(buf, ports_description, bufsize);
-               if (buf_default && bufsize_default)
-                       memset(buf_default, 0, 1);
-               return;
-       }
-
-       if ((elem > MISDN_CFG_FIRST) && (elem < MISDN_CFG_LAST))
-               spec = (struct misdn_cfg_spec *)port_spec;
-       else if ((elem > MISDN_GEN_FIRST) && (elem < MISDN_GEN_LAST))
-               spec = (struct misdn_cfg_spec *)gen_spec;
-
-       if (!spec)
-               memset(buf, 0, 1);
-       else {
-               ast_copy_string(buf, spec[place].desc, bufsize);
-               if (buf_default && bufsize) {
-                       if (!strcmp(spec[place].def, NO_DEFAULT))
-                               memset(buf_default, 0, 1);
-                       else
-                               ast_copy_string(buf_default, spec[place].def, bufsize_default);
-               }
-       }
-}
-
-int misdn_cfg_is_msn_valid (int port, char* msn)
-{
-       int re = 0;
-       struct msn_list *iter;
-
-       if (!misdn_cfg_is_port_valid(port)) {
-               ast_log(LOG_WARNING, "Invalid call to misdn_cfg_is_msn_valid! Port number %d is not valid.\n", port);
-               return 0;
-       }
-
-       misdn_cfg_lock();
-       if (port_cfg[port][map[MISDN_CFG_MSNS]].ml)
-               iter = port_cfg[port][map[MISDN_CFG_MSNS]].ml;
-       else
-               iter = port_cfg[0][map[MISDN_CFG_MSNS]].ml;
-       for (; iter; iter = iter->next)
-               if (*(iter->msn) == '*' || ast_extension_match(iter->msn, msn)) {
-                       re = 1;
-                       break;
-               }
-       misdn_cfg_unlock();
-
-       return re;
-}
-
-int misdn_cfg_is_port_valid (int port)
-{
-       int gn = map[MISDN_CFG_GROUPNAME];
-
-       return (port >= 1 && port <= max_ports && port_cfg[port][gn].str);
-}
-
-int misdn_cfg_is_group_method (char *group, enum misdn_cfg_method meth)
-{
-       int i, re = 0;
-       char *method ;
-
-       misdn_cfg_lock();
-
-       method = port_cfg[0][map[MISDN_CFG_METHOD]].str;
-
-       for (i = 1; i <= max_ports; i++) {
-               if (port_cfg[i] && port_cfg[i][map[MISDN_CFG_GROUPNAME]].str) {
-                       if (!strcasecmp(port_cfg[i][map[MISDN_CFG_GROUPNAME]].str, group))
-                               method = (port_cfg[i][map[MISDN_CFG_METHOD]].str ?
-                                                 port_cfg[i][map[MISDN_CFG_METHOD]].str : port_cfg[0][map[MISDN_CFG_METHOD]].str);
-               }
-       }
-
-       if (method) {
-               switch (meth) {
-               case METHOD_STANDARD:           re = !strcasecmp(method, "standard");
-                                                                       break;
-               case METHOD_ROUND_ROBIN:        re = !strcasecmp(method, "round_robin");
-                                                                       break;
-               case METHOD_STANDARD_DEC:       re = !strcasecmp(method, "standard_dec");
-                                                                       break;
-               }
-       }
-       misdn_cfg_unlock();
-
-       return re;
-}
-
-/*!
- * \brief Generate a comma separated list of all active ports
- */
-void misdn_cfg_get_ports_string (char *ports)
-{
-       char tmp[16];
-       int l, i;
-       int gn = map[MISDN_CFG_GROUPNAME];
-
-       *ports = 0;
-
-       misdn_cfg_lock();
-       for (i = 1; i <= max_ports; i++) {
-               if (port_cfg[i][gn].str) {
-                       if (ptp[i])
-                               sprintf(tmp, "%dptp,", i);
-                       else
-                               sprintf(tmp, "%d,", i);
-                       strcat(ports, tmp);
-               }
-       }
-       misdn_cfg_unlock();
-
-       if ((l = strlen(ports))) {
-               /* Strip trailing ',' */
-               ports[l-1] = 0;
-       }
-}
-
-void misdn_cfg_get_config_string (int port, enum misdn_cfg_elements elem, char* buf, int bufsize)
-{
-       int place;
-       char tempbuf[BUFFERSIZE] = "";
-       struct msn_list *iter;
-
-       if ((elem < MISDN_CFG_LAST) && !misdn_cfg_is_port_valid(port)) {
-               *buf = 0;
-               ast_log(LOG_WARNING, "Invalid call to misdn_cfg_get_config_string! Port number %d is not valid.\n", port);
-               return;
-       }
-
-       place = map[elem];
-
-       misdn_cfg_lock();
-       if (elem == MISDN_CFG_PTP) {
-               snprintf(buf, bufsize, " -> ptp: %s", ptp[port] ? "yes" : "no");
-       }
-       else if (elem > MISDN_CFG_FIRST && elem < MISDN_CFG_LAST) {
-               switch (port_spec[place].type) {
-               case MISDN_CTYPE_INT:
-               case MISDN_CTYPE_BOOLINT:
-                       if (port_cfg[port][place].num)
-                               snprintf(buf, bufsize, " -> %s: %d", port_spec[place].name, *port_cfg[port][place].num);
-                       else if (port_cfg[0][place].num)
-                               snprintf(buf, bufsize, " -> %s: %d", port_spec[place].name, *port_cfg[0][place].num);
-                       else
-                               snprintf(buf, bufsize, " -> %s:", port_spec[place].name);
-                       break;
-               case MISDN_CTYPE_BOOL:
-                       if (port_cfg[port][place].num)
-                               snprintf(buf, bufsize, " -> %s: %s", port_spec[place].name, *port_cfg[port][place].num ? "yes" : "no");
-                       else if (port_cfg[0][place].num)
-                               snprintf(buf, bufsize, " -> %s: %s", port_spec[place].name, *port_cfg[0][place].num ? "yes" : "no");
-                       else
-                               snprintf(buf, bufsize, " -> %s:", port_spec[place].name);
-                       break;
-               case MISDN_CTYPE_ASTGROUP:
-                       if (port_cfg[port][place].grp)
-                               snprintf(buf, bufsize, " -> %s: %s", port_spec[place].name,
-                                                ast_print_group(tempbuf, sizeof(tempbuf), *port_cfg[port][place].grp));
-                       else if (port_cfg[0][place].grp)
-                               snprintf(buf, bufsize, " -> %s: %s", port_spec[place].name,
-                                                ast_print_group(tempbuf, sizeof(tempbuf), *port_cfg[0][place].grp));
-                       else
-                               snprintf(buf, bufsize, " -> %s:", port_spec[place].name);
-                       break;
-               case MISDN_CTYPE_ASTNAMEDGROUP:
-                       if (port_cfg[port][place].namgrp) {
-                               struct ast_str *tmp_str = ast_str_create(1024);
-                               if (tmp_str) {
-                                       snprintf(buf, bufsize, " -> %s: %s", port_spec[place].name,
-                                                       ast_print_namedgroups(&tmp_str, port_cfg[port][place].namgrp));
-                                       ast_free(tmp_str);
-                               }
-                       } else if (port_cfg[0][place].namgrp) {
-                               struct ast_str *tmp_str = ast_str_create(1024);
-                               if (tmp_str) {
-                                       snprintf(buf, bufsize, " -> %s: %s", port_spec[place].name,
-                                                       ast_print_namedgroups(&tmp_str, port_cfg[0][place].namgrp));
-                                       ast_free(tmp_str);
-                               }
-                       } else {
-                               snprintf(buf, bufsize, " -> %s:", port_spec[place].name);
-                       }
-                       break;
-               case MISDN_CTYPE_MSNLIST:
-                       if (port_cfg[port][place].ml)
-                               iter = port_cfg[port][place].ml;
-                       else
-                               iter = port_cfg[0][place].ml;
-                       if (iter) {
-                               for (; iter; iter = iter->next) {
-                                       strncat(tempbuf, iter->msn, sizeof(tempbuf) - strlen(tempbuf) - 1);
-                               }
-                               if (strlen(tempbuf) > 1) {
-                                       tempbuf[strlen(tempbuf)-2] = 0;
-                               }
-                       }
-                       snprintf(buf, bufsize, " -> msns: %s", *tempbuf ? tempbuf : "none");
-                       break;
-               case MISDN_CTYPE_STR:
-                       if ( port_cfg[port][place].str) {
-                               snprintf(buf, bufsize, " -> %s: %s", port_spec[place].name, port_cfg[port][place].str);
-                       } else if (port_cfg[0][place].str) {
-                               snprintf(buf, bufsize, " -> %s: %s", port_spec[place].name, port_cfg[0][place].str);
-                       } else {
-                               snprintf(buf, bufsize, " -> %s:", port_spec[place].name);
-                       }
-                       break;
-               }
-       } else if (elem > MISDN_GEN_FIRST && elem < MISDN_GEN_LAST) {
-               switch (gen_spec[place].type) {
-               case MISDN_CTYPE_INT:
-               case MISDN_CTYPE_BOOLINT:
-                       if (general_cfg[place].num)
-                               snprintf(buf, bufsize, " -> %s: %d", gen_spec[place].name, *general_cfg[place].num);
-                       else
-                               snprintf(buf, bufsize, " -> %s:", gen_spec[place].name);
-                       break;
-               case MISDN_CTYPE_BOOL:
-                       if (general_cfg[place].num)
-                               snprintf(buf, bufsize, " -> %s: %s", gen_spec[place].name, *general_cfg[place].num ? "yes" : "no");
-                       else
-                               snprintf(buf, bufsize, " -> %s:", gen_spec[place].name);
-                       break;
-               case MISDN_CTYPE_STR:
-                       if ( general_cfg[place].str) {
-                               snprintf(buf, bufsize, " -> %s: %s", gen_spec[place].name, general_cfg[place].str);
-                       } else {
-                               snprintf(buf, bufsize, " -> %s:", gen_spec[place].name);
-                       }
-                       break;
-               default:
-                       snprintf(buf, bufsize, " -> type of %s not handled yet", gen_spec[place].name);
-                       break;
-               }
-       } else {
-               *buf = 0;
-               ast_log(LOG_WARNING, "Invalid call to misdn_cfg_get_config_string! Invalid config element (%d) requested.\n", elem);
-       }
-       misdn_cfg_unlock();
-}
-
-int misdn_cfg_get_next_port (int port)
-{
-       int p = -1;
-       int gn = map[MISDN_CFG_GROUPNAME];
-
-       misdn_cfg_lock();
-       for (port++; port <= max_ports; port++) {
-               if (port_cfg[port][gn].str) {
-                       p = port;
-                       break;
-               }
-       }
-       misdn_cfg_unlock();
-
-       return p;
-}
-
-int misdn_cfg_get_next_port_spin (int port)
-{
-       int p = misdn_cfg_get_next_port(port);
-       return (p > 0) ? p : misdn_cfg_get_next_port(0);
-}
-
-static int _parse (union misdn_cfg_pt *dest, const char *value, enum misdn_cfg_type type, int boolint_def)
-{
-       int re = 0;
-       int len, tmp;
-       char *valtmp;
-       char *tmp2 = ast_strdupa(value);
-
-       switch (type) {
-       case MISDN_CTYPE_STR:
-               if (dest->str) {
-                       ast_free(dest->str);
-               }
-               if ((len = strlen(value))) {
-                       dest->str = ast_malloc((len + 1) * sizeof(char));
-                       strncpy(dest->str, value, len);
-                       dest->str[len] = 0;
-               } else {
-                       dest->str = ast_malloc(sizeof(char));
-                       dest->str[0] = 0;
-               }
-               break;
-       case MISDN_CTYPE_INT:
-       {
-               int res;
-
-               if (strchr(value,'x')) {
-                       res = sscanf(value, "%30x", &tmp);
-               } else {
-                       res = sscanf(value, "%30d", &tmp);
-               }
-               if (res) {
-                       if (!dest->num) {
-                               dest->num = ast_malloc(sizeof(int));
-                       }
-                       memcpy(dest->num, &tmp, sizeof(int));
-               } else
-                       re = -1;
-       }
-               break;
-       case MISDN_CTYPE_BOOL:
-               if (!dest->num) {
-                       dest->num = ast_malloc(sizeof(int));
-               }
-               *(dest->num) = (ast_true(value) ? 1 : 0);
-               break;
-       case MISDN_CTYPE_BOOLINT:
-               if (!dest->num) {
-                       dest->num = ast_malloc(sizeof(int));
-               }
-               if (sscanf(value, "%30d", &tmp)) {
-                       memcpy(dest->num, &tmp, sizeof(int));
-               } else {
-                       *(dest->num) = (ast_true(value) ? boolint_def : 0);
-               }
-               break;
-       case MISDN_CTYPE_MSNLIST:
-               for (valtmp = strsep(&tmp2, ","); valtmp; valtmp = strsep(&tmp2, ",")) {
-                       if ((len = strlen(valtmp))) {
-                               struct msn_list *ml = ast_malloc(sizeof(*ml));
-                               ml->msn = ast_calloc(len+1, sizeof(char));
-                               strncpy(ml->msn, valtmp, len);
-                               ml->next = dest->ml;
-                               dest->ml = ml;
-                       }
-               }
-               break;
-       case MISDN_CTYPE_ASTGROUP:
-               if (!dest->grp) {
-                       dest->grp = ast_malloc(sizeof(ast_group_t));
-               }
-               *(dest->grp) = ast_get_group(value);
-               break;
-       case MISDN_CTYPE_ASTNAMEDGROUP:
-               dest->namgrp = ast_get_namedgroups(value);
-               break;
-       }
-
-       return re;
-}
-
-static void _build_general_config (struct ast_variable *v)
-{
-       int pos;
-
-       for (; v; v = v->next) {
-               if (!ast_jb_read_conf(&global_jbconf, v->name, v->value))
-                       continue;
-               if (((pos = get_cfg_position(v->name, GEN_CFG)) < 0) ||
-                       (_parse(&general_cfg[pos], v->value, gen_spec[pos].type, gen_spec[pos].boolint_def) < 0))
-                       CLI_ERROR(v->name, v->value, "general");
-       }
-}
-
-static void _build_port_config (struct ast_variable *v, char *cat)
-{
-       int pos, i;
-       union misdn_cfg_pt cfg_tmp[NUM_PORT_ELEMENTS];
-       int cfg_for_ports[max_ports + 1];
-
-       if (!v || !cat)
-               return;
-
-       memset(cfg_tmp, 0, sizeof(cfg_tmp));
-       memset(cfg_for_ports, 0, sizeof(cfg_for_ports));
-
-       if (!strcasecmp(cat, "default")) {
-               cfg_for_ports[0] = 1;
-       }
-
-       if (((pos = get_cfg_position("name", PORT_CFG)) < 0) ||
-               (_parse(&cfg_tmp[pos], cat, port_spec[pos].type, port_spec[pos].boolint_def) < 0)) {
-               CLI_ERROR(v->name, v->value, cat);
-               return;
-       }
-
-       for (; v; v = v->next) {
-               if (!strcasecmp(v->name, "ports")) {
-                       char *token, *tmp = ast_strdupa(v->value);
-                       char ptpbuf[BUFFERSIZE] = "";
-                       int start, end;
-                       for (token = strsep(&tmp, ","); token; token = strsep(&tmp, ","), *ptpbuf = 0) {
-                               if (!*token)
-                                       continue;
-                               if (sscanf(token, "%30d-%30d%511s", &start, &end, ptpbuf) >= 2) {
-                                       for (; start <= end; start++) {
-                                               if (start <= max_ports && start > 0) {
-                                                       cfg_for_ports[start] = 1;
-                                                       ptp[start] = (strstr(ptpbuf, "ptp")) ? 1 : 0;
-                                               } else
-                                                       CLI_ERROR(v->name, v->value, cat);
-                                       }
-                               } else {
-                                       if (sscanf(token, "%30d%511s", &start, ptpbuf)) {
-                                               if (start <= max_ports && start > 0) {
-                                                       cfg_for_ports[start] = 1;
-                                                       ptp[start] = (strstr(ptpbuf, "ptp")) ? 1 : 0;
-                                               } else
-                                                       CLI_ERROR(v->name, v->value, cat);
-                                       } else
-                                               CLI_ERROR(v->name, v->value, cat);
-                               }
-                       }
-               } else {
-                       if (((pos = get_cfg_position(v->name, PORT_CFG)) < 0) ||
-                               (_parse(&cfg_tmp[pos], v->value, port_spec[pos].type, port_spec[pos].boolint_def) < 0))
-                               CLI_ERROR(v->name, v->value, cat);
-               }
-       }
-
-       for (i = 0; i < (max_ports + 1); ++i) {
-               if (i > 0 && cfg_for_ports[0]) {
-                       /* default category, will populate the port_cfg with additional port
-                       categories in subsequent calls to this function */
-                       memset(cfg_tmp, 0, sizeof(cfg_tmp));
-               }
-               if (cfg_for_ports[i]) {
-                       memcpy(port_cfg[i], cfg_tmp, sizeof(cfg_tmp));
-               }
-       }
-}
-
-void misdn_cfg_update_ptp (void)
-{
-#ifndef MISDN_1_2
-       char misdn_init[BUFFERSIZE];
-       char line[BUFFERSIZE];
-       FILE *fp;
-       char *tok, *p, *end;
-       int port;
-
-       misdn_cfg_get(0, MISDN_GEN_MISDN_INIT, &misdn_init, sizeof(misdn_init));
-
-       if (!ast_strlen_zero(misdn_init)) {
-               fp = fopen(misdn_init, "r");
-               if (fp) {
-                       while(fgets(line, sizeof(line), fp)) {
-                               if (!strncmp(line, "nt_ptp", 6)) {
-                                       for (tok = strtok_r(line,",=", &p);
-                                                tok;
-                                                tok = strtok_r(NULL,",=", &p)) {
-                                               port = strtol(tok, &end, 10);
-                                               if (end != tok && misdn_cfg_is_port_valid(port)) {
-                                                       misdn_cfg_lock();
-                                                       ptp[port] = 1;
-                                                       misdn_cfg_unlock();
-                                               }
-                                       }
-                               }
-                       }
-                       fclose(fp);
-               } else {
-                       ast_log(LOG_WARNING,"Couldn't open %s: %s\n", misdn_init, strerror(errno));
-               }
-       }
-#else
-       int i;
-       int proto;
-       char filename[128];
-       FILE *fp;
-
-       for (i = 1; i <= max_ports; ++i) {
-               snprintf(filename, sizeof(filename), "/sys/class/mISDN-stacks/st-%08x/protocol", i << 8);
-               fp = fopen(filename, "r");
-               if (!fp) {
-                       ast_log(LOG_WARNING, "Could not open %s: %s\n", filename, strerror(errno));
-                       continue;
-               }
-               if (fscanf(fp, "0x%08x", &proto) != 1)
-                       ast_log(LOG_WARNING, "Could not parse contents of %s!\n", filename);
-               else
-                       ptp[i] = proto & 1<<5 ? 1 : 0;
-               fclose(fp);
-       }
-#endif
-}
-
-static void _fill_defaults (void)
-{
-       int i;
-
-       for (i = 0; i < NUM_PORT_ELEMENTS; ++i) {
-               if (!port_cfg[0][i].any && strcasecmp(port_spec[i].def, NO_DEFAULT))
-                       _parse(&(port_cfg[0][i]), (char *)port_spec[i].def, port_spec[i].type, port_spec[i].boolint_def);
-       }
-       for (i = 0; i < NUM_GEN_ELEMENTS; ++i) {
-               if (!general_cfg[i].any && strcasecmp(gen_spec[i].def, NO_DEFAULT))
-                       _parse(&(general_cfg[i]), (char *)gen_spec[i].def, gen_spec[i].type, gen_spec[i].boolint_def);
-       }
-}
-
-void misdn_cfg_reload (void)
-{
-       misdn_cfg_init(0, 1);
-}
-
-void misdn_cfg_destroy (void)
-{
-       misdn_cfg_lock();
-
-       _free_port_cfg();
-       _free_general_cfg();
-
-       ast_free(port_cfg);
-       ast_free(general_cfg);
-       ast_free(ptp);
-       ast_free(map);
-
-       misdn_cfg_unlock();
-       ast_mutex_destroy(&config_mutex);
-}
-
-int misdn_cfg_init(int this_max_ports, int reload)
-{
-       char config[] = "misdn.conf";
-       char *cat, *p;
-       int i;
-       struct ast_config *cfg;
-       struct ast_variable *v;
-       struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
-
-       if (!(cfg = ast_config_load2(config, "chan_misdn", config_flags)) || cfg == CONFIG_STATUS_FILEINVALID) {
-               ast_log(LOG_WARNING, "missing or invalid file: misdn.conf\n");
-               return -1;
-       } else if (cfg == CONFIG_STATUS_FILEUNCHANGED)
-               return 0;
-
-       ast_mutex_init(&config_mutex);
-
-       /* Copy the default jb config over global_jbconf */
-       memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
-
-       misdn_cfg_lock();
-
-       if (this_max_ports) {
-               /* this is the first run */
-               max_ports = this_max_ports;
-               map = ast_calloc(MISDN_GEN_LAST + 1, sizeof(int));
-               if (_enum_array_map())
-                       return -1;
-               p = ast_calloc(1, (max_ports + 1) * sizeof(union misdn_cfg_pt *)
-                                                  + (max_ports + 1) * NUM_PORT_ELEMENTS * sizeof(union misdn_cfg_pt));
-               port_cfg = (union misdn_cfg_pt **)p;
-               p += (max_ports + 1) * sizeof(union misdn_cfg_pt *);
-               for (i = 0; i <= max_ports; ++i) {
-                       port_cfg[i] = (union misdn_cfg_pt *)p;
-                       p += NUM_PORT_ELEMENTS * sizeof(union misdn_cfg_pt);
-               }
-               general_cfg = ast_calloc(1, sizeof(union misdn_cfg_pt *) * NUM_GEN_ELEMENTS);
-               ptp = ast_calloc(max_ports + 1, sizeof(int));
-       }
-       else {
-               /* misdn reload */
-               _free_port_cfg();
-               _free_general_cfg();
-               memset(port_cfg[0], 0, NUM_PORT_ELEMENTS * sizeof(union misdn_cfg_pt) * (max_ports + 1));
-               memset(general_cfg, 0, sizeof(union misdn_cfg_pt *) * NUM_GEN_ELEMENTS);
-               memset(ptp, 0, sizeof(int) * (max_ports + 1));
-       }
-
-       cat = ast_category_browse(cfg, NULL);
-
-       while(cat) {
-               v = ast_variable_browse(cfg, cat);
-               if (!strcasecmp(cat, "general")) {
-                       _build_general_config(v);
-               } else {
-                       _build_port_config(v, cat);
-               }
-               cat = ast_category_browse(cfg, cat);
-       }
-
-       _fill_defaults();
-
-       misdn_cfg_unlock();
-       ast_config_destroy(cfg);
-
-       return 0;
-}
-
-struct ast_jb_conf *misdn_get_global_jbconf() {
-       return &global_jbconf;
-}
diff --git a/configs/samples/misdn.conf.sample b/configs/samples/misdn.conf.sample
deleted file mode 100644 (file)
index ca27c03..0000000
+++ /dev/null
@@ -1,537 +0,0 @@
-;
-; chan_misdn sample config
-;
-
-; general section:
-;
-; for debugging and general setup, things that are not bound to port groups
-;
-
-[general]
-;
-; Sets the Path to the misdn-init.conf (for nt_ptp mode checking)
-;
-misdn_init=/etc/misdn-init.conf
-
-; set debugging flag:
-;   0 - No Debug
-;   1 - mISDN Messages and * - Messages, and * - State changes
-;   2 - Messages + Message specific Informations (e.g. bearer capability)
-;   3 - very Verbose, the above + lots of Driver specific infos
-;   4 - even more Verbose than 3
-;
-; default value: 0
-;
-debug=0
-
-
-
-; set debugging file and flags for mISDNuser (NT-Stack)
-;
-; flags can be or'ed with the following values:
-;
-; DBGM_NET        0x00000001
-; DBGM_MSG        0x00000002
-; DBGM_FSM        0x00000004
-; DBGM_TEI        0x00000010
-; DBGM_L2         0x00000020
-; DBGM_L3         0x00000040
-; DBGM_L3DATA     0x00000080
-; DBGM_BC         0x00000100
-; DBGM_TONE       0x00000200
-; DBGM_BCDATA     0x00000400
-; DBGM_MAN        0x00001000
-; DBGM_APPL       0x00002000
-; DBGM_ISDN       0x00004000
-; DBGM_SOCK       0x00010000
-; DBGM_CONN       0x00020000
-; DBGM_CDATA      0x00040000
-; DBGM_DDATA      0x00080000
-; DBGM_SOUND      0x00100000
-; DBGM_SDATA      0x00200000
-; DBGM_TOPLEVEL   0x40000000
-; DBGM_ALL        0xffffffff
-;
-
-ntdebugflags=0
-ntdebugfile=/var/log/misdn-nt.log
-
-
-; some pbx systems do cut the L1 for some milliseconds, to avoid
-; dropping running calls, we can set this flag to yes and tell
-; mISDNuser not to drop the calls on L2_RELEASE
-ntkeepcalls=no
-
-; the big trace
-;
-; default value: [not set]
-;
-;tracefile=/var/log/asterisk/misdn.log
-
-
-; set to yes if you want mISDN_dsp to bridge the calls in HW
-;
-; default value: yes
-;
-bridging=no
-
-
-; stops dialtone after getting first digit on nt Port
-;
-; default value: yes
-;
-stop_tone_after_first_digit=yes
-
-; whether to append overlapdialed Digits to Extension or not
-;
-; default value: yes
-;
-append_digits2exten=yes
-
-;;; CRYPTION STUFF
-
-; Whether to look for dynamic crypting attempt
-;
-; default value: no
-;
-dynamic_crypt=no
-
-; crypt_prefix, what is used for crypting Protocol
-;
-; default value: [not set]
-;
-crypt_prefix=**
-
-; Keys for cryption, you reference them in the dialplan
-; later also in dynamic encr.
-;
-; default value: [not set]
-;
-crypt_keys=test,muh
-
-; ----------------------------- JITTER BUFFER CONFIGURATION --------------------------
-; jbenable = yes              ; Enables the use of a jitterbuffer on the receiving side of a
-                              ; SIP channel. Defaults to "no". An enabled jitterbuffer will
-                              ; be used only if the sending side can create and the receiving
-                              ; side can not accept jitter. The SIP channel can accept jitter,
-                              ; thus a jitterbuffer on the receive SIP side will be used only
-                              ; if it is forced and enabled.
-
-; jbforce = no                ; Forces the use of a jitterbuffer on the receive side of a SIP
-                              ; channel. Defaults to "no".
-
-; jbmaxsize = 200             ; Max length of the jitterbuffer in milliseconds.
-
-; jbresyncthreshold = 1000    ; Jump in the frame timestamps over which the jitterbuffer is
-                              ; resynchronized. Useful to improve the quality of the voice, with
-                              ; big jumps in/broken timestamps, usually sent from exotic devices
-                              ; and programs. Defaults to 1000.
-
-; jbimpl = fixed              ; Jitterbuffer implementation, used on the receiving side of a SIP
-                              ; channel. Two implementations are currently available - "fixed"
-                              ; (with size always equals to jbmaxsize) and "adaptive" (with
-                              ; variable size, actually the new jb of IAX2). Defaults to fixed.
-
-; jbtargetextra = 40          ; This option only affects the jb when 'jbimpl = adaptive' is set.
-                              ; The option represents the number of milliseconds by which the new
-                              ; jitter buffer will pad its size. the default is 40, so without
-                              ; modification, the new jitter buffer will set its size to the jitter
-                              ; value plus 40 milliseconds. increasing this value may help if your
-                              ; network normally has low jitter, but occasionally has spikes.
-
-; jblog = no                  ; Enables jitterbuffer frame logging. Defaults to "no".
-; ----------------------------------------------------------------------------------
-
-; users sections:
-;
-; name your sections as you wish but not "general" or "default" !
-; the sections are Groups, you can dial out in extensions.conf
-; with Dial(mISDN/g:extern/101) where extern is a section name,
-; chan_misdn tries every port in this section to find a
-; new free channel
-;
-; The default section is not a group section, it just contains config elements
-; which are inherited by group sections.
-;
-[default]
-
-; define your default context here
-;
-; default value: default
-;
-context=misdn
-
-; language
-;
-; default value: en
-;
-language=en
-
-;
-; This option specifies a default music on hold class to
-; use when put on hold if the channel's moh class was not
-; explicitly set with Set(CHANNEL(musicclass)=whatever) and
-; the peer channel did not suggest a class to use.
-;
-musicclass=default
-
-;
-; Either if we should produce DTMF Tones ourselves
-;
-senddtmf=yes
-
-;
-; If we should generate Ringing for chan_sip and others
-;
-far_alerting=no
-
-
-;
-; Here you can list which bearer capabilities should be allowed:
-;   all                  - allow any bearer capability
-;   speech               - allow speech
-;   3_1khz               - allow 3.1KHz audio
-;   digital_unrestricted - allow unrestricted digital
-;   digital_restricted   - allow restricted digital
-;   video                - allow video
-;
-; Example:
-; allowed_bearers=speech,3_1khz
-;
-allowed_bearers=all
-
-; Incoming number prefixes for the indicated Type-Of-Number.  These are
-; inserted before any number (caller, dialed, connected, redirecting,
-; redirection) received from the ISDN link if that number has the
-; corresponding Type-Of-Number.
-; See the dialplan options.
-;
-; default values:
-;    unknownprefix=
-;    internationalprefix=00
-;    nationalprefix=0
-;    netspecificprefix=
-;    subscriberprefix=
-;    abbreviatedprefix=
-;
-;unknownprefix=
-internationalprefix=00
-nationalprefix=0
-;netspecificprefix=
-;subscriberprefix=
-;abbreviatedprefix=
-
-; set rx/tx gains between -8 and 8 to change the RX/TX Gain
-;
-; default values: rxgain: 0
-;                 txgain: 0
-;
-rxgain=0
-txgain=0
-
-; some telcos especially in NL seem to need this set to yes, also in
-; switzerland this seems to be important
-;
-; default value: no
-;
-te_choose_channel=no
-
-
-
-;
-; Monitors L1 of the port.  If L1 is down it tries
-; to bring it up.  The polling timeout is given in seconds.
-; Setting the value to 0 disables monitoring L1 of the port.
-;
-; default value: 0
-;
-; This option is only read at chan_misdn loading time.
-; You need to unload and load chan_misdn to change the
-; value.  An asterisk restart will also do the trick.
-;
-l1watcher_timeout=0
-
-;
-; This option defines, if chan_misdn should check the L1 on  a PMP
-; before making a group call on it. The L1 may go down for PMP Ports
-; so we might need this.
-; But be aware! a broken or plugged off cable might be used for a group call
-; as well, since chan_misdn has no chance to distinguish if the L1 is down
-; because of a lost Link or because the Provider shut it down...
-;
-; default: no
-;
-pmp_l1_check=no
-
-
-;
-; in PMP this option defines which cause should be sent out to
-; the 3. caller. chan_misdn does not support callwaiting on TE
-; PMP side. This allows to modify the RELEASE_COMPLETE cause
-; at least.
-;
-reject_cause=16
-
-
-;
-; Send Setup_Acknowledge on incoming calls anyway (instead of PROCEEDING),
-; this requests additional Infos, so we can waitfordigits
-; without much issues. This works only for PTP Ports
-;
-; default value: no
-;
-need_more_infos=no
-
-
-;
-; set this to yes if you want to disconnect calls when a timeout occurs
-; for example during the overlapdial phase
-;
-nttimeout=no
-
-; Set the method to use for channel selection:
-;   standard     - Use the first free channel starting from the lowest number.
-;   standard_dec - Use the first free channel starting from the highest number.
-;   round_robin  - Use the round robin algorithm to select a channel. Use this
-;                  if you want to balance your load.
-;
-; default value: standard
-;
-method=standard
-
-
-; specify if chan_misdn should collect digits before going into the
-; dialplan, you can choose yes=4 Seconds, no, or specify the amount
-; of seconds you need;
-;
-overlapdial=yes
-
-;
-; dialplan means Type Of Number in ISDN Terms
-; There are different types of the dialplan:
-;
-; dialplan -> for outgoing call's dialed number
-; localdialplan -> for outgoing call's callerid
-;       (if -1 is set use the value from the asterisk channel)
-; cpndialplan -> for incoming call's connected party number sent to caller
-;       (if -1 is set use the value from the asterisk channel)
-;
-; dialplan options:
-;
-; 0 - unknown
-; 1 - International
-; 2 - National
-; 3 - Network-Specific
-; 4 - Subscriber
-; 5 - Abbreviated
-;
-; default value: 0
-;
-dialplan=0
-localdialplan=0
-cpndialplan=0
-
-
-
-;
-; turn this to no if you don't mind correct handling of Progress Indicators
-;
-early_bconnect=yes
-
-
-;
-; turn this on if you like to send Tone Indications to a Incoming
-; isdn channel on a TE Port. Rarely used, only if the Telco allows
-; you to send indications by yourself, normally the Telco sends the
-; indications to the remote party.
-;
-; default: no
-;
-incoming_early_audio=no
-
-; uncomment the following to get into s extension at extension conf
-; there you can use DigitTimeout if you can't or don't want to use
-; isdn overlap dial.
-; note: This will jump into the s exten for every exten!
-;
-; default value: no
-;
-;always_immediate=no
-
-;
-; set this to yes if you want to generate your own dialtone
-; with always_immediate=yes, else chan_misdn generates the dialtone
-;
-; default value: no
-;
-nodialtone=no
-
-
-; uncomment the following if you want callers which called exactly the
-; base number (so no extension is set) jump to the s extension.
-; if the user dials something more it jumps to the correct extension
-; instead
-;
-; default value: no
-;
-;immediate=no
-
-; uncomment the following to have hold and retrieve support
-;
-; default value: no
-;
-;hold_allowed=yes
-
-; Pickup and Callgroup
-;
-; default values: not set = 0
-; range: 0-63
-;
-;callgroup=1
-;pickupgroup=1
-
-; Named pickup groups and named call groups
-;
-; give a name to groups and configure any number of groups
-;
-;namedcallgroup=engineering,sales,netgroup,protgroup
-;namedpickupgroup=sales
-
-; Set the outgoing caller id to the value.
-;callerid="name" <number>
-
-;
-; these are the exact isdn screening and presentation indicators
-; if -1 is given for either value the presentation indicators are used
-; from asterisks CALLERPRES function.
-; s=0, p=0 -> callerid presented
-; s=1, p=1 -> callerid restricted (the remote end does not see it!)
-;
-; default values s=-1, p=-1
-presentation=-1
-screen=-1
-
-; Incoming calls will have a caller ID tag set to this value
-;
-;incoming_cid_tag = "asterisk"
-
-; With this set, you can automatically append the MSN of a party
-; to the cid_tag. Incoming calls have the dialed number appended
-; to the tag, and outgoing calls have the caller number appended
-; to the tag. An '_' is used to separate the tag from the
-; MSN.
-; Default is no.
-;
-;append_msn_to_cid_tag = no
-
-; Select what to do with outgoing COLP information on this port.
-;
-; 0 - Send out COLP information unaltered. (default)
-; 1 - Force COLP to restricted on all outgoing COLP information.
-; 2 - Do not send COLP information.
-outgoing_colp=0
-
-; Put a display ie in the CONNECT message containing the following
-; information if it is available (nt port only):
-;
-; 0 - Do not put the connected line information in the display ie.
-; 1 - Put the available connected line name in the display ie.
-; 2 - Put the available connected line number in the display ie.
-; 3 - Put the available connected line name and number in the display ie.
-;
-display_connected=0
-
-; Put a display ie in the SETUP message containing the following
-; information if it is available (nt port only):
-;
-; 0 - Do not put the caller information in the display ie.
-; 1 - Put the available caller name in the display ie.
-; 2 - Put the available caller number in the display ie.
-; 3 - Put the available caller name and number in the display ie.
-;
-display_setup=0
-
-; This enables echo cancellation with the given number of taps.
-; Be aware: Move this setting only to outgoing portgroups!
-; A value of zero turns echo cancellation off.
-;
-; possible values are: 0,32,64,128,256,yes(=128),no(=0)
-;
-; default value: no
-;
-;echocancel=no
-
-;
-; chan_misdns jitterbuffer, default 4000
-;
-jitterbuffer=4000
-
-;
-; change this threshold to enable dejitter functionality
-;
-jitterbuffer_upper_threshold=0
-
-
-;
-; change this to yes, if you want to bridge a mISDN data channel to
-; another channel type or to an application.
-;
-hdlc=no
-
-
-;
-; defines the maximum amount of incoming calls per port for
-; this group. Calls which exceed the maximum will be marked with
-; the channel variable MAX_OVERFLOW. It will contain the amount of
-; overflowed calls
-;
-max_incoming=-1
-
-;
-; defines the maximum amount of outgoing calls per port for this group
-; exceeding calls will be rejected
-;
-max_outgoing=-1
-
-;
-; Enable/disable the call-completion retention option support (ptp only).
-;
-; Note: To use the CCBS/CCNR supplementary service feature and other
-; supplementary services using FACILITY messages requires a
-; modified version of mISDN from:
-; http://svn.digium.com/svn/thirdparty/mISDN/trunk
-; http://svn.digium.com/svn/thirdparty/mISDNuser/trunk
-;
-cc_request_retention=yes
-
-[intern]
-; define your ports, e.g. 1,2 (depends on mISDN-driver loading order)
-ports=1,2
-; context where to go to when incoming Call on one of the above ports
-context=Intern
-
-[internPP]
-;
-; adding the postfix 'ptp' to a port number is obsolete now, chan_misdn
-; parses /etc/misdn-init.conf and sets the ptp mode to the corresponding
-; configs. For backwards compatibility you can still set ptp here.
-;
-ports=3
-
-[first_extern]
-; again port defs
-ports=4
-; again a context for incoming calls
-context=Extern1
-; msns for te ports, listen on those numbers on the above ports, and
-; indicate the incoming calls to asterisk
-; here you can give a comma separated list or simply an '*' for
-; any msn.
-msns=*
-
-; here an example with given msns
-[second_extern]
-ports=5
-context=Extern2
-callerid="Asterisk" <1234>
-msns=102,144,101,104
index 78ed4544071de5353d65c4af9143b60af34e6ebf..5778a04c0c4460e2654f80390233baebe43b93d7 100755 (executable)
--- a/configure
+++ b/configure
@@ -667,8 +667,6 @@ CONFIG_NETSNMP
 CONFIG_NEON29
 CONFIG_NEON
 CONFIG_MYSQLCLIENT
-PBX_MISDN_FAC_ERROR
-PBX_MISDN_FAC_RESULT
 ILBC_LIBS
 ILBC_CFLAGS
 ILBC_INTERNAL
@@ -750,10 +748,6 @@ PBX_FREETDS
 FREETDS_DIR
 FREETDS_INCLUDE
 FREETDS_LIB
-PBX_SUPPSERV
-SUPPSERV_DIR
-SUPPSERV_INCLUDE
-SUPPSERV_LIB
 PBX_RT
 RT_DIR
 RT_INCLUDE
@@ -1038,10 +1032,6 @@ PBX_MYSQLCLIENT
 MYSQLCLIENT_DIR
 MYSQLCLIENT_INCLUDE
 MYSQLCLIENT_LIB
-PBX_MISDN
-MISDN_DIR
-MISDN_INCLUDE
-MISDN_LIB
 LUA_VERSIONS
 PBX_LUA
 LUA_DIR
@@ -1088,10 +1078,6 @@ PBX_JACK
 JACK_DIR
 JACK_INCLUDE
 JACK_LIB
-PBX_ISDNNET
-ISDNNET_DIR
-ISDNNET_INCLUDE
-ISDNNET_LIB
 PBX_IODBC
 IODBC_DIR
 IODBC_INCLUDE
@@ -1394,7 +1380,6 @@ with_iksemel
 with_imap
 with_inotify
 with_iodbc
-with_isdnnet
 with_jack
 with_jansson
 with_uriparser
@@ -1405,7 +1390,6 @@ with_libedit
 with_libxml2
 with_libxslt
 with_lua
-with_misdn
 with_mysqlclient
 with_neon
 with_neon29
@@ -1436,7 +1420,6 @@ with_sqlite
 with_sqlite3
 with_srtp
 with_ssl
-with_suppserv
 with_tds
 with_timerfd
 with_tonezone
@@ -2165,7 +2148,6 @@ Optional Packages:
   --with-imap=PATH        use UW IMAP Toolkit files in PATH
   --with-inotify=PATH     use inotify support files in PATH
   --with-iodbc=PATH       use iODBC files in PATH
-  --with-isdnnet=PATH     use ISDN4Linux files in PATH
   --with-jack=PATH        use Jack Audio Connection Kit files in PATH
   --with-jansson=PATH     use Jansson JSON library files in PATH
   --with-uriparser=PATH   use uriparser library files in PATH
@@ -2177,7 +2159,6 @@ Optional Packages:
   --with-libxml2=PATH     use LibXML2 files in PATH
   --with-libxslt=PATH     use LibXSLT files in PATH
   --with-lua=PATH         use Lua files in PATH
-  --with-misdn=PATH       use mISDN user files in PATH
   --with-mysqlclient=PATH use MySQL client files in PATH
   --with-neon=PATH        use neon files in PATH
   --with-neon29=PATH      use neon29 files in PATH
@@ -2209,7 +2190,6 @@ Optional Packages:
   --with-sqlite3=PATH     use SQLite files in PATH
   --with-srtp=PATH        use Secure RTP files in PATH
   --with-ssl=PATH         use OpenSSL Secure Sockets Layer files in PATH
-  --with-suppserv=PATH    use mISDN Supplemental Services files in PATH
   --with-tds=PATH         use FreeTDS files in PATH
   --with-timerfd=PATH     use timerfd files in PATH
   --with-tonezone=PATH    use tonezone files in PATH
 
 
 
-    ISDNNET_DESCRIP="ISDN4Linux"
-    ISDNNET_OPTION="isdnnet"
-    PBX_ISDNNET=0
-
-# Check whether --with-isdnnet was given.
-if test "${with_isdnnet+set}" = set; then :
-  withval=$with_isdnnet;
-       case ${withval} in
-       n|no)
-       USE_ISDNNET=no
-       # -1 is a magic value used by menuselect to know that the package
-       # was disabled, other than 'not found'
-       PBX_ISDNNET=-1
-       ;;
-       y|ye|yes)
-       ac_mandatory_list="${ac_mandatory_list} ISDNNET"
-       ;;
-       *)
-       ISDNNET_DIR="${withval}"
-       ac_mandatory_list="${ac_mandatory_list} ISDNNET"
-       ;;
-       esac
-
-fi
-
-
-
-
-
-
-
-
     JACK_DESCRIP="Jack Audio Connection Kit"
     JACK_OPTION="jack"
     PBX_JACK=0
 
 
 
-    MISDN_DESCRIP="mISDN user"
-    MISDN_OPTION="misdn"
-    PBX_MISDN=0
-
-# Check whether --with-misdn was given.
-if test "${with_misdn+set}" = set; then :
-  withval=$with_misdn;
-       case ${withval} in
-       n|no)
-       USE_MISDN=no
-       # -1 is a magic value used by menuselect to know that the package
-       # was disabled, other than 'not found'
-       PBX_MISDN=-1
-       ;;
-       y|ye|yes)
-       ac_mandatory_list="${ac_mandatory_list} MISDN"
-       ;;
-       *)
-       MISDN_DIR="${withval}"
-       ac_mandatory_list="${ac_mandatory_list} MISDN"
-       ;;
-       esac
-
-fi
-
-
-
-
-
-
-
-
     MYSQLCLIENT_DESCRIP="MySQL client"
     MYSQLCLIENT_OPTION="mysqlclient"
     PBX_MYSQLCLIENT=0
@@ -12383,38 +12299,6 @@ PBX_RT=0
 
 
 
-    SUPPSERV_DESCRIP="mISDN Supplemental Services"
-    SUPPSERV_OPTION="suppserv"
-    PBX_SUPPSERV=0
-
-# Check whether --with-suppserv was given.
-if test "${with_suppserv+set}" = set; then :
-  withval=$with_suppserv;
-       case ${withval} in
-       n|no)
-       USE_SUPPSERV=no
-       # -1 is a magic value used by menuselect to know that the package
-       # was disabled, other than 'not found'
-       PBX_SUPPSERV=-1
-       ;;
-       y|ye|yes)
-       ac_mandatory_list="${ac_mandatory_list} SUPPSERV"
-       ;;
-       *)
-       SUPPSERV_DIR="${withval}"
-       ac_mandatory_list="${ac_mandatory_list} SUPPSERV"
-       ;;
-       esac
-
-fi
-
-
-
-
-
-
-
-
     FREETDS_DESCRIP="FreeTDS"
     FREETDS_OPTION="tds"
     PBX_FREETDS=0
 
 
 
-if test "x${PBX_MISDN}" != "x1" -a "${USE_MISDN}" != "no"; then
-   pbxlibdir=""
-   # if --with-MISDN=DIR has been specified, use it.
-   if test "x${MISDN_DIR}" != "x"; then
-      if test -d ${MISDN_DIR}/lib; then
-         pbxlibdir="-L${MISDN_DIR}/lib"
-      else
-         pbxlibdir="-L${MISDN_DIR}"
-      fi
-   fi
-
-      ast_ext_lib_check_save_CFLAGS="${CFLAGS}"
-      CFLAGS="${CFLAGS} "
-      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for mISDN_open in -lmISDN" >&5
-$as_echo_n "checking for mISDN_open in -lmISDN... " >&6; }
-if ${ac_cv_lib_mISDN_mISDN_open+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lmISDN ${pbxlibdir}  $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-char mISDN_open ();
-int
-main ()
-{
-return mISDN_open ();
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  ac_cv_lib_mISDN_mISDN_open=yes
-else
-  ac_cv_lib_mISDN_mISDN_open=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_mISDN_mISDN_open" >&5
-$as_echo "$ac_cv_lib_mISDN_mISDN_open" >&6; }
-if test "x$ac_cv_lib_mISDN_mISDN_open" = xyes; then :
-  AST_MISDN_FOUND=yes
-else
-  AST_MISDN_FOUND=no
-fi
-
-      CFLAGS="${ast_ext_lib_check_save_CFLAGS}"
-
-
-   # now check for the header.
-   if test "${AST_MISDN_FOUND}" = "yes"; then
-      MISDN_LIB="${pbxlibdir} -lmISDN "
-      # if --with-MISDN=DIR has been specified, use it.
-      if test "x${MISDN_DIR}" != "x"; then
-         MISDN_INCLUDE="-I${MISDN_DIR}/include"
-      fi
-      MISDN_INCLUDE="${MISDN_INCLUDE} "
-
-         # check for the header
-         ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
-         CPPFLAGS="${CPPFLAGS} ${MISDN_INCLUDE}"
-         ac_fn_c_check_header_mongrel "$LINENO" "mISDNuser/mISDNlib.h" "ac_cv_header_mISDNuser_mISDNlib_h" "$ac_includes_default"
-if test "x$ac_cv_header_mISDNuser_mISDNlib_h" = xyes; then :
-  MISDN_HEADER_FOUND=1
-else
-  MISDN_HEADER_FOUND=0
-fi
-
-
-         CPPFLAGS="${ast_ext_lib_check_saved_CPPFLAGS}"
-
-      if test "x${MISDN_HEADER_FOUND}" = "x0" ; then
-         MISDN_LIB=""
-         MISDN_INCLUDE=""
-      else
-
-         PBX_MISDN=1
-         cat >>confdefs.h <<_ACEOF
-#define HAVE_MISDN 1
-_ACEOF
-
-      fi
-   fi
-fi
-
-
-
-if test "${PBX_MISDN}" = 1; then
-
-if test "x${PBX_ISDNNET}" != "x1" -a "${USE_ISDNNET}" != "no"; then
-   pbxlibdir=""
-   # if --with-ISDNNET=DIR has been specified, use it.
-   if test "x${ISDNNET_DIR}" != "x"; then
-      if test -d ${ISDNNET_DIR}/lib; then
-         pbxlibdir="-L${ISDNNET_DIR}/lib"
-      else
-         pbxlibdir="-L${ISDNNET_DIR}"
-      fi
-   fi
-
-      ast_ext_lib_check_save_CFLAGS="${CFLAGS}"
-      CFLAGS="${CFLAGS} "
-      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for init_manager in -lisdnnet" >&5
-$as_echo_n "checking for init_manager in -lisdnnet... " >&6; }
-if ${ac_cv_lib_isdnnet_init_manager+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lisdnnet ${pbxlibdir} -lmISDN -lpthread $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-char init_manager ();
-int
-main ()
-{
-return init_manager ();
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  ac_cv_lib_isdnnet_init_manager=yes
-else
-  ac_cv_lib_isdnnet_init_manager=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_isdnnet_init_manager" >&5
-$as_echo "$ac_cv_lib_isdnnet_init_manager" >&6; }
-if test "x$ac_cv_lib_isdnnet_init_manager" = xyes; then :
-  AST_ISDNNET_FOUND=yes
-else
-  AST_ISDNNET_FOUND=no
-fi
-
-      CFLAGS="${ast_ext_lib_check_save_CFLAGS}"
-
-
-   # now check for the header.
-   if test "${AST_ISDNNET_FOUND}" = "yes"; then
-      ISDNNET_LIB="${pbxlibdir} -lisdnnet -lmISDN -lpthread"
-      # if --with-ISDNNET=DIR has been specified, use it.
-      if test "x${ISDNNET_DIR}" != "x"; then
-         ISDNNET_INCLUDE="-I${ISDNNET_DIR}/include"
-      fi
-      ISDNNET_INCLUDE="${ISDNNET_INCLUDE} "
-
-         # check for the header
-         ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
-         CPPFLAGS="${CPPFLAGS} ${ISDNNET_INCLUDE}"
-         ac_fn_c_check_header_mongrel "$LINENO" "mISDNuser/isdn_net.h" "ac_cv_header_mISDNuser_isdn_net_h" "$ac_includes_default"
-if test "x$ac_cv_header_mISDNuser_isdn_net_h" = xyes; then :
-  ISDNNET_HEADER_FOUND=1
-else
-  ISDNNET_HEADER_FOUND=0
-fi
-
-
-         CPPFLAGS="${ast_ext_lib_check_saved_CPPFLAGS}"
-
-      if test "x${ISDNNET_HEADER_FOUND}" = "x0" ; then
-         ISDNNET_LIB=""
-         ISDNNET_INCLUDE=""
-      else
-
-         PBX_ISDNNET=1
-         cat >>confdefs.h <<_ACEOF
-#define HAVE_ISDNNET 1
-_ACEOF
-
-      fi
-   fi
-fi
-
-
-
-if test "x${PBX_SUPPSERV}" != "x1" -a "${USE_SUPPSERV}" != "no"; then
-   pbxlibdir=""
-   # if --with-SUPPSERV=DIR has been specified, use it.
-   if test "x${SUPPSERV_DIR}" != "x"; then
-      if test -d ${SUPPSERV_DIR}/lib; then
-         pbxlibdir="-L${SUPPSERV_DIR}/lib"
-      else
-         pbxlibdir="-L${SUPPSERV_DIR}"
-      fi
-   fi
-
-      ast_ext_lib_check_save_CFLAGS="${CFLAGS}"
-      CFLAGS="${CFLAGS} "
-      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for encodeFac in -lsuppserv" >&5
-$as_echo_n "checking for encodeFac in -lsuppserv... " >&6; }
-if ${ac_cv_lib_suppserv_encodeFac+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lsuppserv ${pbxlibdir}  $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-char encodeFac ();
-int
-main ()
-{
-return encodeFac ();
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  ac_cv_lib_suppserv_encodeFac=yes
-else
-  ac_cv_lib_suppserv_encodeFac=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_suppserv_encodeFac" >&5
-$as_echo "$ac_cv_lib_suppserv_encodeFac" >&6; }
-if test "x$ac_cv_lib_suppserv_encodeFac" = xyes; then :
-  AST_SUPPSERV_FOUND=yes
-else
-  AST_SUPPSERV_FOUND=no
-fi
-
-      CFLAGS="${ast_ext_lib_check_save_CFLAGS}"
-
-
-   # now check for the header.
-   if test "${AST_SUPPSERV_FOUND}" = "yes"; then
-      SUPPSERV_LIB="${pbxlibdir} -lsuppserv "
-      # if --with-SUPPSERV=DIR has been specified, use it.
-      if test "x${SUPPSERV_DIR}" != "x"; then
-         SUPPSERV_INCLUDE="-I${SUPPSERV_DIR}/include"
-      fi
-      SUPPSERV_INCLUDE="${SUPPSERV_INCLUDE} "
-
-         # check for the header
-         ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
-         CPPFLAGS="${CPPFLAGS} ${SUPPSERV_INCLUDE}"
-         ac_fn_c_check_header_mongrel "$LINENO" "mISDNuser/suppserv.h" "ac_cv_header_mISDNuser_suppserv_h" "$ac_includes_default"
-if test "x$ac_cv_header_mISDNuser_suppserv_h" = xyes; then :
-  SUPPSERV_HEADER_FOUND=1
-else
-  SUPPSERV_HEADER_FOUND=0
-fi
-
-
-         CPPFLAGS="${ast_ext_lib_check_saved_CPPFLAGS}"
-
-      if test "x${SUPPSERV_HEADER_FOUND}" = "x0" ; then
-         SUPPSERV_LIB=""
-         SUPPSERV_INCLUDE=""
-      else
-
-         PBX_SUPPSERV=1
-         cat >>confdefs.h <<_ACEOF
-#define HAVE_SUPPSERV 1
-_ACEOF
-
-      fi
-   fi
-fi
-
-
-
-    if test "x${PBX_MISDN_FAC_RESULT}" != "x1"; then
-       { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Fac_RESULT in mISDNuser/suppserv.h" >&5
-$as_echo_n "checking for Fac_RESULT in mISDNuser/suppserv.h... " >&6; }
-       saved_cppflags="${CPPFLAGS}"
-       if test "x${MISDN_FAC_RESULT_DIR}" != "x"; then
-           MISDN_FAC_RESULT_INCLUDE="-I${MISDN_FAC_RESULT_DIR}/include"
-       fi
-       CPPFLAGS="${CPPFLAGS} ${MISDN_FAC_RESULT_INCLUDE}"
-
-       cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
- #include <mISDNuser/suppserv.h>
-int
-main ()
-{
-#if defined(Fac_RESULT)
-                               int foo = 0;
-                               #else
-                               int foo = bar;
-                               #endif
-                               0
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-     { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-               PBX_MISDN_FAC_RESULT=1
-
-$as_echo "#define HAVE_MISDN_FAC_RESULT 1" >>confdefs.h
-
-
-
-else
-     { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-       CPPFLAGS="${saved_cppflags}"
-    fi
-
-
-
-    if test "x${PBX_MISDN_FAC_ERROR}" != "x1"; then
-       { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Fac_ERROR in mISDNuser/suppserv.h" >&5
-$as_echo_n "checking for Fac_ERROR in mISDNuser/suppserv.h... " >&6; }
-       saved_cppflags="${CPPFLAGS}"
-       if test "x${MISDN_FAC_ERROR_DIR}" != "x"; then
-           MISDN_FAC_ERROR_INCLUDE="-I${MISDN_FAC_ERROR_DIR}/include"
-       fi
-       CPPFLAGS="${CPPFLAGS} ${MISDN_FAC_ERROR_INCLUDE}"
-
-       cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
- #include <mISDNuser/suppserv.h>
-int
-main ()
-{
-#if defined(Fac_ERROR)
-                               int foo = 0;
-                               #else
-                               int foo = bar;
-                               #endif
-                               0
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-     { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-               PBX_MISDN_FAC_ERROR=1
-
-$as_echo "#define HAVE_MISDN_FAC_ERROR 1" >>confdefs.h
-
-
-
-else
-     { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-       CPPFLAGS="${saved_cppflags}"
-    fi
-
-
-   ac_fn_c_check_header_mongrel "$LINENO" "linux/mISDNdsp.h" "ac_cv_header_linux_mISDNdsp_h" "$ac_includes_default"
-if test "x$ac_cv_header_linux_mISDNdsp_h" = xyes; then :
-
-cat >>confdefs.h <<_ACEOF
-#define MISDN_1_2 1
-_ACEOF
-
-fi
-
-
-   ac_fn_c_check_member "$LINENO" "Q931_info_t" "redirect_dn" "ac_cv_member_Q931_info_t_redirect_dn" "#include <mISDNuser/mISDNlib.h>
-"
-if test "x$ac_cv_member_Q931_info_t_redirect_dn" = xyes; then :
-
-else
-  PBX_MISDN=0
-fi
-
-fi
-
-
-
                if test "x${PBX_MYSQLCLIENT}" != "x1" -a "${USE_MYSQLCLIENT}" != "no"; then
                PBX_MYSQLCLIENT=0
                if test -n "$ac_tool_prefix"; then
index fa62e4ac05b2186eb34f46a4a4815d901fc9534b..2ae410e20dfd1d8c7934647d72f367407065cbb7 100644 (file)
@@ -498,7 +498,6 @@ AST_EXT_LIB_SETUP([IKSEMEL], [Iksemel Jabber], [iksemel])
 AST_EXT_LIB_SETUP([IMAP_TK], [UW IMAP Toolkit], [imap])
 AST_EXT_LIB_SETUP([INOTIFY], [inotify support], [inotify])
 AST_EXT_LIB_SETUP([IODBC], [iODBC], [iodbc])
-AST_EXT_LIB_SETUP([ISDNNET], [ISDN4Linux], [isdnnet])
 AST_EXT_LIB_SETUP([JACK], [Jack Audio Connection Kit], [jack])
 AST_EXT_LIB_SETUP([JANSSON], [Jansson JSON library], [jansson])
 AST_EXT_LIB_SETUP([URIPARSER], [uriparser library], [uriparser])
@@ -512,7 +511,6 @@ AST_EXT_LIB_SETUP([LIBXSLT], [LibXSLT], [libxslt])
 AST_EXT_LIB_SETUP_OPTIONAL([LIBXSLT_CLEANUP], [LibXSLT Library Cleanup Function], [LIBXSLT], [libxslt])
 AST_EXT_LIB_SETUP([LUA], [Lua], [lua])
 AC_ARG_VAR([LUA_VERSIONS],[A space separated list of target lua versions to test.])
-AST_EXT_LIB_SETUP([MISDN], [mISDN user], [misdn])
 AST_EXT_LIB_SETUP([MYSQLCLIENT], [MySQL client], [mysqlclient])
 AST_EXT_LIB_SETUP([NEON], [neon], [neon])
 AST_EXT_LIB_SETUP([NEON29], [neon29], [neon29])
@@ -594,7 +592,6 @@ AST_EXT_LIB_SETUP_OPTIONAL([SRTP_SHUTDOWN], [SRTP Library Shutdown Function], [S
 AST_EXT_LIB_SETUP_OPTIONAL([SRTP_GET_VERSION], [SRTP Library Version Function], [SRTP], [srtp])
 AST_EXT_LIB_SETUP([OPENSSL], [OpenSSL Secure Sockets Layer], [ssl])
 AST_EXT_LIB_SETUP_OPTIONAL([RT], [Realtime functions], [rt])
-AST_EXT_LIB_SETUP([SUPPSERV], [mISDN Supplemental Services], [suppserv])
 AST_EXT_LIB_SETUP([FREETDS], [FreeTDS], [tds])
 AST_EXT_LIB_SETUP([TIMERFD], [timerfd], [timerfd])
 AST_EXT_LIB_SETUP([TONEZONE], [tonezone], [tonezone])
@@ -2266,18 +2263,6 @@ AC_CHECK_FUNCS([kevent64])
 
 AST_EXT_LIB_CHECK([LDAP], [ldap], [ldap_initialize], [ldap.h])
 
-AST_EXT_LIB_CHECK([MISDN], [mISDN], [mISDN_open], [mISDNuser/mISDNlib.h])
-
-if test "${PBX_MISDN}" = 1; then
-   AST_EXT_LIB_CHECK([ISDNNET], [isdnnet], [init_manager], [mISDNuser/isdn_net.h], [-lmISDN -lpthread])
-   AST_EXT_LIB_CHECK([SUPPSERV], [suppserv], [encodeFac], [mISDNuser/suppserv.h])
-   AST_C_DEFINE_CHECK([MISDN_FAC_RESULT], [Fac_RESULT], [mISDNuser/suppserv.h])
-   AST_C_DEFINE_CHECK([MISDN_FAC_ERROR], [Fac_ERROR], [mISDNuser/suppserv.h])
-   AC_CHECK_HEADER([linux/mISDNdsp.h], [AC_DEFINE_UNQUOTED([MISDN_1_2], 1, [Build chan_misdn for mISDN 1.2 or later.])])
-   AC_CHECK_MEMBER([Q931_info_t.redirect_dn], [], [PBX_MISDN=0], [#include <mISDNuser/mISDNlib.h>])
-fi
-
-
 AST_EXT_TOOL_CHECK([MYSQLCLIENT], [mysql_config])
 
 if test "${PBX_MYSQLCLIENT}" = 1; then
diff --git a/doc/UPGRADE-staging/chan_misdn_removal.txt b/doc/UPGRADE-staging/chan_misdn_removal.txt
new file mode 100644 (file)
index 0000000..bb597dc
--- /dev/null
@@ -0,0 +1,6 @@
+Subject: chan_misdn
+Master-Only: True
+
+This module was deprecated in Asterisk 16
+and is now being removed in accordance with
+the Asterisk Module Deprecation policy.
index d61c85ca86c7008a21eecfe9a789d9a511a23b79..b9a6b6620470f777e9d1f84c522eb49d18731b02 100644 (file)
 /* Define to 1 if you have the `isascii' function. */
 #undef HAVE_ISASCII
 
-/* Define to 1 if you have the ISDN4Linux library. */
-#undef HAVE_ISDNNET
-
 /* Define to 1 if you have the Jack Audio Connection Kit library. */
 #undef HAVE_JACK
 
 /* Define to 1 if you have the `memset' function. */
 #undef HAVE_MEMSET
 
-/* Define to 1 if you have the mISDN user library. */
-#undef HAVE_MISDN
-
-/* Define if your system has the MISDN_FAC_ERROR headers. */
-#undef HAVE_MISDN_FAC_ERROR
-
-/* Define if your system has the MISDN_FAC_RESULT headers. */
-#undef HAVE_MISDN_FAC_RESULT
-
 /* Define to 1 if you have the `mkdir' function. */
 #undef HAVE_MKDIR
 
 /* Define to 1 if `uid' is a member of `struct ucred'. */
 #undef HAVE_STRUCT_UCRED_UID
 
-/* Define to 1 if you have the mISDN Supplemental Services library. */
-#undef HAVE_SUPPSERV
-
 /* Define to 1 if you have the `swapctl' function. */
 #undef HAVE_SWAPCTL
 
    slash. */
 #undef LSTAT_FOLLOWS_SLASHED_SYMLINK
 
-/* Build chan_misdn for mISDN 1.2 or later. */
-#undef MISDN_1_2
-
 /* Define to the address where bug reports for this package should be sent. */
 #undef PACKAGE_BUGREPORT
 
index 886a4093614cca1ae1da1238c26e63e5c661a783..a418752a603d1e5586506eebed78d7d1d62d68b1 100644 (file)
@@ -331,15 +331,6 @@ DAHDI_INCLUDE=@DAHDI_INCLUDE@
 ZLIB_INCLUDE=@ZLIB_INCLUDE@
 ZLIB_LIB=@ZLIB_LIB@
 
-ISDNNET_INCLUDE=@ISDNNET_INCLUDE@
-ISDNNET_LIB=@ISDNNET_LIB@
-
-MISDN_INCLUDE=@MISDN_INCLUDE@
-MISDN_LIB=@MISDN_LIB@
-
-SUPPSERV_INCLUDE=@SUPPSERV_INCLUDE@
-SUPPSERV_LIB=@SUPPSERV_LIB@
-
 CAP_LIB=@CAP_LIB@
 CAP_INCLUDE=@CAP_INCLUDE@