Sat Aug 6 00:39:23 2011

Asterisk developer's documentation


chan_dahdi.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 1999 - 2006, Digium, Inc.
00005  *
00006  * Mark Spencer <markster@digium.com>
00007  *
00008  * See http://www.asterisk.org for more information about
00009  * the Asterisk project. Please do not directly contact
00010  * any of the maintainers of this project for assistance;
00011  * the project provides a web site, mailing lists and IRC
00012  * channels for your use.
00013  *
00014  * This program is free software, distributed under the terms of
00015  * the GNU General Public License Version 2. See the LICENSE file
00016  * at the top of the source tree.
00017  */
00018 
00019 /*! \file
00020  *
00021  * \brief DAHDI Pseudo TDM interface 
00022  *
00023  * \author Mark Spencer <markster@digium.com>
00024  * 
00025  * Connects to the DAHDI telephony library as well as 
00026  * libpri. Libpri is optional and needed only if you are
00027  * going to use ISDN connections.
00028  *
00029  * You need to install libraries before you attempt to compile
00030  * and install the DAHDI channel.
00031  *
00032  * \par See also
00033  * \arg \ref Config_dahdi
00034  *
00035  * \ingroup channel_drivers
00036  *
00037  * \todo Deprecate the "musiconhold" configuration option post 1.4
00038  */
00039 
00040 /*** MODULEINFO
00041    <depend>res_smdi</depend>
00042    <depend>dahdi</depend>
00043    <depend>tonezone</depend>
00044    <depend>res_features</depend>
00045    <use>pri</use>
00046    <use>openr2</use>
00047  ***/
00048 
00049 #include "asterisk.h"
00050 
00051 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 313188 $")
00052 
00053 #include <stdio.h>
00054 #include <string.h>
00055 #if defined(__NetBSD__) || defined(__FreeBSD__)
00056 #include <pthread.h>
00057 #include <signal.h>
00058 #else
00059 #include <sys/signal.h>
00060 #endif
00061 #include <errno.h>
00062 #include <stdlib.h>
00063 #if !defined(SOLARIS) && !defined(__FreeBSD__)
00064 #include <stdint.h>
00065 #endif
00066 #include <unistd.h>
00067 #include <sys/ioctl.h>
00068 #include <math.h>
00069 #include <ctype.h>
00070 
00071 #ifdef HAVE_PRI
00072 #include <libpri.h>
00073 #endif
00074 
00075 #ifdef HAVE_OPENR2
00076 #include <openr2.h>
00077 #endif
00078 
00079 #include "asterisk/lock.h"
00080 #include "asterisk/channel.h"
00081 #include "asterisk/config.h"
00082 #include "asterisk/logger.h"
00083 #include "asterisk/module.h"
00084 #include "asterisk/pbx.h"
00085 #include "asterisk/options.h"
00086 #include "asterisk/file.h"
00087 #include "asterisk/ulaw.h"
00088 #include "asterisk/alaw.h"
00089 #include "asterisk/callerid.h"
00090 #include "asterisk/adsi.h"
00091 #include "asterisk/cli.h"
00092 #include "asterisk/cdr.h"
00093 #include "asterisk/features.h"
00094 #include "asterisk/musiconhold.h"
00095 #include "asterisk/say.h"
00096 #include "asterisk/tdd.h"
00097 #include "asterisk/app.h"
00098 #include "asterisk/dsp.h"
00099 #include "asterisk/astdb.h"
00100 #include "asterisk/manager.h"
00101 #include "asterisk/causes.h"
00102 #include "asterisk/term.h"
00103 #include "asterisk/utils.h"
00104 #include "asterisk/transcap.h"
00105 #include "asterisk/stringfields.h"
00106 #include "asterisk/abstract_jb.h"
00107 #include "asterisk/smdi.h"
00108 #include "asterisk/astobj.h"
00109 #define SMDI_MD_WAIT_TIMEOUT 1500 /* 1.5 seconds */
00110 
00111 #include "asterisk/dahdi_compat.h"
00112 #include "asterisk/tonezone_compat.h"
00113 
00114 /*! Global jitterbuffer configuration - by default, jb is disabled */
00115 static struct ast_jb_conf default_jbconf =
00116 {
00117    .flags = 0,
00118    .max_size = -1,
00119    .resync_threshold = -1,
00120    .impl = ""
00121 };
00122 static struct ast_jb_conf global_jbconf;
00123 
00124 #ifndef DAHDI_TONEDETECT
00125 /* Work around older code with no tone detect */
00126 #define DAHDI_EVENT_DTMFDOWN 0
00127 #define DAHDI_EVENT_DTMFUP 0
00128 #endif
00129 
00130 /* define this to send PRI user-user information elements */
00131 #undef SUPPORT_USERUSER
00132 
00133 /*! 
00134  * Define to make always pick a channel if allowed.  Useful for
00135  * testing channel shifting.
00136  */
00137 //#define ALWAYS_PICK_CHANNEL 1
00138 
00139 /*!
00140  * Define to force a RESTART on a channel that returns a cause
00141  * code of PRI_CAUSE_REQUESTED_CHAN_UNAVAIL(44).  If the cause
00142  * is because of a stuck channel on the peer and the channel is
00143  * always the next channel we pick for an outgoing call then
00144  * this can help.
00145  */
00146 #define FORCE_RESTART_UNAVAIL_CHANS    1
00147 
00148 /*!
00149  * \note Define ZHONE_HACK to cause us to go off hook and then back on hook when
00150  * the user hangs up to reset the state machine so ring works properly.
00151  * This is used to be able to support kewlstart by putting the zhone in
00152  * groundstart mode since their forward disconnect supervision is entirely
00153  * broken even though their documentation says it isn't and their support
00154  * is entirely unwilling to provide any assistance with their channel banks
00155  * even though their web site says they support their products for life.
00156  */
00157 /* #define ZHONE_HACK */
00158 
00159 /*! \note
00160  * Define if you want to check the hook state for an FXO (FXS signalled) interface
00161  * before dialing on it.  Certain FXO interfaces always think they're out of
00162  * service with this method however.
00163  */
00164 /* #define DAHDI_CHECK_HOOKSTATE */
00165 
00166 /*! \brief Typically, how many rings before we should send Caller*ID */
00167 #define DEFAULT_CIDRINGS 1
00168 
00169 #define AST_LAW(p) (((p)->law == DAHDI_LAW_ALAW) ? AST_FORMAT_ALAW : AST_FORMAT_ULAW)
00170 
00171 /*! \brief Signaling types that need to use MF detection should be placed in this macro */
00172 #define NEED_MFDETECT(p) (((p)->sig == SIG_FEATDMF) || ((p)->sig == SIG_FEATDMF_TA) || ((p)->sig == SIG_E911) || ((p)->sig == SIG_FGC_CAMA) || ((p)->sig == SIG_FGC_CAMAMF) || ((p)->sig == SIG_FEATB)) 
00173 
00174 static const char tdesc[] = "DAHDI Telephony Driver"
00175 #ifdef HAVE_PRI
00176                " w/PRI"
00177 #endif
00178 
00179 #ifdef HAVE_OPENR2
00180           " w/OPENR2"
00181 #endif
00182 ;
00183 
00184 #define SIG_EM    DAHDI_SIG_EM
00185 #define SIG_EMWINK   (0x0100000 | DAHDI_SIG_EM)
00186 #define SIG_FEATD (0x0200000 | DAHDI_SIG_EM)
00187 #define  SIG_FEATDMF (0x0400000 | DAHDI_SIG_EM)
00188 #define  SIG_FEATB   (0x0800000 | DAHDI_SIG_EM)
00189 #define  SIG_E911 (0x1000000 | DAHDI_SIG_EM)
00190 #define  SIG_FEATDMF_TA (0x2000000 | DAHDI_SIG_EM)
00191 #define  SIG_FGC_CAMA   (0x4000000 | DAHDI_SIG_EM)
00192 #define  SIG_FGC_CAMAMF (0x8000000 | DAHDI_SIG_EM)
00193 #define SIG_FXSLS DAHDI_SIG_FXSLS
00194 #define SIG_FXSGS DAHDI_SIG_FXSGS
00195 #define SIG_FXSKS DAHDI_SIG_FXSKS
00196 #define SIG_FXOLS DAHDI_SIG_FXOLS
00197 #define SIG_FXOGS DAHDI_SIG_FXOGS
00198 #define SIG_FXOKS DAHDI_SIG_FXOKS
00199 #define SIG_PRI      DAHDI_SIG_CLEAR
00200 #define SIG_MFCR2 DAHDI_SIG_CAS
00201 #define  SIG_SF      DAHDI_SIG_SF
00202 #define SIG_SFWINK   (0x0100000 | DAHDI_SIG_SF)
00203 #define SIG_SF_FEATD (0x0200000 | DAHDI_SIG_SF)
00204 #define  SIG_SF_FEATDMF (0x0400000 | DAHDI_SIG_SF)
00205 #define  SIG_SF_FEATB   (0x0800000 | DAHDI_SIG_SF)
00206 #define SIG_EM_E1 DAHDI_SIG_EM_E1
00207 #define SIG_GR303FXOKS  (0x0100000 | DAHDI_SIG_FXOKS)
00208 #define SIG_GR303FXSKS  (0x0100000 | DAHDI_SIG_FXSKS)
00209 
00210 #define NUM_SPANS       32
00211 #define NUM_DCHANS      4  /*!< No more than 4 d-channels */
00212 #define MAX_CHANNELS 672      /*!< No more than a DS3 per trunk group */
00213 
00214 #define CHAN_PSEUDO  -2
00215 
00216 #define DCHAN_PROVISIONED (1 << 0)
00217 #define DCHAN_NOTINALARM  (1 << 1)
00218 #define DCHAN_UP          (1 << 2)
00219 
00220 #define DCHAN_AVAILABLE (DCHAN_PROVISIONED | DCHAN_NOTINALARM | DCHAN_UP)
00221 
00222 /* Overlap dialing option types */
00223 #define DAHDI_OVERLAPDIAL_NONE 0
00224 #define DAHDI_OVERLAPDIAL_OUTGOING 1
00225 #define DAHDI_OVERLAPDIAL_INCOMING 2
00226 #define DAHDI_OVERLAPDIAL_BOTH (DAHDI_OVERLAPDIAL_INCOMING|DAHDI_OVERLAPDIAL_OUTGOING)
00227 
00228 static char defaultcic[64] = "";
00229 static char defaultozz[64] = "";
00230 
00231 static char progzone[10] = "";
00232 
00233 static int distinctiveringaftercid = 0;
00234 
00235 static int numbufs = 4;
00236 static int dtmfcid_level = 256;
00237 
00238 #ifdef HAVE_PRI
00239 static struct ast_channel inuse;
00240 #ifdef PRI_GETSET_TIMERS
00241 static int pritimers[PRI_MAX_TIMERS];
00242 #endif
00243 static int pridebugfd = -1;
00244 static char pridebugfilename[1024] = "";
00245 #endif
00246 
00247 /*! \brief Wait up to 16 seconds for first digit (FXO logic) */
00248 static int firstdigittimeout = 16000;
00249 
00250 /*! \brief How long to wait for following digits (FXO logic) */
00251 static int gendigittimeout = 8000;
00252 
00253 /*! \brief How long to wait for an extra digit, if there is an ambiguous match */
00254 static int matchdigittimeout = 3000;
00255 
00256 /*! \brief Protect the interface list (of dahdi_pvt's) */
00257 AST_MUTEX_DEFINE_STATIC(iflock);
00258 
00259 
00260 static int ifcount = 0;
00261 
00262 #ifdef HAVE_PRI
00263 AST_MUTEX_DEFINE_STATIC(pridebugfdlock);
00264 #endif
00265 
00266 /*! \brief Protect the monitoring thread, so only one process can kill or start it, and not
00267    when it's doing something critical. */
00268 AST_MUTEX_DEFINE_STATIC(monlock);
00269 
00270 /*! \brief This is the thread for the monitor which checks for input on the channels
00271    which are not currently in use. */
00272 static pthread_t monitor_thread = AST_PTHREADT_NULL;
00273 static ast_cond_t ss_thread_complete;
00274 AST_MUTEX_DEFINE_STATIC(ss_thread_lock);
00275 AST_MUTEX_DEFINE_STATIC(restart_lock);
00276 static int ss_thread_count = 0;
00277 static int num_restart_pending = 0;
00278 
00279 static int restart_monitor(void);
00280 
00281 static enum ast_bridge_result dahdi_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms);
00282 
00283 static int dahdi_sendtext(struct ast_channel *c, const char *text);
00284 
00285 #define SIG_PRI_LIB_HANDLE_CASES \
00286    SIG_PRI
00287 
00288 /*! \brief Avoid the silly dahdi_getevent which ignores a bunch of events */
00289 static inline int dahdi_get_event(int fd)
00290 {
00291    int j;
00292    if (ioctl(fd, DAHDI_GETEVENT, &j) == -1)
00293       return -1;
00294    return j;
00295 }
00296 
00297 /*! \brief Avoid the silly dahdi_waitevent which ignores a bunch of events */
00298 static inline int dahdi_wait_event(int fd)
00299 {
00300    int i, j = 0;
00301    i = DAHDI_IOMUX_SIGEVENT;
00302    if (ioctl(fd, DAHDI_IOMUX, &i) == -1)
00303       return -1;
00304    if (ioctl(fd, DAHDI_GETEVENT, &j) == -1)
00305       return -1;
00306    return j;
00307 }
00308 
00309 /*! Chunk size to read -- we use 20ms chunks to make things happy. */
00310 #define READ_SIZE 160
00311 
00312 #define MASK_AVAIL      (1 << 0) /*!< Channel available for PRI use */
00313 #define MASK_INUSE      (1 << 1) /*!< Channel currently in use */
00314 
00315 #define CALLWAITING_SILENT_SAMPLES     ((300 * 8) / READ_SIZE) /*!< 300 ms */
00316 #define CALLWAITING_REPEAT_SAMPLES     ((10000 * 8) / READ_SIZE) /*!< 10,000 ms */
00317 #define CALLWAITING_SUPPRESS_SAMPLES   ((100 * 8) / READ_SIZE) /*!< 100 ms */
00318 #define CIDCW_EXPIRE_SAMPLES        ((500 * 8) / READ_SIZE) /*!< 500 ms */
00319 #define MIN_MS_SINCE_FLASH          ((2000) )   /*!< 2000 ms */
00320 #define DEFAULT_RINGT               ((8000 * 8) / READ_SIZE) /*!< 8,000 ms */
00321 
00322 struct dahdi_pvt;
00323 
00324 /*!
00325  * \brief Configured ring timeout base.
00326  * \note Value computed from "ringtimeout" read in from chan_dahdi.conf if it exists.
00327  */
00328 static int ringt_base = DEFAULT_RINGT;
00329 
00330 #ifdef HAVE_OPENR2
00331 
00332 struct dahdi_mfcr2 {
00333    pthread_t master;           /*!< Thread of master */
00334    openr2_context_t *protocol_context;    /*!< OpenR2 context handle */ 
00335    struct dahdi_pvt *pvts[MAX_CHANNELS];     /*!< Member channel pvt structs */
00336    int numchans;                          /*!< Number of channels in this R2 block */
00337 };
00338 
00339 static struct dahdi_mfcr2 r2links[NUM_SPANS];
00340 static openr2_variant_t mfcr2_cur_variant = OR2_VAR_UNKNOWN;
00341 static int mfcr2_cur_mfback_timeout = -1;
00342 static int mfcr2_cur_metering_pulse_timeout = -1;
00343 static int mfcr2_cur_max_ani = 10;
00344 static int mfcr2_cur_max_dnis = 4;
00345 static int mfcr2_cur_get_ani_first = -1;
00346 static int mfcr2_cur_skip_category = -1;
00347 static int mfcr2_cur_context_index = 0;
00348 static int mfcr2_cur_call_files = 0;
00349 static int mfcr2_cur_allow_collect_calls = 0;
00350 static int mfcr2_cur_accept_on_offer = 1;
00351 static int mfcr2_cur_charge_calls = 1;
00352 static int mfcr2_cur_forced_release = 0;
00353 static int mfcr2_cur_double_answer = 0;
00354 static int mfcr2_cur_immediate_accept = -1;
00355 /* starting with openr2 interface 3 we have DTMF support */
00356 #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 2
00357 static int mfcr2_cur_dtmf_dialing = -1;
00358 static int mfcr2_cur_dtmf_detection = -1;
00359 static int mfcr2_cur_dtmf_time_on = OR2_DEFAULT_DTMF_ON;
00360 static int mfcr2_cur_dtmf_time_off = OR2_DEFAULT_DTMF_OFF;
00361 #endif
00362 static char mfcr2_cur_logdir[OR2_MAX_PATH];
00363 static char mfcr2_cur_r2proto_file[OR2_MAX_PATH];
00364 static openr2_log_level_t mfcr2_cur_loglevel = OR2_LOG_ERROR | OR2_LOG_WARNING;
00365 static openr2_calling_party_category_t mfcr2_cur_category = OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER;
00366 
00367 #endif /* HAVE_OPENR2 */
00368 
00369 #ifdef HAVE_PRI
00370 
00371 #define PVT_TO_CHANNEL(p) (((p)->prioffset) | ((p)->logicalspan << 8) | (p->pri->mastertrunkgroup ? 0x10000 : 0))
00372 #define PRI_CHANNEL(p) ((p) & 0xff)
00373 #define PRI_SPAN(p) (((p) >> 8) & 0xff)
00374 #define PRI_EXPLICIT(p) (((p) >> 16) & 0x01)
00375 
00376 /*! Call establishment life cycle level for simple comparisons. */
00377 enum dahdi_call_level {
00378    /*! Call does not exist. */
00379    DAHDI_CALL_LEVEL_IDLE,
00380    /*! Call is present but has no response yet. (SETUP) */
00381    DAHDI_CALL_LEVEL_SETUP,
00382    /*! Call is collecting digits for overlap dialing. (SETUP ACKNOWLEDGE) */
00383    DAHDI_CALL_LEVEL_OVERLAP,
00384    /*! Call routing is happening. (PROCEEDING) */
00385    DAHDI_CALL_LEVEL_PROCEEDING,
00386    /*! Called party is being alerted of the call. (ALERTING) */
00387    DAHDI_CALL_LEVEL_ALERTING,
00388    /*! Call is connected/answered. (CONNECT) */
00389    DAHDI_CALL_LEVEL_CONNECT,
00390 };
00391 
00392 struct dahdi_pri {
00393    pthread_t master;                /*!< Thread of master */
00394    ast_mutex_t lock;                /*!< Mutex */
00395    char idleext[AST_MAX_EXTENSION];          /*!< Where to idle extra calls */
00396    char idlecontext[AST_MAX_CONTEXT];           /*!< What context to use for idle */
00397    char idledial[AST_MAX_EXTENSION];            /*!< What to dial before dumping */
00398    int minunused;                   /*!< Min # of channels to keep empty */
00399    int minidle;                     /*!< Min # of "idling" calls to keep active */
00400    int nodetype;                    /*!< Node type */
00401    int switchtype;                     /*!< Type of switch to emulate */
00402    int nsf;                   /*!< Network-Specific Facilities */
00403    int dialplan;                    /*!< Dialing plan */
00404    int localdialplan;                  /*!< Local dialing plan */
00405    char internationalprefix[10];             /*!< country access code ('00' for european dialplans) */
00406    char nationalprefix[10];               /*!< area access code ('0' for european dialplans) */
00407    char localprefix[20];                  /*!< area access code + area code ('0'+area code for european dialplans) */
00408    char privateprefix[20];                /*!< for private dialplans */
00409    char unknownprefix[20];                /*!< for unknown dialplans */
00410    int dchannels[NUM_DCHANS];             /*!< What channel are the dchannels on */
00411    int trunkgroup;                     /*!< What our trunkgroup is */
00412    int mastertrunkgroup;                  /*!< What trunk group is our master */
00413    int prilogicalspan;                 /*!< Logical span number within trunk group */
00414    int numchans;                    /*!< Num of channels we represent */
00415    int overlapdial;                 /*!< In overlap dialing mode */
00416    int facilityenable;                 /*!< Enable facility IEs */
00417    struct pri *dchans[NUM_DCHANS];              /*!< Actual d-channels */
00418    int dchanavail[NUM_DCHANS];               /*!< Whether each channel is available */
00419    struct pri *pri;                 /*!< Currently active D-channel */
00420    /*! \brief TRUE if to dump PRI event info (Tested but never set) */
00421    int debug;
00422    int fds[NUM_DCHANS];                /*!< FD's for d-channels */
00423    /*! \brief Value set but not used */
00424    int offset;
00425    /*! \brief Span number put into user output messages */
00426    int span;
00427    /*! \brief TRUE if span is being reset/restarted */
00428    int resetting;
00429    /*! \brief Current position during a reset (-1 if not started) */
00430    int resetpos;
00431 #ifdef HAVE_PRI_INBANDDISCONNECT
00432    unsigned int inbanddisconnect:1;          /*!< Should we support inband audio after receiving DISCONNECT? */
00433 #endif
00434    /*! TRUE if we have already whined about no D channels available. */
00435    unsigned int no_d_channels:1;
00436    time_t lastreset;                /*!< time when unused channels were last reset */
00437    long resetinterval;                 /*!< Interval (in seconds) for resetting unused channels */
00438    struct dahdi_pvt *pvts[MAX_CHANNELS];           /*!< Member channel pvt structs */
00439    struct dahdi_pvt *crvs;                /*!< Member CRV structs */
00440    struct dahdi_pvt *crvend;                 /*!< Pointer to end of CRV structs */
00441 };
00442 
00443 
00444 static struct dahdi_pri pris[NUM_SPANS];
00445 
00446 #if 0
00447 #define DEFAULT_PRI_DEBUG (PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q921_DUMP | PRI_DEBUG_Q921_RAW | PRI_DEBUG_Q921_STATE)
00448 #else
00449 #define DEFAULT_PRI_DEBUG 0
00450 #endif
00451 
00452 static inline void pri_rel(struct dahdi_pri *pri)
00453 {
00454    ast_mutex_unlock(&pri->lock);
00455 }
00456 
00457 #else
00458 /*! Shut up the compiler */
00459 struct dahdi_pri;
00460 #endif
00461 
00462 #define SUB_REAL  0        /*!< Active call */
00463 #define SUB_CALLWAIT 1        /*!< Call-Waiting call on hold */
00464 #define SUB_THREEWAY 2        /*!< Three-way call */
00465 
00466 /* Polarity states */
00467 #define POLARITY_IDLE   0
00468 #define POLARITY_REV    1
00469 
00470 
00471 static struct dahdi_distRings drings;
00472 
00473 struct distRingData {
00474    int ring[3];
00475 };
00476 struct ringContextData {
00477    char contextData[AST_MAX_CONTEXT];
00478 };
00479 struct dahdi_distRings {
00480    struct distRingData ringnum[3];
00481    struct ringContextData ringContext[3];
00482 };
00483 
00484 static char *subnames[] = {
00485    "Real",
00486    "Callwait",
00487    "Threeway"
00488 };
00489 
00490 struct dahdi_subchannel {
00491    int dfd;
00492    struct ast_channel *owner;
00493    int chan;
00494    short buffer[AST_FRIENDLY_OFFSET/2 + READ_SIZE];
00495    struct ast_frame f;     /*!< One frame for each channel.  How did this ever work before? */
00496    unsigned int needringing:1;
00497    unsigned int needbusy:1;
00498    unsigned int needcongestion:1;
00499    unsigned int needcallerid:1;
00500    unsigned int needanswer:1;
00501    unsigned int needflash:1;
00502    unsigned int needhold:1;
00503    unsigned int needunhold:1;
00504    unsigned int linear:1;
00505    unsigned int inthreeway:1;
00506    struct dahdi_confinfo curconf;
00507 };
00508 
00509 #define CONF_USER_REAL     (1 << 0)
00510 #define CONF_USER_THIRDCALL   (1 << 1)
00511 
00512 #define MAX_SLAVES   4
00513 
00514 static struct dahdi_pvt {
00515    ast_mutex_t lock;             /*!< Channel private lock. */
00516    struct ast_channel *owner;       /*!< Our current active owner (if applicable) */
00517                      /*!< Up to three channels can be associated with this call */
00518       
00519    struct dahdi_subchannel sub_unused;    /*!< Just a safety precaution */
00520    struct dahdi_subchannel subs[3];       /*!< Sub-channels */
00521    struct dahdi_confinfo saveconf;        /*!< Saved conference info */
00522 
00523    struct dahdi_pvt *slaves[MAX_SLAVES];     /*!< Slave to us (follows our conferencing) */
00524    struct dahdi_pvt *master;           /*!< Master to us (we follow their conferencing) */
00525    int inconference;          /*!< If our real should be in the conference */
00526    
00527    int bufsize;                /*!< Size of the buffers */
00528    int buf_no;             /*!< Number of buffers */
00529    int buf_policy;            /*!< Buffer policy */
00530    int sig;             /*!< Signalling style */
00531    /*!
00532     * \brief Nonzero if the signaling type is sent over a radio.
00533     * \note Set to a couple of nonzero values but it is only tested like a boolean.
00534     */
00535    int radio;
00536    int outsigmod;             /*!< Outbound Signalling style (modifier) */
00537    int oprmode;               /*!< "Operator Services" mode */
00538    struct dahdi_pvt *oprpeer;          /*!< "Operator Services" peer tech_pvt ptr */
00539    /*! \brief Rx gain set by chan_dahdi.conf */
00540    float rxgain;
00541    /*! \brief Tx gain set by chan_dahdi.conf */
00542    float txgain;
00543    int tonezone;              /*!< tone zone for this chan, or -1 for default */
00544    struct dahdi_pvt *next;          /*!< Next channel in list */
00545    struct dahdi_pvt *prev;          /*!< Prev channel in list */
00546 
00547    /* flags */
00548 
00549    /*!
00550     * \brief TRUE if ADSI (Analog Display Services Interface) available
00551     * \note Set from the "adsi" value read in from chan_dahdi.conf
00552     */
00553    unsigned int adsi:1;
00554    /*!
00555     * \brief TRUE if we can use a polarity reversal to mark when an outgoing
00556     * call is answered by the remote party.
00557     * \note Set from the "answeronpolarityswitch" value read in from chan_dahdi.conf
00558     */
00559    unsigned int answeronpolarityswitch:1;
00560    /*!
00561     * \brief TRUE if busy detection is enabled.
00562     * (Listens for the beep-beep busy pattern.)
00563     * \note Set from the "busydetect" value read in from chan_dahdi.conf
00564     */
00565    unsigned int busydetect:1;
00566    /*!
00567     * \brief TRUE if call return is enabled.
00568     * (*69, if your dialplan doesn't catch this first)
00569     * \note Set from the "callreturn" value read in from chan_dahdi.conf
00570     */
00571    unsigned int callreturn:1;
00572    /*!
00573     * \brief TRUE if busy extensions will hear the call-waiting tone
00574     * and can use hook-flash to switch between callers.
00575     * \note Can be disabled by dialing *70.
00576     * \note Initialized with the "callwaiting" value read in from chan_dahdi.conf
00577     */
00578    unsigned int callwaiting:1;
00579    /*!
00580     * \brief TRUE if send caller ID for Call Waiting
00581     * \note Set from the "callwaitingcallerid" value read in from chan_dahdi.conf
00582     */
00583    unsigned int callwaitingcallerid:1;
00584    /*!
00585     * \brief TRUE if support for call forwarding enabled.
00586     * Dial *72 to enable call forwarding.
00587     * Dial *73 to disable call forwarding.
00588     * \note Set from the "cancallforward" value read in from chan_dahdi.conf
00589     */
00590    unsigned int cancallforward:1;
00591    /*!
00592     * \brief TRUE if support for call parking is enabled.
00593     * \note Set from the "canpark" value read in from chan_dahdi.conf
00594     */
00595    unsigned int canpark:1;
00596    /*! \brief TRUE if to wait for a DTMF digit to confirm answer */
00597    unsigned int confirmanswer:1;
00598    /*!
00599     * \brief TRUE if the channel is to be destroyed on hangup.
00600     * (Used by pseudo channels.)
00601     */
00602    unsigned int destroy:1;
00603    unsigned int didtdd:1;           /*!< flag to say its done it once */
00604    /*! \brief TRUE if analog type line dialed no digits in Dial() */
00605    unsigned int dialednone:1;
00606    /*! \brief TRUE if in the process of dialing digits or sending something. */
00607    unsigned int dialing:1;
00608    /*! \brief TRUE if the transfer capability of the call is digital. */
00609    unsigned int digital:1;
00610    /*! \brief TRUE if Do-Not-Disturb is enabled. */
00611    unsigned int dnd:1;
00612    /*! \brief XXX BOOLEAN Purpose??? */
00613    unsigned int echobreak:1;
00614    /*!
00615     * \brief TRUE if echo cancellation enabled when bridged.
00616     * \note Initialized with the "echocancelwhenbridged" value read in from chan_dahdi.conf
00617     * \note Disabled if the echo canceller is not setup.
00618     */
00619    unsigned int echocanbridged:1;
00620    /*! \brief TRUE if echo cancellation is turned on. */
00621    unsigned int echocanon:1;
00622    /*! \brief TRUE if a fax tone has already been handled. */
00623    unsigned int faxhandled:1;
00624    /*!< TRUE while buffer configuration override is in use. */
00625    unsigned int bufferoverrideinuse:1;
00626    /*! \brief TRUE if over a radio and dahdi_read() has been called. */
00627    unsigned int firstradio:1;
00628    /*!
00629     * \brief TRUE if the call will be considered "hung up" on a polarity reversal.
00630     * \note Set from the "hanguponpolarityswitch" value read in from chan_dahdi.conf
00631     */
00632    unsigned int hanguponpolarityswitch:1;
00633    /*! \brief TRUE if DTMF detection needs to be done by hardware. */
00634    unsigned int hardwaredtmf:1;
00635    /*!
00636     * \brief TRUE if the outgoing caller ID is blocked/hidden.
00637     * \note Caller ID can be disabled by dialing *67.
00638     * \note Caller ID can be enabled by dialing *82.
00639     * \note Initialized with the "hidecallerid" value read in from chan_dahdi.conf
00640     */
00641    unsigned int hidecallerid:1;
00642    /*!
00643     * \brief TRUE if hide just the name not the number for legacy PBX use.
00644     * \note Only applies to PRI channels.
00645     * \note Set from the "hidecalleridname" value read in from chan_dahdi.conf
00646     */
00647    unsigned int hidecalleridname:1;
00648    /*! \brief TRUE if DTMF detection is disabled. */
00649    unsigned int ignoredtmf:1;
00650    /*!
00651     * \brief TRUE if the channel should be answered immediately
00652     * without attempting to gather any digits.
00653     * \note Set from the "immediate" value read in from chan_dahdi.conf
00654     */
00655    unsigned int immediate:1;
00656    /*! \brief TRUE if in an alarm condition. */
00657    unsigned int inalarm:1;
00658    unsigned int unknown_alarm:1;
00659    /*! \brief TRUE if TDD in MATE mode */
00660    unsigned int mate:1;
00661 #if defined(HAVE_PRI)
00662    /*!
00663     * \brief TRUE when this channel is allocated.
00664     *
00665     * \details
00666     * Needed to hold an outgoing channel allocation before the
00667     * owner pointer is created.
00668     *
00669     * \note This is one of several items to check to see if a
00670     * channel is available for use.
00671     */
00672    unsigned int allocated:1;
00673 #endif   /* defined(HAVE_PRI) */
00674    /*! \brief TRUE if we originated the call leg. */
00675    unsigned int outgoing:1;
00676    /* unsigned int overlapdial:1;         unused and potentially confusing */
00677    /*!
00678     * \brief TRUE if busy extensions will hear the call-waiting tone
00679     * and can use hook-flash to switch between callers.
00680     * \note Set from the "callwaiting" value read in from chan_dahdi.conf
00681     */
00682    unsigned int permcallwaiting:1;
00683    /*!
00684     * \brief TRUE if the outgoing caller ID is blocked/restricted/hidden.
00685     * \note Set from the "hidecallerid" value read in from chan_dahdi.conf
00686     */
00687    unsigned int permhidecallerid:1;
00688    /*!
00689     * \brief TRUE if PRI congestion/busy indications are sent out-of-band.
00690     * \note Set from the "priindication" value read in from chan_dahdi.conf
00691     */
00692    unsigned int priindication_oob:1;
00693    /*!
00694     * \brief TRUE if PRI B channels are always exclusively selected.
00695     * \note Set from the "priexclusive" value read in from chan_dahdi.conf
00696     */
00697    unsigned int priexclusive:1;
00698    /*!
00699     * \brief TRUE if we will pulse dial.
00700     * \note Set from the "pulsedial" value read in from chan_dahdi.conf
00701     */
00702    unsigned int pulse:1;
00703    /*! \brief TRUE if a pulsed digit was detected. (Pulse dial phone detected) */
00704    unsigned int pulsedial:1;
00705    unsigned int restartpending:1;      /*!< flag to ensure counted only once for restart */
00706    /*!
00707     * \brief TRUE if caller ID is restricted.
00708     * \note Set but not used.  Should be deleted.  Redundant with permhidecallerid.
00709     * \note Set from the "restrictcid" value read in from chan_dahdi.conf
00710     */
00711    unsigned int restrictcid:1;
00712    /*!
00713     * \brief TRUE if three way calling is enabled
00714     * \note Set from the "threewaycalling" value read in from chan_dahdi.conf
00715     */
00716    unsigned int threewaycalling:1;
00717    /*!
00718     * \brief TRUE if call transfer is enabled
00719     * \note For FXS ports (either direct analog or over T1/E1):
00720     *   Support flash-hook call transfer
00721     * \note For digital ports using ISDN PRI protocols:
00722     *   Support switch-side transfer (called 2BCT, RLT or other names)
00723     * \note Set from the "transfer" value read in from chan_dahdi.conf
00724     */
00725    unsigned int transfer:1;
00726    /*!
00727     * \brief TRUE if caller ID is used on this channel.
00728     * \note PRI spans will save caller ID from the networking peer.
00729     * \note FXS ports will generate the caller ID spill.
00730     * \note FXO ports will listen for the caller ID spill.
00731     * \note Set from the "usecallerid" value read in from chan_dahdi.conf
00732     */
00733    unsigned int use_callerid:1;
00734    /*!
00735     * \brief TRUE if we will use the calling presentation setting
00736     * from the Asterisk channel for outgoing calls.
00737     * \note Only applies to PRI channels.
00738     * \note Set from the "usecallingpres" value read in from chan_dahdi.conf
00739     */
00740    unsigned int use_callingpres:1;
00741    /*!
00742     * \brief TRUE if distinctive rings are to be detected.
00743     * \note For FXO lines
00744     * \note Set indirectly from the "usedistinctiveringdetection" value read in from chan_dahdi.conf
00745     */
00746    unsigned int usedistinctiveringdetection:1;
00747    /*!
00748     * \brief TRUE if we should use the callerid from incoming call on dahdi transfer.
00749     * \note Set from the "useincomingcalleridondahditransfer" value read in from chan_dahdi.conf
00750     */
00751    unsigned int dahditrcallerid:1;
00752    /*!
00753     * \brief TRUE if allowed to flash-transfer to busy channels.
00754     * \note Set from the "transfertobusy" value read in from chan_dahdi.conf
00755     */
00756    unsigned int transfertobusy:1;
00757    /*!
00758     * \brief TRUE if SMDI (Simplified Message Desk Interface) is enabled
00759     * \note Set from the "usesmdi" value read in from chan_dahdi.conf
00760     */
00761    unsigned int use_smdi:1;
00762 #if defined(HAVE_PRI)
00763    /*! \brief TRUE if the call has already gone/hungup */
00764    unsigned int alreadyhungup:1;
00765    /*!
00766     * \brief TRUE if this is an idle call
00767     * \note Applies to PRI channels.
00768     */
00769    unsigned int isidlecall:1;
00770    /*! \brief TRUE if the call has seen inband-information progress through the network. */
00771    unsigned int progress:1;
00772    /*!
00773     * \brief TRUE if this channel is being reset/restarted
00774     * \note Applies to PRI channels.
00775     */
00776    unsigned int resetting:1;
00777 
00778    /*! Call establishment life cycle level for simple comparisons. */
00779    enum dahdi_call_level call_level;
00780 #endif
00781    /*! \brief The serial port to listen for SMDI data on */
00782    struct ast_smdi_interface *smdi_iface;
00783 
00784    /*! \brief Distinctive Ring data */
00785    struct dahdi_distRings drings;
00786 
00787    /*!
00788     * \brief The configured context for incoming calls.
00789     * \note The "context" string read in from chan_dahdi.conf
00790     */
00791    char context[AST_MAX_CONTEXT];
00792    /*!
00793     * \brief Saved context string.
00794     */
00795    char defcontext[AST_MAX_CONTEXT];
00796    /*! \brief Extension to use in the dialplan. */
00797    char exten[AST_MAX_EXTENSION];
00798    /*!
00799     * \brief Language configured for calls.
00800     * \note The "language" string read in from chan_dahdi.conf
00801     */
00802    char language[MAX_LANGUAGE];
00803    /*!
00804     * \brief The configured music-on-hold class to use for calls.
00805     * \note The "musicclass" or "mohinterpret" or "musiconhold" string read in from chan_dahdi.conf
00806     */
00807    char mohinterpret[MAX_MUSICCLASS];
00808    /*!
00809     * \brief Sugggested music-on-hold class for peer channel to use for calls.
00810     * \note The "mohsuggest" string read in from chan_dahdi.conf
00811     */
00812    char mohsuggest[MAX_MUSICCLASS];
00813 #ifdef PRI_ANI
00814    /*! \brief Automatic Number Identification number (Alternate PRI caller ID number) */
00815    char cid_ani[AST_MAX_EXTENSION];
00816 #endif
00817    /*! \brief Caller ID number from an incoming call. */
00818    char cid_num[AST_MAX_EXTENSION];
00819    /*! \brief Caller ID Q.931 TON/NPI field values.  Set by PRI. Zero otherwise. */
00820    int cid_ton;
00821    /*! \brief Caller ID name from an incoming call. */
00822    char cid_name[AST_MAX_EXTENSION];
00823    /*! \brief Last Caller ID number from an incoming call. */
00824    char lastcid_num[AST_MAX_EXTENSION];
00825    /*! \brief Last Caller ID name from an incoming call. */
00826    char lastcid_name[AST_MAX_EXTENSION];
00827    char *origcid_num;            /*!< malloced original callerid */
00828    char *origcid_name;           /*!< malloced original callerid */
00829    /*! \brief Call waiting number. */
00830    char callwait_num[AST_MAX_EXTENSION];
00831    /*! \brief Call waiting name. */
00832    char callwait_name[AST_MAX_EXTENSION];
00833    /*! \brief Redirecting Directory Number Information Service (RDNIS) number */
00834    char rdnis[AST_MAX_EXTENSION];
00835    /*! \brief Dialed Number Identifier */
00836    char dnid[AST_MAX_EXTENSION];
00837    /*!
00838     * \brief Bitmapped groups this belongs to.
00839     * \note The "group" bitmapped group string read in from chan_dahdi.conf
00840     */
00841    ast_group_t group;
00842    /*! \brief Active PCM encoding format: DAHDI_LAW_ALAW or DAHDI_LAW_MULAW */
00843    int law;
00844    int confno;             /*!< Our conference */
00845    int confusers;             /*!< Who is using our conference */
00846    int propconfno;               /*!< Propagated conference number */
00847    /*!
00848     * \brief Bitmapped call groups this belongs to.
00849     * \note The "callgroup" bitmapped group string read in from chan_dahdi.conf
00850     */
00851    ast_group_t callgroup;
00852    /*!
00853     * \brief Bitmapped pickup groups this belongs to.
00854     * \note The "pickupgroup" bitmapped group string read in from chan_dahdi.conf
00855     */
00856    ast_group_t pickupgroup;
00857    int channel;               /*!< Channel Number or CRV */
00858    int span;               /*!< Span number */
00859    time_t guardtime;          /*!< Must wait this much time before using for new call */
00860    int cid_signalling;           /*!< CID signalling type bell202 or v23 */
00861    int cid_start;             /*!< CID start indicator, polarity or ring or DTMF without warning event */
00862    int dtmfcid_holdoff_state;    /*!< State indicator that allows for line to settle before checking for dtmf energy */
00863    struct timeval dtmfcid_delay;  /*!< Time value used for allow line to settle */
00864    int callingpres;           /*!< The value of callling presentation that we're going to use when placing a PRI call */
00865    int callwaitingrepeat;           /*!< How many samples to wait before repeating call waiting */
00866    int cidcwexpire;           /*!< When to stop waiting for CID/CW CAS response (In samples) */
00867    int cid_suppress_expire;      /*!< How many samples to suppress after a CID spill. */
00868    /*! \brief Analog caller ID waveform sample buffer */
00869    unsigned char *cidspill;
00870    /*! \brief Position in the cidspill buffer to send out next. */
00871    int cidpos;
00872    /*! \brief Length of the cidspill buffer containing samples. */
00873    int cidlen;
00874    /*! \brief Ring timeout timer?? */
00875    int ringt;
00876    /*!
00877     * \brief Ring timeout base.
00878     * \note Value computed indirectly from "ringtimeout" read in from chan_dahdi.conf
00879     */
00880    int ringt_base;
00881    /*!
00882     * \brief Number of most significant digits/characters to strip from the dialed number.
00883     * \note Feature is deprecated.  Use dialplan logic.
00884     * \note The characters are stripped before the PRI TON/NPI prefix
00885     * characters are processed.
00886     */
00887    int stripmsd;
00888    /*!
00889     * \brief TRUE if Call Waiting (CW) CPE Alert Signal (CAS) is being sent.
00890     * \note
00891     * After CAS is sent, the call waiting caller id will be sent if the phone
00892     * gives a positive reply.
00893     */
00894    int callwaitcas;
00895    /*! \brief Number of call waiting rings. */
00896    int callwaitrings;
00897    /*! \brief Number of echo cancel taps.  0 if echo canceller not requested. */
00898    int echocancel;
00899    /*!
00900     * \brief Echo training time. 0 = disabled
00901     * \note Set from the "echotraining" value read in from chan_dahdi.conf
00902     */
00903    int echotraining;
00904    /*! \brief Filled with 'w'.  XXX Purpose?? */
00905    char echorest[20];
00906    /*!
00907     * \brief Number of times to see "busy" tone before hanging up.
00908     * \note Set from the "busycount" value read in from chan_dahdi.conf
00909     */
00910    int busycount;
00911    /*!
00912     * \brief If your country has a busy tone with the same length tone and silence (as many countries do), consider using this option in order to compare tone and silence lengths
00913     * \note Set from the "busycompare" value read in from chan_dahdi.conf
00914     */
00915    int busycompare;
00916    /*!
00917     * \brief Lenght of "tone" in ms.
00918     * \note Set from the "busypattern" value read in from chan_dahdi.conf
00919     */
00920    int busytonelength;
00921    /*!
00922     * \brief Lenght of "silence" in ms.
00923     * \note Set from the "busypattern" value read in from chan_dahdi.conf
00924     */
00925    int busyquietlength;
00926    /*!
00927     * \brief  Maximun percentage difference allowed between measured and actual pattern
00928     * \note Set from the "busyfuzziness" value read in from chan_dahdi.conf
00929     */
00930    int busyfuzziness;
00931    /*!
00932     * \brief Maximun signal average level considered as silence in this channel
00933     * \note Set from the "silencethreshold" value read in from chan_dahdi.conf
00934     */
00935    int silencethreshold;
00936    /*!
00937     * \brief Bitmapped call progress detection flags. CALLPROGRESS_xxx values.
00938     * \note Bits set from the "callprogress" and "faxdetect" values read in from chan_dahdi.conf
00939     */
00940    int callprogress;
00941    struct timeval flashtime;        /*!< Last flash-hook time */
00942    /*! \brief Opaque DSP configuration structure. */
00943    struct ast_dsp *dsp;
00944    //int cref;             /*!< Call reference number (Not used) */
00945    /*! \brief DAHDI dial operation command struct for ioctl() call. */
00946    struct dahdi_dialoperation dop;
00947    int whichwink;             /*!< SIG_FEATDMF_TA Which wink are we on? */
00948    /*! \brief Second part of SIG_FEATDMF_TA wink operation. */
00949    char finaldial[64];
00950    char accountcode[AST_MAX_ACCOUNT_CODE];      /*!< Account code */
00951    int amaflags;              /*!< AMA Flags */
00952    struct tdd_state *tdd;           /*!< TDD flag */
00953    /*! \brief Accumulated call forwarding number. */
00954    char call_forward[AST_MAX_EXTENSION];
00955    /*!
00956     * \brief Voice mailbox location.
00957     * \note Set from the "mailbox" string read in from chan_dahdi.conf
00958     */
00959    char mailbox[AST_MAX_EXTENSION];
00960    /*! \brief Delayed dialing for E911.  Overlap digits for ISDN. */
00961    char dialdest[256];
00962    /*! \brief Time the interface went on-hook. */
00963    int onhooktime;
00964    /*! \brief -1 = unknown, 0 = no messages, 1 = new messages available */
00965    int msgstate;
00966    int distinctivering;          /*!< Which distinctivering to use */
00967    int cidrings;              /*!< Which ring to deliver CID on */
00968    int dtmfrelax;             /*!< whether to run in relaxed DTMF mode */
00969    /*! \brief Holding place for event injected from outside normal operation. */
00970    int fake_event;
00971    /*!
00972     * \brief Minimal time period (ms) between the answer polarity
00973     * switch and hangup polarity switch.
00974     */
00975    int polarityonanswerdelay;
00976    /*! \brief Start delay time if polarityonanswerdelay is nonzero. */
00977    struct timeval polaritydelaytv;
00978    /*!
00979     * \brief Send caller ID after this many rings.
00980     * \note Set from the "sendcalleridafter" value read in from chan_dahdi.conf
00981     */
00982    int sendcalleridafter;
00983 #ifdef HAVE_PRI
00984    /*! \brief DAHDI PRI control parameters */
00985    struct dahdi_pri *pri;
00986    /*! \brief XXX Purpose??? */
00987    struct dahdi_pvt *bearer;
00988    /*! \brief XXX Purpose??? */
00989    struct dahdi_pvt *realcall;
00990    /*! \brief Opaque libpri call control structure */
00991    q931_call *call;
00992    /*! \brief Channel number in span. */
00993    int prioffset;
00994    /*! \brief Logical span number within trunk group */
00995    int logicalspan;
00996 #endif   
00997 
00998 #ifdef HAVE_OPENR2
00999    int mfcr2call;
01000    int mfcr2block;
01001    struct dahdi_mfcr2 *mfcr2;
01002    openr2_chan_t *r2chan;
01003    openr2_calling_party_category_t mfcr2_recvd_category;
01004    openr2_calling_party_category_t mfcr2_category;
01005    int mfcr2_accept_on_offer;
01006    int mfcr2_charge_calls;
01007    int mfcr2_allow_collect_calls;
01008    int mfcr2_forced_release;
01009    int mfcr2_dnis_index;
01010    int mfcr2_ani_index;
01011    int mfcr2_dnis_matched;
01012    int mfcr2_call_accepted;
01013 #endif
01014 
01015    /*! \brief Current line interface polarity. POLARITY_IDLE, POLARITY_REV */
01016    int polarity;
01017    /*! \brief DSP feature flags: DSP_FEATURE_xxx */
01018    int dsp_features;
01019    /*! \brief DTMF digit in progress.  0 when no digit in progress. */
01020    char begindigit;
01021 } *iflist = NULL, *ifend = NULL;
01022 
01023 /*! \brief Channel configuration from chan_dahdi.conf .
01024  * This struct is used for parsing the [channels] section of chan_dahdi.conf.
01025  * Generally there is a field here for every possible configuration item.
01026  *
01027  * The state of fields is saved along the parsing and whenever a 'channel'
01028  * statement is reached, the current dahdi_chan_conf is used to configure the 
01029  * channel (struct dahdi_pvt)
01030  *
01031  * @seealso dahdi_chan_init for the default values.
01032  */
01033 struct dahdi_chan_conf {
01034    struct dahdi_pvt chan;
01035 #ifdef HAVE_PRI
01036    struct dahdi_pri pri;
01037 #endif
01038    struct dahdi_params timing;
01039 
01040    /*!
01041     * \brief The serial port to listen for SMDI data on
01042     * \note Set from the "smdiport" string read in from chan_dahdi.conf
01043     */
01044    char smdi_port[SMDI_MAX_FILENAME_LEN];
01045 };
01046 
01047 /** returns a new dahdi_chan_conf with default values (by-value) */
01048 static struct dahdi_chan_conf dahdi_chan_conf_default(void) {
01049    /* recall that if a field is not included here it is initialized
01050     * to 0 or equivalent
01051     */
01052    struct dahdi_chan_conf conf = {
01053 #ifdef HAVE_PRI
01054       .pri = {
01055          .nsf = PRI_NSF_NONE,
01056          .switchtype = PRI_SWITCH_NI2,
01057          .dialplan = PRI_NATIONAL_ISDN + 1,
01058          .localdialplan = PRI_NATIONAL_ISDN + 1,
01059          .nodetype = PRI_CPE,
01060 
01061          .minunused = 2,
01062          .idleext = "",
01063          .idledial = "",
01064          .internationalprefix = "",
01065          .nationalprefix = "",
01066          .localprefix = "",
01067          .privateprefix = "",
01068          .unknownprefix = "",
01069 
01070          .resetinterval = 3600
01071       },
01072 #endif
01073       .chan = {
01074          .context = "default",
01075          .cid_num = "",
01076          .cid_name = "",
01077          .mohinterpret = "default",
01078          .mohsuggest = "",
01079          .transfertobusy = 1,
01080 
01081          .cid_signalling = CID_SIG_BELL,
01082          .cid_start = CID_START_RING,
01083          .dahditrcallerid = 0,
01084          .use_callerid = 1,
01085          .sig = -1,
01086          .outsigmod = -1,
01087 
01088          .tonezone = -1,
01089 
01090          .echocancel = 1,
01091 
01092          .busycount = 3,
01093          .busycompare = 0,
01094          .busytonelength = 0,
01095          .busyquietlength = 0,
01096          .busyfuzziness = 0,
01097          .silencethreshold = 0,
01098 
01099          .accountcode = "",
01100 
01101          .mailbox = "",
01102 
01103 
01104          .polarityonanswerdelay = 600,
01105 
01106          .sendcalleridafter = DEFAULT_CIDRINGS,
01107 
01108          .buf_policy = DAHDI_POLICY_IMMEDIATE,
01109          .buf_no = numbufs,
01110       },
01111       .timing = {
01112          .prewinktime = -1,
01113          .preflashtime = -1,
01114          .winktime = -1,
01115          .flashtime = -1,
01116          .starttime = -1,
01117          .rxwinktime = -1,
01118          .rxflashtime = -1,
01119          .debouncetime = -1
01120       },
01121       .smdi_port = "/dev/ttyS0",
01122    };
01123 
01124    return conf;
01125 }
01126 
01127 
01128 static struct ast_channel *dahdi_request(const char *type, int format, void *data, int *cause);
01129 static int dahdi_digit_begin(struct ast_channel *ast, char digit);
01130 static int dahdi_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
01131 static int dahdi_sendtext(struct ast_channel *c, const char *text);
01132 static int dahdi_call(struct ast_channel *ast, char *rdest, int timeout);
01133 static int dahdi_hangup(struct ast_channel *ast);
01134 static int dahdi_answer(struct ast_channel *ast);
01135 static struct ast_frame *dahdi_read(struct ast_channel *ast);
01136 static int dahdi_write(struct ast_channel *ast, struct ast_frame *frame);
01137 static struct ast_frame *dahdi_exception(struct ast_channel *ast);
01138 static int dahdi_indicate(struct ast_channel *chan, int condition, const void *data, size_t datalen);
01139 static int dahdi_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
01140 static int dahdi_setoption(struct ast_channel *chan, int option, void *data, int datalen);
01141 static int dahdi_func_read(struct ast_channel *chan, char *function, char *data, char *buf, size_t len); 
01142 static int dahdi_func_write(struct ast_channel *chan, char *function, char *data, const char *value);
01143 
01144 static const struct ast_channel_tech dahdi_tech = {
01145    .type = "DAHDI",
01146    .description = tdesc,
01147    .capabilities = AST_FORMAT_SLINEAR | AST_FORMAT_ULAW | AST_FORMAT_ALAW,
01148    .requester = dahdi_request,
01149    .send_digit_begin = dahdi_digit_begin,
01150    .send_digit_end = dahdi_digit_end,
01151    .send_text = dahdi_sendtext,
01152    .call = dahdi_call,
01153    .hangup = dahdi_hangup,
01154    .answer = dahdi_answer,
01155    .read = dahdi_read,
01156    .write = dahdi_write,
01157    .bridge = dahdi_bridge,
01158    .exception = dahdi_exception,
01159    .indicate = dahdi_indicate,
01160    .fixup = dahdi_fixup,
01161    .setoption = dahdi_setoption,
01162    .func_channel_read = dahdi_func_read,
01163    .func_channel_write = dahdi_func_write,
01164 };
01165 
01166 static const struct ast_channel_tech zap_tech = {
01167    .type = "Zap",
01168    .description = tdesc,
01169    .capabilities = AST_FORMAT_SLINEAR | AST_FORMAT_ULAW | AST_FORMAT_ALAW,
01170    .requester = dahdi_request,
01171    .send_digit_begin = dahdi_digit_begin,
01172    .send_digit_end = dahdi_digit_end,
01173    .send_text = dahdi_sendtext,
01174    .call = dahdi_call,
01175    .hangup = dahdi_hangup,
01176    .answer = dahdi_answer,
01177    .read = dahdi_read,
01178    .write = dahdi_write,
01179    .bridge = dahdi_bridge,
01180    .exception = dahdi_exception,
01181    .indicate = dahdi_indicate,
01182    .fixup = dahdi_fixup,
01183    .setoption = dahdi_setoption,
01184    .func_channel_read = dahdi_func_read,
01185    .func_channel_write = dahdi_func_write,
01186 };
01187 
01188 static const struct ast_channel_tech *chan_tech;
01189 
01190 #ifdef HAVE_PRI
01191 #define GET_CHANNEL(p) ((p)->bearer ? (p)->bearer->channel : p->channel)
01192 #else
01193 #define GET_CHANNEL(p) ((p)->channel)
01194 #endif
01195 
01196 struct dahdi_pvt *round_robin[32];
01197 
01198 #ifdef HAVE_PRI
01199 static inline int pri_grab(struct dahdi_pvt *pvt, struct dahdi_pri *pri)
01200 {
01201    int res;
01202    /* Grab the lock first */
01203    do {
01204       res = ast_mutex_trylock(&pri->lock);
01205       if (res) {
01206          DEADLOCK_AVOIDANCE(&pvt->lock);
01207       }
01208    } while (res);
01209    /* Then break the poll */
01210    if (pri->master != AST_PTHREADT_NULL)
01211       pthread_kill(pri->master, SIGURG);
01212    return 0;
01213 }
01214 #endif
01215 
01216 #define NUM_CADENCE_MAX 25
01217 static int num_cadence = 4;
01218 static int user_has_defined_cadences = 0;
01219 
01220 static struct dahdi_ring_cadence cadences[NUM_CADENCE_MAX] = {
01221    { { 125, 125, 2000, 4000 } },       /*!< Quick chirp followed by normal ring */
01222    { { 250, 250, 500, 1000, 250, 250, 500, 4000 } }, /*!< British style ring */
01223    { { 125, 125, 125, 125, 125, 4000 } }, /*!< Three short bursts */
01224    { { 1000, 500, 2500, 5000 } },   /*!< Long ring */
01225 };
01226 
01227 /*! \brief cidrings says in which pause to transmit the cid information, where the first pause
01228  * is 1, the second pause is 2 and so on.
01229  */
01230 
01231 static int cidrings[NUM_CADENCE_MAX] = {
01232    2,                            /*!< Right after first long ring */
01233    4,                            /*!< Right after long part */
01234    3,                            /*!< After third chirp */
01235    2,                            /*!< Second spell */
01236 };
01237 
01238 #define ISTRUNK(p) ((p->sig == SIG_FXSLS) || (p->sig == SIG_FXSKS) || \
01239          (p->sig == SIG_FXSGS) || (p->sig == SIG_PRI))
01240 
01241 #define CANBUSYDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __DAHDI_SIG_FXO) */)
01242 #define CANPROGRESSDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __DAHDI_SIG_FXO) */)
01243 
01244 #define dahdi_get_index(ast, p, nullok)   _dahdi_get_index(ast, p, nullok, __PRETTY_FUNCTION__, __LINE__)
01245 static int _dahdi_get_index(struct ast_channel *ast, struct dahdi_pvt *p, int nullok, const char *fname, unsigned long line)
01246 {
01247    int res;
01248    if (p->subs[SUB_REAL].owner == ast)
01249       res = 0;
01250    else if (p->subs[SUB_CALLWAIT].owner == ast)
01251       res = 1;
01252    else if (p->subs[SUB_THREEWAY].owner == ast)
01253       res = 2;
01254    else {
01255       res = -1;
01256       if (!nullok)
01257          ast_log(LOG_WARNING,
01258             "Unable to get index for '%s' on channel %d (%s(), line %lu)\n",
01259             ast ? ast->name : "", p->channel, fname, line);
01260    }
01261    return res;
01262 }
01263 
01264 /*!
01265  * \internal
01266  * \brief Obtain the specified subchannel owner lock if the owner exists.
01267  *
01268  * \param pvt Channel private struct.
01269  * \param sub_idx Subchannel owner to lock.
01270  *
01271  * \note Assumes the pvt->lock is already obtained.
01272  *
01273  * \note
01274  * Because deadlock avoidance may have been necessary, you need to confirm
01275  * the state of things before continuing.
01276  *
01277  * \return Nothing
01278  */
01279 static void dahdi_lock_sub_owner(struct dahdi_pvt *pvt, int sub_idx)
01280 {
01281    for (;;) {
01282       if (!pvt->subs[sub_idx].owner) {
01283          /* No subchannel owner pointer */
01284          break;
01285       }
01286       if (!ast_mutex_trylock(&pvt->subs[sub_idx].owner->lock)) {
01287          /* Got subchannel owner lock */
01288          break;
01289       }
01290       /* We must unlock the private to avoid the possibility of a deadlock */
01291       DEADLOCK_AVOIDANCE(&pvt->lock);
01292    }
01293 }
01294 
01295 static void wakeup_sub(struct dahdi_pvt *p, int a, struct dahdi_pri *pri)
01296 {
01297 #ifdef HAVE_PRI
01298    if (pri)
01299       ast_mutex_unlock(&pri->lock);
01300 #endif         
01301    dahdi_lock_sub_owner(p, a);
01302    if (p->subs[a].owner) {
01303       ast_queue_frame(p->subs[a].owner, &ast_null_frame);
01304       ast_mutex_unlock(&p->subs[a].owner->lock);
01305    }
01306 #ifdef HAVE_PRI
01307    if (pri)
01308       ast_mutex_lock(&pri->lock);
01309 #endif         
01310 }
01311 
01312 #ifdef HAVE_PRI
01313 static void dahdi_queue_frame(struct dahdi_pvt *p, struct ast_frame *f, struct dahdi_pri *pri)
01314 #else
01315 static void dahdi_queue_frame(struct dahdi_pvt *p, struct ast_frame *f, void *pri)
01316 #endif
01317 {
01318    /* We must unlock the PRI to avoid the possibility of a deadlock */
01319 #ifdef HAVE_PRI
01320    if (pri)
01321       ast_mutex_unlock(&pri->lock);
01322 #endif      
01323    for (;;) {
01324       if (p->owner) {
01325          if (ast_mutex_trylock(&p->owner->lock)) {
01326             DEADLOCK_AVOIDANCE(&p->lock);
01327          } else {
01328             ast_queue_frame(p->owner, f);
01329             ast_mutex_unlock(&p->owner->lock);
01330             break;
01331          }
01332       } else
01333          break;
01334    }
01335 #ifdef HAVE_PRI
01336    if (pri)
01337       ast_mutex_lock(&pri->lock);
01338 #endif      
01339 }
01340 
01341 static struct ast_channel *dahdi_new(struct dahdi_pvt *i, int state, int startpbx, int index, int law, int transfercapability);
01342 #ifdef HAVE_OPENR2
01343 static void init_mfcr2_globals(void)
01344 {
01345    int r;
01346    mfcr2_cur_context_index = 0;
01347    mfcr2_cur_variant = OR2_VAR_UNKNOWN;
01348    mfcr2_cur_mfback_timeout = -1;
01349    mfcr2_cur_metering_pulse_timeout = -1;
01350    mfcr2_cur_max_ani = 10;
01351    mfcr2_cur_max_dnis = 4;
01352    mfcr2_cur_get_ani_first = -1;
01353 #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 2
01354    mfcr2_cur_dtmf_dialing = -1;
01355    mfcr2_cur_dtmf_detection = -1;
01356    mfcr2_cur_dtmf_time_on = OR2_DEFAULT_DTMF_ON;
01357    mfcr2_cur_dtmf_time_off = OR2_DEFAULT_DTMF_OFF;
01358 #endif
01359    mfcr2_cur_skip_category = -1;
01360    mfcr2_cur_call_files = 0;
01361    mfcr2_cur_allow_collect_calls = 0;
01362    mfcr2_cur_forced_release = 0;
01363    mfcr2_cur_double_answer = 0;
01364    mfcr2_cur_immediate_accept = -1;
01365    mfcr2_cur_loglevel = OR2_LOG_ERROR | OR2_LOG_WARNING;
01366    mfcr2_cur_category = OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER;
01367    memset(mfcr2_cur_logdir, 0, sizeof(mfcr2_cur_logdir));
01368    memset(mfcr2_cur_r2proto_file, 0, sizeof(mfcr2_cur_r2proto_file));
01369    memset(r2links, 0, sizeof(r2links));
01370    for (r = 0; r < NUM_SPANS; r++) {
01371       r2links[r].master = AST_PTHREADT_NULL;
01372    }
01373 }
01374 
01375 static int dahdi_r2_answer(struct dahdi_pvt *p)
01376 {
01377    int res = 0;
01378    /* openr2 1.1.0 and older does not even define OR2_LIB_INTERFACE
01379     * and does not has support for openr2_chan_answer_call_with_mode
01380     *  */
01381 #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1
01382    const char *double_answer = pbx_builtin_getvar_helper(p->owner, "MFCR2_DOUBLE_ANSWER");
01383    int wants_double_answer = ast_true(double_answer) ? 1 : 0;
01384    if (!double_answer) {
01385       /* this still can result in double answer if the channel context 
01386        * was configured that way */
01387       res = openr2_chan_answer_call(p->r2chan);
01388    } else if (wants_double_answer) {
01389       res = openr2_chan_answer_call_with_mode(p->r2chan, OR2_ANSWER_DOUBLE);
01390    } else {
01391       res = openr2_chan_answer_call_with_mode(p->r2chan, OR2_ANSWER_SIMPLE);
01392    } 
01393 #else
01394    res = openr2_chan_answer_call(p->r2chan);
01395 #endif
01396    return res;
01397 }
01398 
01399 static openr2_calling_party_category_t dahdi_r2_get_channel_category(struct ast_channel *c)
01400 {
01401    openr2_calling_party_category_t cat;
01402    const char *catstr = pbx_builtin_getvar_helper(c, "MFCR2_CATEGORY");
01403    struct dahdi_pvt *p = c->tech_pvt;
01404    if (ast_strlen_zero(catstr)) {
01405       ast_log(LOG_DEBUG, "no MFC/R2 category specified for chan %s, using default %s\n", 
01406             c->name, openr2_proto_get_category_string(p->mfcr2_category));
01407       return p->mfcr2_category;
01408    }
01409    if ((cat = openr2_proto_get_category(catstr)) == OR2_CALLING_PARTY_CATEGORY_UNKNOWN) {
01410       ast_log(LOG_WARNING, "Invalid category specified '%s' for chan %s, using default %s\n",
01411             catstr, c->name, openr2_proto_get_category_string(p->mfcr2_category));
01412       return p->mfcr2_category;
01413    }
01414    ast_log(LOG_DEBUG, "Using category %s\n", catstr);
01415    return cat;
01416 }
01417 
01418 static void dahdi_r2_on_call_init(openr2_chan_t *r2chan)
01419 {
01420    struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
01421    ast_mutex_lock(&p->lock);
01422    if (p->mfcr2call) {
01423       ast_mutex_unlock(&p->lock);
01424       /* TODO: This can happen when some other thread just finished zt_request requesting this very same
01425       interface but has not yet seized the line (zt_call), and the far end wins and seize the line,
01426       can we avoid this somehow?, at this point when zt_call send the seize, it is likely that since
01427       the other end will see our seize as a forced release and drop the call, we will see an invalid
01428       pattern that will be seen and treated as protocol error. */
01429       ast_log(LOG_ERROR, "Collision of calls on chan %d detected!.\n", openr2_chan_get_number(r2chan));
01430       return;
01431    }
01432    p->mfcr2call = 1;
01433    /* better safe than sorry ... */
01434    p->cid_name[0] = 0;
01435    p->cid_num[0] = 0;
01436    p->rdnis[0] = 0;
01437    p->exten[0] = 0;
01438    p->mfcr2_ani_index = 0;
01439    p->mfcr2_dnis_index = 0;
01440    p->mfcr2_dnis_matched = 0;
01441    p->mfcr2_call_accepted = 0;
01442    ast_mutex_unlock(&p->lock);
01443    ast_verbose("New MFC/R2 call detected on chan %d.\n", openr2_chan_get_number(r2chan));
01444 }
01445 
01446 static void handle_alarms(struct dahdi_pvt *p, int alarms);
01447 static int get_alarms(struct dahdi_pvt *p);
01448 static void dahdi_r2_on_hardware_alarm(openr2_chan_t *r2chan, int alarm)
01449 {
01450    int res;
01451    struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
01452    ast_mutex_lock(&p->lock);
01453    p->inalarm = alarm ? 1 : 0;
01454    if (p->inalarm) {
01455       res = get_alarms(p);
01456       /* unknown_alarm may be set here */
01457       handle_alarms(p, res);
01458    } else {
01459       if (!p->unknown_alarm) {
01460          ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", p->channel);
01461          manager_event(EVENT_FLAG_SYSTEM, "AlarmClear", "Channel: %d\r\n", p->channel);
01462       } else {
01463          p->unknown_alarm = 0;
01464       }
01465    }
01466    ast_mutex_unlock(&p->lock);
01467    ast_log(LOG_WARNING, "Zap alarm on chan %d.\n", openr2_chan_get_number(r2chan));
01468 }
01469 
01470 static void dahdi_r2_on_os_error(openr2_chan_t *r2chan, int errorcode)
01471 {
01472    ast_log(LOG_ERROR, "OS error on chan %d: %s\n", openr2_chan_get_number(r2chan), strerror(errorcode));
01473 }
01474 
01475 static void dahdi_r2_on_protocol_error(openr2_chan_t *r2chan, openr2_protocol_error_t reason)
01476 {
01477    struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
01478    ast_log(LOG_ERROR, "MFC/R2 protocol error on chan %d: %s\n", openr2_chan_get_number(r2chan), openr2_proto_get_error(reason));
01479    if (p->owner) {
01480       p->owner->hangupcause = AST_CAUSE_PROTOCOL_ERROR;
01481       p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
01482    } 
01483    ast_mutex_lock(&p->lock);
01484    p->mfcr2call = 0;
01485    ast_mutex_unlock(&p->lock);
01486 }
01487 
01488 static void dahdi_r2_disconnect_call(struct dahdi_pvt *p, openr2_call_disconnect_cause_t cause)
01489 {
01490    if (openr2_chan_disconnect_call(p->r2chan, cause)) {
01491       ast_log(LOG_NOTICE, "Bad! failed to disconnect call on channel %d with reason %s, hope for the best!\n", 
01492             p->channel, openr2_proto_get_disconnect_string(cause));
01493       /* force the chan to idle and release the call flag now since we will not see a clean on_call_end */
01494       openr2_chan_set_idle(p->r2chan);
01495       ast_mutex_lock(&p->lock);
01496       p->mfcr2call = 0;
01497       ast_mutex_unlock(&p->lock);
01498    }
01499 }
01500 
01501 static void dahdi_r2_on_call_offered(openr2_chan_t *r2chan, const char *ani, const char *dnis, openr2_calling_party_category_t category)
01502 {
01503    struct dahdi_pvt *p;
01504    struct ast_channel *c;
01505    ast_verbose("MFC/R2 call offered on chan %d. ANI = %s, DNIS = %s, Category = %s\n", 
01506          openr2_chan_get_number(r2chan), ani ? ani : "(restricted)", dnis, openr2_proto_get_category_string(category));
01507    p = openr2_chan_get_client_data(r2chan);
01508    if (!p->mfcr2_allow_collect_calls && category == OR2_CALLING_PARTY_CATEGORY_COLLECT_CALL) {
01509       ast_log(LOG_NOTICE, "Rejecting MFC/R2 collect call on chan %d\n", p->channel);
01510       dahdi_r2_disconnect_call(p, OR2_CAUSE_COLLECT_CALL_REJECTED);
01511       return;
01512    }
01513    ast_mutex_lock(&p->lock);
01514    p->mfcr2_recvd_category = category;
01515    /* if we're not supposed to use CID, clear whatever we have */
01516    if (!p->use_callerid) {
01517       ast_log(LOG_DEBUG, "No CID allowed in configuration, CID is being cleared!\n");
01518       p->cid_num[0] = 0;
01519    p->cid_name[0] = 0;
01520    }
01521    /* if we're supposed to answer immediately, clear DNIS and set 's' exten */
01522    if (p->immediate || !openr2_context_get_max_dnis(openr2_chan_get_context(r2chan))) {
01523       ast_log(LOG_DEBUG, "Setting exten => s because of immediate or 0 DNIS configured\n");
01524       p->exten[0] = 's';
01525       p->exten[1] = 0;
01526    }
01527    ast_mutex_unlock(&p->lock);
01528    if (!ast_exists_extension(NULL, p->context, p->exten, 1, p->cid_num)) {
01529       ast_log(LOG_NOTICE, "MFC/R2 call on channel %d requested non-existent extension '%s' in context '%s'. Rejecting call.\n",
01530             p->channel, p->exten, p->context);
01531       dahdi_r2_disconnect_call(p, OR2_CAUSE_UNALLOCATED_NUMBER);
01532    } else {
01533       /* if the user does not want to accept on offer, then we should launch the PBX thread now */
01534       if (!p->mfcr2_accept_on_offer) {
01535          c = dahdi_new(p, AST_STATE_RING, 1, SUB_REAL, DAHDI_LAW_ALAW, 0);
01536          if (!c) {
01537             ast_log(LOG_ERROR, "Unable to create PBX channel on chan %d\n", p->channel);
01538             dahdi_r2_disconnect_call(p, OR2_CAUSE_OUT_OF_ORDER);
01539          }
01540          /* Don't disable reading since we still need to generate MF tone to accept
01541             the call or reject it and detect the tone off condition of the other end */
01542       } else if (p->mfcr2_charge_calls) {
01543          ast_log(LOG_DEBUG, "Accepting MFC/R2 call on offer with charge on chan %d\n", p->channel);
01544          openr2_chan_accept_call(r2chan, OR2_CALL_WITH_CHARGE);
01545       } else {
01546          ast_log(LOG_DEBUG, "Accepting MFC/R2 call on offer with no charge on chan %d\n", p->channel);
01547          openr2_chan_accept_call(r2chan, OR2_CALL_NO_CHARGE);
01548       }  
01549    }  
01550 }
01551 
01552 static void dahdi_r2_on_call_end(openr2_chan_t *r2chan)
01553 {
01554    struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
01555    ast_verbose("MFC/R2 call end on chan %d\n", p->channel);
01556    ast_mutex_lock(&p->lock);
01557    p->mfcr2call = 0;
01558    ast_mutex_unlock(&p->lock);
01559 }
01560 
01561 static void dahdi_enable_ec(struct dahdi_pvt *p);
01562 static void dahdi_r2_on_call_accepted(openr2_chan_t *r2chan, openr2_call_mode_t mode)
01563 {
01564    struct dahdi_pvt *p = NULL;
01565    struct ast_channel *c = NULL;
01566    p = openr2_chan_get_client_data(r2chan);
01567    dahdi_enable_ec(p);
01568    p->mfcr2_call_accepted = 1;
01569    if (OR2_DIR_BACKWARD == openr2_chan_get_direction(r2chan)) {
01570       ast_verbose("MFC/R2 call has been accepted on backward channel %d\n", openr2_chan_get_number(r2chan));
01571       /* if accept on offer is not set, it means at this point the PBX thread is already
01572          launched and therefore this callback is being executed in the PBX thread rather than
01573          the monitor thread, don't launch any other thread, just disable the R2 reading and
01574          answer the call */
01575       if (!p->mfcr2_accept_on_offer) {
01576          openr2_chan_disable_read(r2chan);
01577          ast_verbose("Answering MFC/R2 call after accepting it on chan %d\n", openr2_chan_get_number(r2chan));
01578          dahdi_r2_answer(p);
01579          return;
01580       }
01581       c = dahdi_new(p, AST_STATE_RING, 1, SUB_REAL, DAHDI_LAW_ALAW, 0);
01582       if (c) {
01583          /* chan_dahdi will take care of reading from now on, tell the library to forget about it */
01584          openr2_chan_disable_read(r2chan);
01585       } else {
01586          ast_log(LOG_ERROR, "Unable to create PBX channel on chan %d\n", p->channel);
01587          dahdi_r2_disconnect_call(p, OR2_CAUSE_OUT_OF_ORDER);
01588          return;
01589       }
01590    } else {
01591       ast_verbose("Call accepted on forward channel %d\n", p->channel);
01592       p->subs[SUB_REAL].needringing = 1;
01593       p->dialing = 0;
01594       /* chan_dahdi will take care of reading from now on, tell the library to forget about it */
01595       openr2_chan_disable_read(r2chan);
01596    }  
01597 }
01598 
01599 static void dahdi_r2_on_call_answered(openr2_chan_t *r2chan)
01600 {
01601    struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
01602    ast_verbose("MFC/R2 call has been answered on chan %d\n", openr2_chan_get_number(r2chan));
01603    p->subs[SUB_REAL].needanswer = 1;
01604 }
01605 
01606 static void dahdi_r2_on_call_read(openr2_chan_t *r2chan, const unsigned char *buf, int buflen)
01607 {
01608    /*ast_log(LOG_DEBUG, "Read data from dahdi channel %d\n", openr2_chan_get_number(r2chan));*/
01609 }
01610 
01611 /*static int dahdi_r2_cause_to_ast_cause(openr2_call_disconnect_cause_t cause)
01612 {
01613    switch (cause) {
01614    case OR2_CAUSE_BUSY_NUMBER:
01615       return AST_CAUSE_BUSY;
01616    case OR2_CAUSE_NETWORK_CONGESTION:
01617       return AST_CAUSE_CONGESTION;
01618    case OR2_CAUSE_OUT_OF_ORDER:
01619       return AST_CAUSE_DESTINATION_OUT_OF_ORDER;
01620    case OR2_CAUSE_UNALLOCATED_NUMBER:
01621       return AST_CAUSE_UNREGISTERED;
01622    case OR2_CAUSE_NO_ANSWER:
01623       return AST_CAUSE_NO_ANSWER;
01624    case OR2_CAUSE_NORMAL_CLEARING:
01625       return AST_CAUSE_NORMAL_CLEARING;
01626    case OR2_CAUSE_UNSPECIFIED:
01627    default:
01628       return AST_CAUSE_NOTDEFINED;
01629    }  
01630 }*/
01631 
01632 static void dahdi_r2_on_call_disconnect(openr2_chan_t *r2chan, openr2_call_disconnect_cause_t cause)
01633 {
01634    struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
01635    ast_verbose("MFC/R2 call disconnected on chan %d\n", openr2_chan_get_number(r2chan));
01636    ast_mutex_lock(&p->lock);
01637    if (p->owner) {
01638       /* when we have an owner we don't call openr2_chan_disconnect_call here, that will
01639          be done in zt_hangup */
01640       if (p->owner->_state == AST_STATE_UP) {
01641          p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
01642          ast_mutex_unlock(&p->lock);
01643       } else if (openr2_chan_get_direction(r2chan) == OR2_DIR_FORWARD) {
01644          /* being the forward side we must report what happened to the call to whoever requested it */
01645          switch (cause) {
01646          case OR2_CAUSE_BUSY_NUMBER:
01647             p->owner->hangupcause = AST_CAUSE_BUSY;
01648             p->subs[SUB_REAL].needbusy = 1;
01649             break;
01650          case OR2_CAUSE_NUMBER_CHANGED:
01651             p->owner->hangupcause = AST_CAUSE_NUMBER_CHANGED;
01652             p->subs[SUB_REAL].needcongestion = 1;
01653             break;
01654          case OR2_CAUSE_NETWORK_CONGESTION:
01655             p->owner->hangupcause = AST_CAUSE_NETWORK_OUT_OF_ORDER;
01656             p->subs[SUB_REAL].needcongestion = 1;
01657             break;
01658          case OR2_CAUSE_OUT_OF_ORDER:
01659             p->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
01660             p->subs[SUB_REAL].needcongestion = 1;
01661             break;
01662          case OR2_CAUSE_UNALLOCATED_NUMBER:
01663             p->owner->hangupcause = AST_CAUSE_UNALLOCATED;
01664             p->subs[SUB_REAL].needcongestion = 1;
01665             break;
01666          case OR2_CAUSE_NO_ANSWER:
01667             p->owner->hangupcause = AST_CAUSE_NO_ANSWER;
01668             p->subs[SUB_REAL].needcongestion = 1;
01669             break;
01670          case OR2_CAUSE_UNSPECIFIED:
01671             p->owner->hangupcause = AST_CAUSE_NOTDEFINED;
01672             p->subs[SUB_REAL].needcongestion = 1;
01673             break;
01674          case OR2_CAUSE_NORMAL_CLEARING:
01675             p->owner->hangupcause = AST_CAUSE_NORMAL_CLEARING;
01676             p->subs[SUB_REAL].needcongestion = 1;
01677             break;
01678          default:
01679             ast_log(LOG_WARNING, "Unhandled cause %d\n", cause);
01680          }
01681          p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
01682          ast_mutex_unlock(&p->lock);
01683       } else {
01684          ast_mutex_unlock(&p->lock);
01685          /* being the backward side and not UP yet, we only need to request hangup */
01686          /* TODO: what about doing this same thing when were AST_STATE_UP? */
01687          ast_queue_hangup(p->owner);
01688       }  
01689    } else {
01690       ast_mutex_unlock(&p->lock);
01691       /* no owner, therefore we can't use zt_hangup to disconnect, do it right now */
01692       dahdi_r2_disconnect_call(p, OR2_CAUSE_NORMAL_CLEARING);
01693    }
01694 }
01695 
01696 static void dahdi_r2_write_log(openr2_log_level_t level, char *logmessage)
01697 {
01698    switch (level) {
01699    case OR2_LOG_NOTICE:
01700       ast_verbose("%s", logmessage);
01701       break;
01702    case OR2_LOG_WARNING:
01703       ast_log(LOG_WARNING, "%s", logmessage);
01704       break;
01705    case OR2_LOG_ERROR:
01706       ast_log(LOG_ERROR, "%s", logmessage);
01707       break;
01708    case OR2_LOG_STACK_TRACE:
01709    case OR2_LOG_MF_TRACE:
01710    case OR2_LOG_CAS_TRACE:
01711    case OR2_LOG_DEBUG:
01712    case OR2_LOG_EX_DEBUG:
01713       ast_log(LOG_DEBUG, "%s", logmessage);
01714       break;
01715    default:
01716       ast_log(LOG_WARNING, "We should handle logging level %d here.\n", level);
01717       ast_log(LOG_NOTICE, "%s", logmessage);
01718       break;
01719    }
01720 }
01721 
01722 #define DAHDI_R2_REMOTE_BLOCK (1 << 0)
01723 #define DAHDI_R2_LOCAL_BLOCK (1 << 1)
01724 static void dahdi_r2_on_line_blocked(openr2_chan_t *r2chan)
01725 {
01726    struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
01727    ast_log(LOG_NOTICE, "Far end blocked on chan %d\n", p->channel);
01728    ast_mutex_lock(&p->lock);
01729    p->mfcr2block |= DAHDI_R2_REMOTE_BLOCK;
01730    ast_mutex_unlock(&p->lock);
01731 }
01732 
01733 static void dahdi_r2_on_line_idle(openr2_chan_t *r2chan)
01734 {
01735    struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
01736    ast_log(LOG_NOTICE, "Far end unblocked on chan %d\n", openr2_chan_get_number(r2chan));
01737    ast_mutex_lock(&p->lock);
01738    p->mfcr2block &= ~DAHDI_R2_REMOTE_BLOCK;
01739    ast_mutex_unlock(&p->lock);
01740 }
01741 
01742 static void dahdi_r2_on_context_log(openr2_context_t *r2context, openr2_log_level_t level, const char *fmt, va_list ap)
01743    __attribute__((format (printf, 3, 0)));
01744 static void dahdi_r2_on_context_log(openr2_context_t *r2context, openr2_log_level_t level, const char *fmt, va_list ap)
01745 {
01746    char logmsg[256];
01747    char completemsg[sizeof(logmsg)+50];
01748    vsnprintf(logmsg, sizeof(logmsg), fmt, ap);
01749    snprintf(completemsg, sizeof(completemsg), "Context - %s", logmsg);
01750    dahdi_r2_write_log(level, completemsg);
01751 }
01752 
01753 static void dahdi_r2_on_chan_log(openr2_chan_t *r2chan, openr2_log_level_t level, const char *fmt, va_list ap)
01754    __attribute__((format (printf, 3, 0)));
01755 static void dahdi_r2_on_chan_log(openr2_chan_t *r2chan, openr2_log_level_t level, const char *fmt, va_list ap)
01756 {
01757    char logmsg[256];
01758    char completemsg[sizeof(logmsg)+50];
01759    vsnprintf(logmsg, sizeof(logmsg), fmt, ap);
01760    snprintf(completemsg, sizeof(completemsg), "Chan %d - %s", openr2_chan_get_number(r2chan), logmsg);
01761    dahdi_r2_write_log(level, completemsg);
01762 }
01763 
01764 static int dahdi_r2_on_dnis_digit_received(openr2_chan_t *r2chan, char digit)
01765 {
01766    struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
01767    /* if 'immediate' is set, let's stop requesting DNIS */
01768    if (p->immediate) {
01769       return 0;
01770    }
01771    p->exten[p->mfcr2_dnis_index] = digit;
01772    p->rdnis[p->mfcr2_dnis_index] = digit;
01773    p->mfcr2_dnis_index++;
01774    p->exten[p->mfcr2_dnis_index] = 0;
01775    p->rdnis[p->mfcr2_dnis_index] = 0;
01776    /*
01777    ast_log(LOG_DEBUG, "Got digit %c in dahdi, dnis so far: %s\n", digit, p->exten);
01778    int ret;
01779    ret = ast_exists_extension(NULL, p->context, p->exten, 1, p->cid_num);
01780    ast_log(LOG_DEBUG, "ast_exists_extension(%s, %s, 1, %s) = %d\n", p->context, p->exten, p->cid_num, ret);
01781    ret = ast_matchmore_extension(NULL, p->context, p->exten, 1, p->cid_num);
01782    ast_log(LOG_DEBUG, "ast_matchmore_extension(%s, %s, 1, %s) = %d\n", p->context, p->exten, p->cid_num, ret);
01783    */
01784    /* if the DNIS is a match and cannot match more, stop requesting DNIS */
01785    if ((p->mfcr2_dnis_matched || 
01786        (ast_exists_extension(NULL, p->context, p->exten, 1, p->cid_num) && (p->mfcr2_dnis_matched = 1))) &&
01787        !ast_matchmore_extension(NULL, p->context, p->exten, 1, p->cid_num)) {
01788       return 0;
01789    }
01790    /* otherwise keep going */
01791    return 1;
01792 }
01793 
01794 static void dahdi_r2_on_ani_digit_received(openr2_chan_t *r2chan, char digit)
01795 {
01796    struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
01797    p->cid_num[p->mfcr2_ani_index] = digit;
01798    p->cid_name[p->mfcr2_ani_index] = digit;
01799    p->mfcr2_ani_index++;
01800    p->cid_num[p->mfcr2_ani_index] = 0;
01801    p->cid_name[p->mfcr2_ani_index] = 0;
01802 }
01803 
01804 static void dahdi_r2_on_billing_pulse_received(openr2_chan_t *r2chan)
01805 {
01806    ast_log(LOG_NOTICE, "MFC/R2 billing pulse received on channel %d\n", openr2_chan_get_number(r2chan));
01807 }
01808 
01809 static openr2_event_interface_t dahdi_r2_event_iface = {
01810    .on_call_init = dahdi_r2_on_call_init,
01811    .on_call_offered = dahdi_r2_on_call_offered,
01812    .on_call_accepted = dahdi_r2_on_call_accepted,
01813    .on_call_answered = dahdi_r2_on_call_answered,
01814    .on_call_disconnect = dahdi_r2_on_call_disconnect,
01815    .on_call_end = dahdi_r2_on_call_end,
01816    .on_call_read = dahdi_r2_on_call_read,
01817    .on_hardware_alarm = dahdi_r2_on_hardware_alarm,
01818    .on_os_error = dahdi_r2_on_os_error,
01819    .on_protocol_error = dahdi_r2_on_protocol_error,
01820    .on_line_blocked = dahdi_r2_on_line_blocked,
01821    .on_line_idle = dahdi_r2_on_line_idle,
01822    /* cast seems to be needed to get rid of the annoying warning regarding format attribute */
01823    .on_context_log = (openr2_handle_context_logging_func)dahdi_r2_on_context_log,
01824    .on_dnis_digit_received = dahdi_r2_on_dnis_digit_received,
01825    .on_ani_digit_received = dahdi_r2_on_ani_digit_received,
01826    /* so far we do nothing with billing pulses, just log it */
01827    .on_billing_pulse_received = dahdi_r2_on_billing_pulse_received 
01828 };
01829 
01830 static inline int16_t dahdi_r2_alaw_to_linear(uint8_t sample)
01831 {
01832    return AST_ALAW(sample);
01833 }
01834 
01835 static inline uint8_t dahdi_r2_linear_to_alaw(int sample)
01836 {
01837    return AST_LIN2A(sample);
01838 }
01839 
01840 static openr2_transcoder_interface_t dahdi_r2_transcode_iface = {
01841    dahdi_r2_alaw_to_linear,
01842    dahdi_r2_linear_to_alaw
01843 };
01844 
01845 #endif /* HAVE_OPENR2 */
01846 
01847 static int restore_gains(struct dahdi_pvt *p);
01848 
01849 static void swap_subs(struct dahdi_pvt *p, int a, int b)
01850 {
01851    int tchan;
01852    int tinthreeway;
01853    struct ast_channel *towner;
01854 
01855    ast_log(LOG_DEBUG, "Swapping %d and %d\n", a, b);
01856 
01857    tchan = p->subs[a].chan;
01858    towner = p->subs[a].owner;
01859    tinthreeway = p->subs[a].inthreeway;
01860 
01861    p->subs[a].chan = p->subs[b].chan;
01862    p->subs[a].owner = p->subs[b].owner;
01863    p->subs[a].inthreeway = p->subs[b].inthreeway;
01864 
01865    p->subs[b].chan = tchan;
01866    p->subs[b].owner = towner;
01867    p->subs[b].inthreeway = tinthreeway;
01868 
01869    if (p->subs[a].owner) 
01870       p->subs[a].owner->fds[0] = p->subs[a].dfd;
01871    if (p->subs[b].owner) 
01872       p->subs[b].owner->fds[0] = p->subs[b].dfd;
01873    wakeup_sub(p, a, NULL);
01874    wakeup_sub(p, b, NULL);
01875 }
01876 
01877 static int dahdi_open(char *fn)
01878 {
01879    int fd;
01880    int isnum;
01881    int chan = 0;
01882    int bs;
01883    int x;
01884    isnum = 1;
01885    for (x = 0; x < strlen(fn); x++) {
01886       if (!isdigit(fn[x])) {
01887          isnum = 0;
01888          break;
01889       }
01890    }
01891    if (isnum) {
01892       chan = atoi(fn);
01893       if (chan < 1) {
01894          ast_log(LOG_WARNING, "Invalid channel number '%s'\n", fn);
01895          return -1;
01896       }
01897       fn = DAHDI_FILE_CHANNEL;
01898    }
01899    fd = open(fn, O_RDWR | O_NONBLOCK);
01900    if (fd < 0) {
01901       ast_log(LOG_WARNING, "Unable to open '%s': %s\n", fn, strerror(errno));
01902       return -1;
01903    }
01904    if (chan) {
01905       if (ioctl(fd, DAHDI_SPECIFY, &chan)) {
01906          x = errno;
01907          close(fd);
01908          errno = x;
01909          ast_log(LOG_WARNING, "Unable to specify channel %d: %s\n", chan, strerror(errno));
01910          return -1;
01911       }
01912    }
01913    bs = READ_SIZE;
01914    if (ioctl(fd, DAHDI_SET_BLOCKSIZE, &bs) == -1) {
01915       ast_log(LOG_WARNING, "Unable to set blocksize '%d': %s\n", bs,  strerror(errno));
01916       x = errno;
01917       close(fd);
01918       errno = x;
01919       return -1;
01920    }
01921    return fd;
01922 }
01923 
01924 static void dahdi_close(int fd)
01925 {
01926    if (fd > 0)
01927       close(fd);
01928 }
01929 
01930 static void dahdi_close_sub(struct dahdi_pvt *chan_pvt, int sub_num)
01931 {
01932    dahdi_close(chan_pvt->subs[sub_num].dfd);
01933    chan_pvt->subs[sub_num].dfd = -1;
01934 }
01935  
01936 #ifdef HAVE_PRI
01937 static void dahdi_close_pri_fd(struct dahdi_pri *pri, int fd_num)
01938 {
01939    dahdi_close(pri->fds[fd_num]);
01940    pri->fds[fd_num] = -1;
01941 }
01942 #endif
01943 
01944 static int dahdi_setlinear(int dfd, int linear)
01945 {
01946    int res;
01947    res = ioctl(dfd, DAHDI_SETLINEAR, &linear);
01948    if (res)
01949       return res;
01950    return 0;
01951 }
01952 
01953 
01954 static int alloc_sub(struct dahdi_pvt *p, int x)
01955 {
01956    struct dahdi_bufferinfo bi;
01957    int res;
01958    if (p->subs[x].dfd < 0) {
01959       p->subs[x].dfd = dahdi_open(DAHDI_FILE_PSEUDO);
01960       if (p->subs[x].dfd > -1) {
01961          res = ioctl(p->subs[x].dfd, DAHDI_GET_BUFINFO, &bi);
01962          if (!res) {
01963             bi.txbufpolicy = p->buf_policy;
01964             bi.rxbufpolicy = p->buf_policy;
01965             bi.numbufs = p->buf_no;
01966             res = ioctl(p->subs[x].dfd, DAHDI_SET_BUFINFO, &bi);
01967             if (res < 0) {
01968                ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d: %s\n", x, strerror(errno));
01969             }
01970          } else 
01971             ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d: %s\n", x, strerror(errno));
01972          if (ioctl(p->subs[x].dfd, DAHDI_CHANNO, &p->subs[x].chan) == 1) {
01973             ast_log(LOG_WARNING, "Unable to get channel number for pseudo channel on FD %d: %s\n", p->subs[x].dfd, strerror(errno));
01974             dahdi_close_sub(p, x);
01975             return -1;
01976          }
01977          if (option_debug)
01978             ast_log(LOG_DEBUG, "Allocated %s subchannel on FD %d channel %d\n", subnames[x], p->subs[x].dfd, p->subs[x].chan);
01979          return 0;
01980       } else
01981          ast_log(LOG_WARNING, "Unable to open pseudo channel: %s\n", strerror(errno));
01982       return -1;
01983    }
01984    ast_log(LOG_WARNING, "%s subchannel of %d already in use\n", subnames[x], p->channel);
01985    return -1;
01986 }
01987 
01988 static int unalloc_sub(struct dahdi_pvt *p, int x)
01989 {
01990    if (!x) {
01991       ast_log(LOG_WARNING, "Trying to unalloc the real channel %d?!?\n", p->channel);
01992       return -1;
01993    }
01994    ast_log(LOG_DEBUG, "Released sub %d of channel %d\n", x, p->channel);
01995    dahdi_close_sub(p, x);
01996    p->subs[x].linear = 0;
01997    p->subs[x].chan = 0;
01998    p->subs[x].owner = NULL;
01999    p->subs[x].inthreeway = 0;
02000    p->polarity = POLARITY_IDLE;
02001    memset(&p->subs[x].curconf, 0, sizeof(p->subs[x].curconf));
02002    return 0;
02003 }
02004 
02005 static int digit_to_dtmfindex(char digit)
02006 {
02007    if (isdigit(digit))
02008       return DAHDI_TONE_DTMF_BASE + (digit - '0');
02009    else if (digit >= 'A' && digit <= 'D')
02010       return DAHDI_TONE_DTMF_A + (digit - 'A');
02011    else if (digit >= 'a' && digit <= 'd')
02012       return DAHDI_TONE_DTMF_A + (digit - 'a');
02013    else if (digit == '*')
02014       return DAHDI_TONE_DTMF_s;
02015    else if (digit == '#')
02016       return DAHDI_TONE_DTMF_p;
02017    else
02018       return -1;
02019 }
02020 
02021 static int dahdi_digit_begin(struct ast_channel *chan, char digit)
02022 {
02023    struct dahdi_pvt *pvt;
02024    int index;
02025    int dtmf = -1;
02026    
02027    pvt = chan->tech_pvt;
02028 
02029    ast_mutex_lock(&pvt->lock);
02030 
02031    index = dahdi_get_index(chan, pvt, 0);
02032 
02033    if ((index != SUB_REAL) || !pvt->owner)
02034       goto out;
02035 
02036 #ifdef HAVE_PRI
02037    if (pvt->sig == SIG_PRI
02038       && chan->_state == AST_STATE_DIALING) {
02039       if (pvt->call_level < DAHDI_CALL_LEVEL_OVERLAP) {
02040          unsigned int len;
02041 
02042          len = strlen(pvt->dialdest);
02043          if (len < sizeof(pvt->dialdest) - 1) {
02044             ast_log(LOG_DEBUG,
02045                "Queueing digit '%c' since setup_ack not yet received\n", digit);
02046             pvt->dialdest[len++] = digit;
02047             pvt->dialdest[len] = '\0';
02048          } else {
02049             ast_log(LOG_WARNING,
02050                "Span %d: Deferred digit buffer overflow for digit '%c'.\n",
02051                pvt->span, digit);
02052          }
02053          goto out;
02054       }
02055       if (pvt->call_level < DAHDI_CALL_LEVEL_PROCEEDING) {
02056          if (!pri_grab(pvt, pvt->pri)) {
02057             pri_information(pvt->pri->pri, pvt->call, digit);
02058             pri_rel(pvt->pri);
02059          } else {
02060             ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", pvt->span);
02061          }
02062          goto out;
02063       }
02064       if (pvt->call_level < DAHDI_CALL_LEVEL_CONNECT) {
02065          ast_log(LOG_WARNING,
02066             "Span %d: Digit '%c' may be ignored by peer. (Call level:%d)\n",
02067             pvt->span, digit, pvt->call_level);
02068       }
02069    }
02070 #endif
02071    if ((dtmf = digit_to_dtmfindex(digit)) == -1)
02072       goto out;
02073 
02074    if (pvt->pulse || ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_SENDTONE, &dtmf)) {
02075       int res;
02076       struct dahdi_dialoperation zo = {
02077          .op = DAHDI_DIAL_OP_APPEND,
02078          .dialstr[0] = 'T',
02079          .dialstr[1] = digit,
02080          .dialstr[2] = 0,
02081       };
02082       if ((res = ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_DIAL, &zo)))
02083          ast_log(LOG_WARNING, "Couldn't dial digit %c: %s\n", digit, strerror(errno));
02084       else
02085          pvt->dialing = 1;
02086    } else {
02087       ast_log(LOG_DEBUG, "Started VLDTMF digit '%c'\n", digit);
02088       pvt->dialing = 1;
02089       pvt->begindigit = digit;
02090    }
02091 
02092 out:
02093    ast_mutex_unlock(&pvt->lock);
02094 
02095    return 0;
02096 }
02097 
02098 static int dahdi_digit_end(struct ast_channel *chan, char digit, unsigned int duration)
02099 {
02100    struct dahdi_pvt *pvt;
02101    int res = 0;
02102    int index;
02103    int x;
02104    
02105    pvt = chan->tech_pvt;
02106 
02107    ast_mutex_lock(&pvt->lock);
02108    
02109    index = dahdi_get_index(chan, pvt, 0);
02110 
02111    if ((index != SUB_REAL) || !pvt->owner || pvt->pulse)
02112       goto out;
02113 
02114 #ifdef HAVE_PRI
02115    /* This means that the digit was already sent via PRI signalling */
02116    if (pvt->sig == SIG_PRI && !pvt->begindigit)
02117       goto out;
02118 #endif
02119 
02120    if (pvt->begindigit) {
02121       x = -1;
02122       ast_log(LOG_DEBUG, "Ending VLDTMF digit '%c'\n", digit);
02123       res = ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_SENDTONE, &x);
02124       pvt->dialing = 0;
02125       pvt->begindigit = 0;
02126    }
02127 
02128 out:
02129    ast_mutex_unlock(&pvt->lock);
02130 
02131    return res;
02132 }
02133 
02134 static char *events[] = {
02135    "No event",
02136    "On hook",
02137    "Ring/Answered",
02138    "Wink/Flash",
02139    "Alarm",
02140    "No more alarm",
02141    "HDLC Abort",
02142    "HDLC Overrun",
02143    "HDLC Bad FCS",
02144    "Dial Complete",
02145    "Ringer On",
02146    "Ringer Off",
02147    "Hook Transition Complete",
02148    "Bits Changed",
02149    "Pulse Start",
02150    "Timer Expired",
02151    "Timer Ping",
02152    "Polarity Reversal",
02153    "Ring Begin",
02154 };
02155 
02156 static struct {
02157    int alarm;
02158    char *name;
02159 } alarms[] = {
02160    { DAHDI_ALARM_RED, "Red Alarm" },
02161    { DAHDI_ALARM_YELLOW, "Yellow Alarm" },
02162    { DAHDI_ALARM_BLUE, "Blue Alarm" },
02163    { DAHDI_ALARM_RECOVER, "Recovering" },
02164    { DAHDI_ALARM_LOOPBACK, "Loopback" },
02165    { DAHDI_ALARM_NOTOPEN, "Not Open" },
02166    { DAHDI_ALARM_NONE, "None" },
02167 };
02168 
02169 static char *alarm2str(int alarm)
02170 {
02171    int x;
02172    for (x = 0; x < sizeof(alarms) / sizeof(alarms[0]); x++) {
02173       if (alarms[x].alarm & alarm)
02174          return alarms[x].name;
02175    }
02176    return alarm ? "Unknown Alarm" : "No Alarm";
02177 }
02178 
02179 static char *event2str(int event)
02180 {
02181    static char buf[256];
02182    if ((event < (sizeof(events) / sizeof(events[0]))) && (event > -1))
02183       return events[event];
02184    sprintf(buf, "Event %d", event); /* safe */
02185    return buf;
02186 }
02187 
02188 #ifdef HAVE_PRI
02189 static char *dialplan2str(int dialplan)
02190 {
02191    if (dialplan == -1) {
02192       return("Dynamically set dialplan in ISDN");
02193    }
02194    return (pri_plan2str(dialplan));
02195 }
02196 #endif
02197 
02198 static char *dahdi_sig2str(int sig)
02199 {
02200    static char buf[256];
02201    switch (sig) {
02202    case SIG_EM:
02203       return "E & M Immediate";
02204    case SIG_EMWINK:
02205       return "E & M Wink";
02206    case SIG_EM_E1:
02207       return "E & M E1";
02208    case SIG_FEATD:
02209       return "Feature Group D (DTMF)";
02210    case SIG_FEATDMF:
02211       return "Feature Group D (MF)";
02212    case SIG_FEATDMF_TA:
02213       return "Feature Groud D (MF) Tandem Access";
02214    case SIG_FEATB:
02215       return "Feature Group B (MF)";
02216    case SIG_E911:
02217       return "E911 (MF)";
02218    case SIG_FGC_CAMA:
02219       return "FGC/CAMA (Dialpulse)";
02220    case SIG_FGC_CAMAMF:
02221       return "FGC/CAMA (MF)";
02222    case SIG_FXSLS:
02223       return "FXS Loopstart";
02224    case SIG_FXSGS:
02225       return "FXS Groundstart";
02226    case SIG_FXSKS:
02227       return "FXS Kewlstart";
02228    case SIG_FXOLS:
02229       return "FXO Loopstart";
02230    case SIG_FXOGS:
02231       return "FXO Groundstart";
02232    case SIG_FXOKS:
02233       return "FXO Kewlstart";
02234    case SIG_PRI:
02235       return "ISDN PRI";
02236    case SIG_MFCR2:
02237       return "MFC/R2";
02238    case SIG_SF:
02239       return "SF (Tone) Immediate";
02240    case SIG_SFWINK:
02241       return "SF (Tone) Wink";
02242    case SIG_SF_FEATD:
02243       return "SF (Tone) with Feature Group D (DTMF)";
02244    case SIG_SF_FEATDMF:
02245       return "SF (Tone) with Feature Group D (MF)";
02246    case SIG_SF_FEATB:
02247       return "SF (Tone) with Feature Group B (MF)";
02248    case SIG_GR303FXOKS:
02249       return "GR-303 with FXOKS";
02250    case SIG_GR303FXSKS:
02251       return "GR-303 with FXSKS";
02252    case 0:
02253       return "Pseudo";
02254    default:
02255       snprintf(buf, sizeof(buf), "Unknown signalling %d", sig);
02256       return buf;
02257    }
02258 }
02259 
02260 #define sig2str dahdi_sig2str
02261 
02262 static int conf_add(struct dahdi_pvt *p, struct dahdi_subchannel *c, int index, int slavechannel)
02263 {
02264    /* If the conference already exists, and we're already in it
02265       don't bother doing anything */
02266    struct dahdi_confinfo zi;
02267    
02268    memset(&zi, 0, sizeof(zi));
02269    zi.chan = 0;
02270 
02271    if (slavechannel > 0) {
02272       /* If we have only one slave, do a digital mon */
02273       zi.confmode = DAHDI_CONF_DIGITALMON;
02274       zi.confno = slavechannel;
02275    } else {
02276       if (!index) {
02277          /* Real-side and pseudo-side both participate in conference */
02278          zi.confmode = DAHDI_CONF_REALANDPSEUDO | DAHDI_CONF_TALKER | DAHDI_CONF_LISTENER |
02279             DAHDI_CONF_PSEUDO_TALKER | DAHDI_CONF_PSEUDO_LISTENER;
02280       } else
02281          zi.confmode = DAHDI_CONF_CONF | DAHDI_CONF_TALKER | DAHDI_CONF_LISTENER;
02282       zi.confno = p->confno;
02283    }
02284    if ((zi.confno == c->curconf.confno) && (zi.confmode == c->curconf.confmode))
02285       return 0;
02286    if (c->dfd < 0)
02287       return 0;
02288    if (ioctl(c->dfd, DAHDI_SETCONF, &zi)) {
02289       ast_log(LOG_WARNING, "Failed to add %d to conference %d/%d: %s\n", c->dfd, zi.confmode, zi.confno, strerror(errno));
02290       return -1;
02291    }
02292    if (slavechannel < 1) {
02293       p->confno = zi.confno;
02294    }
02295    memcpy(&c->curconf, &zi, sizeof(c->curconf));
02296    ast_log(LOG_DEBUG, "Added %d to conference %d/%d\n", c->dfd, c->curconf.confmode, c->curconf.confno);
02297    return 0;
02298 }
02299 
02300 static int isourconf(struct dahdi_pvt *p, struct dahdi_subchannel *c)
02301 {
02302    /* If they're listening to our channel, they're ours */  
02303    if ((p->channel == c->curconf.confno) && (c->curconf.confmode == DAHDI_CONF_DIGITALMON))
02304       return 1;
02305    /* If they're a talker on our (allocated) conference, they're ours */
02306    if ((p->confno > 0) && (p->confno == c->curconf.confno) && (c->curconf.confmode & DAHDI_CONF_TALKER))
02307       return 1;
02308    return 0;
02309 }
02310 
02311 static int conf_del(struct dahdi_pvt *p, struct dahdi_subchannel *c, int index)
02312 {
02313    struct dahdi_confinfo zi;
02314    if (/* Can't delete if there's no dfd */
02315       (c->dfd < 0) ||
02316       /* Don't delete from the conference if it's not our conference */
02317       !isourconf(p, c)
02318       /* Don't delete if we don't think it's conferenced at all (implied) */
02319       ) return 0;
02320    memset(&zi, 0, sizeof(zi));
02321    if (ioctl(c->dfd, DAHDI_SETCONF, &zi)) {
02322       ast_log(LOG_WARNING, "Failed to drop %d from conference %d/%d: %s\n", c->dfd, c->curconf.confmode, c->curconf.confno, strerror(errno));
02323       return -1;
02324    }
02325    ast_log(LOG_DEBUG, "Removed %d from conference %d/%d\n", c->dfd, c->curconf.confmode, c->curconf.confno);
02326    memcpy(&c->curconf, &zi, sizeof(c->curconf));
02327    return 0;
02328 }
02329 
02330 static int isslavenative(struct dahdi_pvt *p, struct dahdi_pvt **out)
02331 {
02332    int x;
02333    int useslavenative;
02334    struct dahdi_pvt *slave = NULL;
02335    /* Start out optimistic */
02336    useslavenative = 1;
02337    /* Update conference state in a stateless fashion */
02338    for (x = 0; x < 3; x++) {
02339       /* Any three-way calling makes slave native mode *definitely* out
02340          of the question */
02341       if ((p->subs[x].dfd > -1) && p->subs[x].inthreeway)
02342          useslavenative = 0;
02343    }
02344    /* If we don't have any 3-way calls, check to see if we have
02345       precisely one slave */
02346    if (useslavenative) {
02347       for (x = 0; x < MAX_SLAVES; x++) {
02348          if (p->slaves[x]) {
02349             if (slave) {
02350                /* Whoops already have a slave!  No 
02351                   slave native and stop right away */
02352                slave = NULL;
02353                useslavenative = 0;
02354                break;
02355             } else {
02356                /* We have one slave so far */
02357                slave = p->slaves[x];
02358             }
02359          }
02360       }
02361    }
02362    /* If no slave, slave native definitely out */
02363    if (!slave)
02364       useslavenative = 0;
02365    else if (slave->law != p->law) {
02366       useslavenative = 0;
02367       slave = NULL;
02368    }
02369    if (out)
02370       *out = slave;
02371    return useslavenative;
02372 }
02373 
02374 static int reset_conf(struct dahdi_pvt *p)
02375 {
02376    p->confno = -1;
02377    memset(&p->subs[SUB_REAL].curconf, 0, sizeof(p->subs[SUB_REAL].curconf));
02378    if (p->subs[SUB_REAL].dfd > -1) {
02379       struct dahdi_confinfo zi;
02380 
02381       memset(&zi, 0, sizeof(zi));
02382       if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCONF, &zi))
02383          ast_log(LOG_WARNING, "Failed to reset conferencing on channel %d: %s\n", p->channel, strerror(errno));
02384    }
02385    return 0;
02386 }
02387 
02388 static int update_conf(struct dahdi_pvt *p)
02389 {
02390    int needconf = 0;
02391    int x;
02392    int useslavenative;
02393    struct dahdi_pvt *slave = NULL;
02394 
02395    useslavenative = isslavenative(p, &slave);
02396    /* Start with the obvious, general stuff */
02397    for (x = 0; x < 3; x++) {
02398       /* Look for three way calls */
02399       if ((p->subs[x].dfd > -1) && p->subs[x].inthreeway) {
02400          conf_add(p, &p->subs[x], x, 0);
02401          needconf++;
02402       } else {
02403          conf_del(p, &p->subs[x], x);
02404       }
02405    }
02406    /* If we have a slave, add him to our conference now. or DAX
02407       if this is slave native */
02408    for (x = 0; x < MAX_SLAVES; x++) {
02409       if (p->slaves[x]) {
02410          if (useslavenative)
02411             conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p));
02412          else {
02413             conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, 0);
02414             needconf++;
02415          }
02416       }
02417    }
02418    /* If we're supposed to be in there, do so now */
02419    if (p->inconference && !p->subs[SUB_REAL].inthreeway) {
02420       if (useslavenative)
02421          conf_add(p, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(slave));
02422       else {
02423          conf_add(p, &p->subs[SUB_REAL], SUB_REAL, 0);
02424          needconf++;
02425       }
02426    }
02427    /* If we have a master, add ourselves to his conference */
02428    if (p->master) {
02429       if (isslavenative(p->master, NULL)) {
02430          conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p->master));
02431       } else {
02432          conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, 0);
02433       }
02434    }
02435    if (!needconf) {
02436       /* Nobody is left (or should be left) in our conference.
02437          Kill it. */
02438       p->confno = -1;
02439    }
02440    if (option_debug)
02441       ast_log(LOG_DEBUG, "Updated conferencing on %d, with %d conference users\n", p->channel, needconf);
02442    return 0;
02443 }
02444 
02445 static void dahdi_enable_ec(struct dahdi_pvt *p)
02446 {
02447    int x;
02448    int res;
02449    if (!p)
02450       return;
02451    if (p->echocanon) {
02452       ast_log(LOG_DEBUG, "Echo cancellation already on\n");
02453       return;
02454    }
02455    if (p->digital) {
02456       ast_log(LOG_DEBUG, "Echo cancellation isn't required on digital connection\n");
02457       return;
02458    }
02459    if (p->echocancel) {
02460       if (p->sig == SIG_PRI) {
02461          x = 1;
02462          res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &x);
02463          if (res)
02464             ast_log(LOG_WARNING, "Unable to enable audio mode on channel %d (%s)\n", p->channel, strerror(errno));
02465       }
02466       x = p->echocancel;
02467       res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_ECHOCANCEL, &x);
02468       if (res) 
02469          ast_log(LOG_WARNING, "Unable to enable echo cancellation on channel %d (%s)\n", p->channel, strerror(errno));
02470       else {
02471          p->echocanon = 1;
02472          if (option_debug)
02473             ast_log(LOG_DEBUG, "Enabled echo cancellation on channel %d\n", p->channel);
02474       }
02475    } else if (option_debug)
02476       ast_log(LOG_DEBUG, "No echo cancellation requested\n");
02477 }
02478 
02479 static void dahdi_train_ec(struct dahdi_pvt *p)
02480 {
02481    int x;
02482    int res;
02483    if (p && p->echocancel && p->echotraining) {
02484       x = p->echotraining;
02485       res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_ECHOTRAIN, &x);
02486       if (res)
02487          ast_log(LOG_WARNING, "Unable to request echo training on channel %d: %s\n", p->channel, strerror(errno));
02488       else {
02489          ast_log(LOG_DEBUG, "Engaged echo training on channel %d\n", p->channel);
02490       }
02491    } else
02492       ast_log(LOG_DEBUG, "No echo training requested\n");
02493 }
02494 
02495 static void dahdi_disable_ec(struct dahdi_pvt *p)
02496 {
02497    int x;
02498    int res;
02499    if (p->echocancel) {
02500       x = 0;
02501       res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_ECHOCANCEL, &x);
02502       if (res)
02503          ast_log(LOG_WARNING, "Unable to disable echo cancellation on channel %d: %s\n", p->channel, strerror(errno));
02504       else if (option_debug)
02505          ast_log(LOG_DEBUG, "disabled echo cancellation on channel %d\n", p->channel);
02506    }
02507    p->echocanon = 0;
02508 }
02509 
02510 static void fill_txgain(struct dahdi_gains *g, float gain, int law)
02511 {
02512    int j;
02513    int k;
02514    float linear_gain = pow(10.0, gain / 20.0);
02515 
02516    switch (law) {
02517    case DAHDI_LAW_ALAW:
02518       for (j = 0; j < (sizeof(g->txgain) / sizeof(g->txgain[0])); j++) {
02519          if (gain) {
02520             k = (int) (((float) AST_ALAW(j)) * linear_gain);
02521             if (k > 32767) k = 32767;
02522             if (k < -32767) k = -32767;
02523             g->txgain[j] = AST_LIN2A(k);
02524          } else {
02525             g->txgain[j] = j;
02526          }
02527       }
02528       break;
02529    case DAHDI_LAW_MULAW:
02530       for (j = 0; j < (sizeof(g->txgain) / sizeof(g->txgain[0])); j++) {
02531          if (gain) {
02532             k = (int) (((float) AST_MULAW(j)) * linear_gain);
02533             if (k > 32767) k = 32767;
02534             if (k < -32767) k = -32767;
02535             g->txgain[j] = AST_LIN2MU(k);
02536          } else {
02537             g->txgain[j] = j;
02538          }
02539       }
02540       break;
02541    }
02542 }
02543 
02544 static void fill_rxgain(struct dahdi_gains *g, float gain, int law)
02545 {
02546    int j;
02547    int k;
02548    float linear_gain = pow(10.0, gain / 20.0);
02549 
02550    switch (law) {
02551    case DAHDI_LAW_ALAW:
02552       for (j = 0; j < (sizeof(g->rxgain) / sizeof(g->rxgain[0])); j++) {
02553          if (gain) {
02554             k = (int) (((float) AST_ALAW(j)) * linear_gain);
02555             if (k > 32767) k = 32767;
02556             if (k < -32767) k = -32767;
02557             g->rxgain[j] = AST_LIN2A(k);
02558          } else {
02559             g->rxgain[j] = j;
02560          }
02561       }
02562       break;
02563    case DAHDI_LAW_MULAW:
02564       for (j = 0; j < (sizeof(g->rxgain) / sizeof(g->rxgain[0])); j++) {
02565          if (gain) {
02566             k = (int) (((float) AST_MULAW(j)) * linear_gain);
02567             if (k > 32767) k = 32767;
02568             if (k < -32767) k = -32767;
02569             g->rxgain[j] = AST_LIN2MU(k);
02570          } else {
02571             g->rxgain[j] = j;
02572          }
02573       }
02574       break;
02575    }
02576 }
02577 
02578 static int set_actual_txgain(int fd, int chan, float gain, int law)
02579 {
02580    struct dahdi_gains g;
02581    int res;
02582 
02583    memset(&g, 0, sizeof(g));
02584    g.chan = chan;
02585    res = ioctl(fd, DAHDI_GETGAINS, &g);
02586    if (res) {
02587       if (option_debug)
02588          ast_log(LOG_DEBUG, "Failed to read gains: %s\n", strerror(errno));
02589       return res;
02590    }
02591 
02592    fill_txgain(&g, gain, law);
02593 
02594    return ioctl(fd, DAHDI_SETGAINS, &g);
02595 }
02596 
02597 static int set_actual_rxgain(int fd, int chan, float gain, int law)
02598 {
02599    struct dahdi_gains g;
02600    int res;
02601 
02602    memset(&g, 0, sizeof(g));
02603    g.chan = chan;
02604    res = ioctl(fd, DAHDI_GETGAINS, &g);
02605    if (res) {
02606       ast_log(LOG_DEBUG, "Failed to read gains: %s\n", strerror(errno));
02607       return res;
02608    }
02609 
02610    fill_rxgain(&g, gain, law);
02611 
02612    return ioctl(fd, DAHDI_SETGAINS, &g);
02613 }
02614 
02615 static int set_actual_gain(int fd, int chan, float rxgain, float txgain, int law)
02616 {
02617    return set_actual_txgain(fd, chan, txgain, law) | set_actual_rxgain(fd, chan, rxgain, law);
02618 }
02619 
02620 static int bump_gains(struct dahdi_pvt *p)
02621 {
02622    int res;
02623 
02624    /* Bump receive gain by 5.0db */
02625    res = set_actual_gain(p->subs[SUB_REAL].dfd, 0, p->rxgain + 5.0, p->txgain, p->law);
02626    if (res) {
02627       ast_log(LOG_WARNING, "Unable to bump gain: %s\n", strerror(errno));
02628       return -1;
02629    }
02630 
02631    return 0;
02632 }
02633 
02634 static int restore_gains(struct dahdi_pvt *p)
02635 {
02636    int res;
02637 
02638    res = set_actual_gain(p->subs[SUB_REAL].dfd, 0, p->rxgain, p->txgain, p->law);
02639    if (res) {
02640       ast_log(LOG_WARNING, "Unable to restore gains: %s\n", strerror(errno));
02641       return -1;
02642    }
02643 
02644    return 0;
02645 }
02646 
02647 static inline int dahdi_set_hook(int fd, int hs)
02648 {
02649    int x, res;
02650 
02651    x = hs;
02652    res = ioctl(fd, DAHDI_HOOK, &x);
02653 
02654    if (res < 0) {
02655       if (errno == EINPROGRESS)
02656          return 0;
02657       ast_log(LOG_WARNING, "DAHDI hook failed returned %d (trying %d): %s\n", res, hs, strerror(errno));
02658       /* will expectedly fail if phone is off hook during operation, such as during a restart */
02659    }
02660 
02661    return res;
02662 }
02663 
02664 static inline int dahdi_confmute(struct dahdi_pvt *p, int muted)
02665 {
02666    int x, y, res;
02667    x = muted;
02668    if (p->sig == SIG_PRI) {
02669       y = 1;
02670       res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &y);
02671       if (res)
02672          ast_log(LOG_WARNING, "Unable to set audio mode on %d: %s\n", p->channel, strerror(errno));
02673    }
02674    res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_CONFMUTE, &x);
02675    if (res < 0)
02676       ast_log(LOG_WARNING, "dahdi confmute(%d) failed on channel %d: %s\n", muted, p->channel, strerror(errno));
02677    return res;
02678 }
02679 
02680 static int save_conference(struct dahdi_pvt *p)
02681 {
02682    struct dahdi_confinfo c;
02683    int res;
02684    if (p->saveconf.confmode) {
02685       ast_log(LOG_WARNING, "Can't save conference -- already in use\n");
02686       return -1;
02687    }
02688    p->saveconf.chan = 0;
02689    res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GETCONF, &p->saveconf);
02690    if (res) {
02691       ast_log(LOG_WARNING, "Unable to get conference info: %s\n", strerror(errno));
02692       p->saveconf.confmode = 0;
02693       return -1;
02694    }
02695    memset(&c, 0, sizeof(c));
02696    c.confmode = DAHDI_CONF_NORMAL;
02697    res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCONF, &c);
02698    if (res) {
02699       ast_log(LOG_WARNING, "Unable to set conference info: %s\n", strerror(errno));
02700       return -1;
02701    }
02702    if (option_debug)
02703       ast_log(LOG_DEBUG, "Disabled conferencing\n");
02704    return 0;
02705 }
02706 
02707 static int restore_conference(struct dahdi_pvt *p)
02708 {
02709    int res;
02710    if (p->saveconf.confmode) {
02711       res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCONF, &p->saveconf);
02712       p->saveconf.confmode = 0;
02713       if (res) {
02714          ast_log(LOG_WARNING, "Unable to restore conference info: %s\n", strerror(errno));
02715          return -1;
02716       }
02717       if (option_debug)
02718          ast_log(LOG_DEBUG, "Restored conferencing\n");
02719    }
02720    return 0;
02721 }
02722 
02723 static int send_callerid(struct dahdi_pvt *p);
02724 
02725 static int send_cwcidspill(struct dahdi_pvt *p)
02726 {
02727    p->callwaitcas = 0;
02728    p->cidcwexpire = 0;
02729    p->cid_suppress_expire = 0;
02730    if (!(p->cidspill = ast_malloc(MAX_CALLERID_SIZE)))
02731       return -1;
02732    p->cidlen = ast_callerid_callwaiting_generate(p->cidspill, p->callwait_name, p->callwait_num, AST_LAW(p));
02733    /* Make sure we account for the end */
02734    p->cidlen += READ_SIZE * 4;
02735    p->cidpos = 0;
02736    send_callerid(p);
02737    if (option_verbose > 2)
02738       ast_verbose(VERBOSE_PREFIX_3 "CPE supports Call Waiting Caller*ID.  Sending '%s/%s'\n", p->callwait_name, p->callwait_num);
02739    return 0;
02740 }
02741 
02742 static int has_voicemail(struct dahdi_pvt *p)
02743 {
02744 
02745    return ast_app_has_voicemail(p->mailbox, NULL);
02746 }
02747 
02748 static int send_callerid(struct dahdi_pvt *p)
02749 {
02750    /* Assumes spill in p->cidspill, p->cidlen in length and we're p->cidpos into it */
02751    int res;
02752    /* Take out of linear mode if necessary */
02753    if (p->subs[SUB_REAL].linear) {
02754       p->subs[SUB_REAL].linear = 0;
02755       dahdi_setlinear(p->subs[SUB_REAL].dfd, 0);
02756    }
02757    while (p->cidpos < p->cidlen) {
02758       res = write(p->subs[SUB_REAL].dfd, p->cidspill + p->cidpos, p->cidlen - p->cidpos);
02759       if (res < 0) {
02760          if (errno == EAGAIN)
02761             return 0;
02762          else {
02763             ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno));
02764             return -1;
02765          }
02766       }
02767       if (!res)
02768          return 0;
02769       p->cidpos += res;
02770    }
02771    p->cid_suppress_expire = CALLWAITING_SUPPRESS_SAMPLES;
02772    free(p->cidspill);
02773    p->cidspill = NULL;
02774    if (p->callwaitcas) {
02775       /* Wait for CID/CW to expire */
02776       p->cidcwexpire = CIDCW_EXPIRE_SAMPLES;
02777       p->cid_suppress_expire = p->cidcwexpire;
02778    } else
02779       restore_conference(p);
02780    return 0;
02781 }
02782 
02783 static int dahdi_callwait(struct ast_channel *ast)
02784 {
02785    struct dahdi_pvt *p = ast->tech_pvt;
02786    p->callwaitingrepeat = CALLWAITING_REPEAT_SAMPLES;
02787    if (p->cidspill) {
02788       ast_log(LOG_WARNING, "Spill already exists?!?\n");
02789       free(p->cidspill);
02790    }
02791 
02792    /*
02793     * SAS: Subscriber Alert Signal, 440Hz for 300ms
02794     * CAS: CPE Alert Signal, 2130Hz * 2750Hz sine waves
02795     */
02796    if (!(p->cidspill = ast_malloc(2400 /* SAS */ + 680 /* CAS */ + READ_SIZE * 4)))
02797       return -1;
02798    save_conference(p);
02799    /* Silence */
02800    memset(p->cidspill, 0x7f, 2400 + 600 + READ_SIZE * 4);
02801    if (!p->callwaitrings && p->callwaitingcallerid) {
02802       ast_gen_cas(p->cidspill, 1, 2400 + 680, AST_LAW(p));
02803       p->callwaitcas = 1;
02804       p->cidlen = 2400 + 680 + READ_SIZE * 4;
02805    } else {
02806       ast_gen_cas(p->cidspill, 1, 2400, AST_LAW(p));
02807       p->callwaitcas = 0;
02808       p->cidlen = 2400 + READ_SIZE * 4;
02809    }
02810    p->cidpos = 0;
02811    send_callerid(p);
02812    
02813    return 0;
02814 }
02815 
02816 static int dahdi_call(struct ast_channel *ast, char *rdest, int timeout)
02817 {
02818    struct dahdi_pvt *p = ast->tech_pvt;
02819    int x, res, index,mysig;
02820    char *c, *n, *l;
02821 #ifdef HAVE_PRI
02822    char *s = NULL;
02823 #endif
02824    char dest[256]; /* must be same length as p->dialdest */
02825    ast_mutex_lock(&p->lock);
02826    ast_copy_string(dest, rdest, sizeof(dest));
02827    ast_copy_string(p->dialdest, rdest, sizeof(p->dialdest));
02828    if ((ast->_state == AST_STATE_BUSY)) {
02829       p->subs[SUB_REAL].needbusy = 1;
02830       ast_mutex_unlock(&p->lock);
02831       return 0;
02832    }
02833    if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
02834       ast_log(LOG_WARNING, "dahdi_call called on %s, neither down nor reserved\n", ast->name);
02835       ast_mutex_unlock(&p->lock);
02836       return -1;
02837    }
02838    p->dialednone = 0;
02839    if ((p->radio || (p->oprmode < 0)))  /* if a radio channel, up immediately */
02840    {
02841       /* Special pseudo -- automatically up */
02842       ast_setstate(ast, AST_STATE_UP); 
02843       ast_mutex_unlock(&p->lock);
02844       return 0;
02845    }
02846    x = DAHDI_FLUSH_READ | DAHDI_FLUSH_WRITE;
02847    res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_FLUSH, &x);
02848    if (res)
02849       ast_log(LOG_WARNING, "Unable to flush input on channel %d: %s\n", p->channel, strerror(errno));
02850    p->outgoing = 1;
02851 
02852    if (IS_DIGITAL(ast->transfercapability)) {
02853       set_actual_gain(p->subs[SUB_REAL].dfd, 0, 0, 0, p->law);
02854    } else {
02855       set_actual_gain(p->subs[SUB_REAL].dfd, 0, p->rxgain, p->txgain, p->law);
02856    }
02857 
02858    mysig = p->sig;
02859    if (p->outsigmod > -1)
02860       mysig = p->outsigmod;
02861 
02862    switch (mysig) {
02863    case SIG_FXOLS:
02864    case SIG_FXOGS:
02865    case SIG_FXOKS:
02866       if (p->owner == ast) {
02867          /* Normal ring, on hook */
02868          
02869          /* Don't send audio while on hook, until the call is answered */
02870          p->dialing = 1;
02871          if (p->use_callerid) {
02872             /* Generate the Caller-ID spill if desired */
02873             if (p->cidspill) {
02874                ast_log(LOG_WARNING, "cidspill already exists??\n");
02875                free(p->cidspill);
02876             }
02877             p->callwaitcas = 0;
02878             if ((p->cidspill = ast_malloc(MAX_CALLERID_SIZE))) {
02879                p->cidlen = ast_callerid_generate(p->cidspill, ast->cid.cid_name, ast->cid.cid_num, AST_LAW(p));
02880                p->cidpos = 0;
02881                send_callerid(p);
02882             }
02883          }
02884          /* Choose proper cadence */
02885          if ((p->distinctivering > 0) && (p->distinctivering <= num_cadence)) {
02886             if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCADENCE, &cadences[p->distinctivering - 1]))
02887                ast_log(LOG_WARNING, "Unable to set distinctive ring cadence %d on '%s': %s\n", p->distinctivering, ast->name, strerror(errno));
02888             p->cidrings = cidrings[p->distinctivering - 1];
02889          } else {
02890             if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCADENCE, NULL))
02891                ast_log(LOG_WARNING, "Unable to reset default ring on '%s': %s\n", ast->name, strerror(errno));
02892             p->cidrings = p->sendcalleridafter;
02893          }
02894 
02895          /* nick@dccinc.com 4/3/03 mods to allow for deferred dialing */
02896          c = strchr(dest, '/');
02897          if (c)
02898             c++;
02899          if (c && (strlen(c) < p->stripmsd)) {
02900             ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
02901             c = NULL;
02902          }
02903          if (c) {
02904             p->dop.op = DAHDI_DIAL_OP_REPLACE;
02905             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "Tw%s", c);
02906             ast_log(LOG_DEBUG, "FXO: setup deferred dialstring: %s\n", c);
02907          } else {
02908             p->dop.dialstr[0] = '\0';
02909          }
02910          x = DAHDI_RING;
02911          if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x) && (errno != EINPROGRESS)) {
02912             ast_log(LOG_WARNING, "Unable to ring phone: %s\n", strerror(errno));
02913             ast_mutex_unlock(&p->lock);
02914             return -1;
02915          }
02916          p->dialing = 1;
02917       } else {
02918          /* Call waiting call */
02919          p->callwaitrings = 0;
02920          if (ast->cid.cid_num)
02921             ast_copy_string(p->callwait_num, ast->cid.cid_num, sizeof(p->callwait_num));
02922          else
02923             p->callwait_num[0] = '\0';
02924          if (ast->cid.cid_name)
02925             ast_copy_string(p->callwait_name, ast->cid.cid_name, sizeof(p->callwait_name));
02926          else
02927             p->callwait_name[0] = '\0';
02928          /* Call waiting tone instead */
02929          if (dahdi_callwait(ast)) {
02930             ast_mutex_unlock(&p->lock);
02931             return -1;
02932          }
02933          /* Make ring-back */
02934          if (tone_zone_play_tone(p->subs[SUB_CALLWAIT].dfd, DAHDI_TONE_RINGTONE))
02935             ast_log(LOG_WARNING, "Unable to generate call-wait ring-back on channel %s\n", ast->name);
02936             
02937       }
02938       n = ast->cid.cid_name;
02939       l = ast->cid.cid_num;
02940       if (l)
02941          ast_copy_string(p->lastcid_num, l, sizeof(p->lastcid_num));
02942       else
02943          p->lastcid_num[0] = '\0';
02944       if (n)
02945          ast_copy_string(p->lastcid_name, n, sizeof(p->lastcid_name));
02946       else
02947          p->lastcid_name[0] = '\0';
02948       ast_setstate(ast, AST_STATE_RINGING);
02949       index = dahdi_get_index(ast, p, 0);
02950       if (index > -1) {
02951          p->subs[index].needringing = 1;
02952       }
02953       break;
02954    case SIG_FXSLS:
02955    case SIG_FXSGS:
02956    case SIG_FXSKS:
02957    case SIG_EMWINK:
02958    case SIG_EM:
02959    case SIG_EM_E1:
02960    case SIG_FEATD:
02961    case SIG_FEATDMF:
02962    case SIG_E911:
02963    case SIG_FGC_CAMA:
02964    case SIG_FGC_CAMAMF:
02965    case SIG_FEATB:
02966    case SIG_SFWINK:
02967    case SIG_SF:
02968    case SIG_SF_FEATD:
02969    case SIG_SF_FEATDMF:
02970    case SIG_FEATDMF_TA:
02971    case SIG_SF_FEATB:
02972       c = strchr(dest, '/');
02973       if (c)
02974          c++;
02975       else
02976          c = "";
02977       if (strlen(c) < p->stripmsd) {
02978          ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
02979          ast_mutex_unlock(&p->lock);
02980          return -1;
02981       }
02982 #ifdef HAVE_PRI
02983       /* Start the trunk, if not GR-303 */
02984       if (!p->pri) {
02985 #endif
02986          x = DAHDI_START;
02987          res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x);
02988          if (res < 0) {
02989             if (errno != EINPROGRESS) {
02990                ast_log(LOG_WARNING, "Unable to start channel: %s\n", strerror(errno));
02991                ast_mutex_unlock(&p->lock);
02992                return -1;
02993             }
02994          }
02995 #ifdef HAVE_PRI
02996       }
02997 #endif
02998       ast_log(LOG_DEBUG, "Dialing '%s'\n", c);
02999       p->dop.op = DAHDI_DIAL_OP_REPLACE;
03000 
03001       c += p->stripmsd;
03002 
03003       switch (mysig) {
03004       case SIG_FEATD:
03005          l = ast->cid.cid_num;
03006          if (l) 
03007             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T*%s*%s*", l, c);
03008          else
03009             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T**%s*", c);
03010          break;
03011       case SIG_FEATDMF:
03012          l = ast->cid.cid_num;
03013          if (l) 
03014             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*00%s#*%s#", l, c);
03015          else
03016             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*02#*%s#", c);
03017          break;
03018       case SIG_FEATDMF_TA:
03019       {
03020          const char *cic, *ozz;
03021 
03022          /* If you have to go through a Tandem Access point you need to use this */
03023          ozz = pbx_builtin_getvar_helper(p->owner, "FEATDMF_OZZ");
03024          if (!ozz)
03025             ozz = defaultozz;
03026          cic = pbx_builtin_getvar_helper(p->owner, "FEATDMF_CIC");
03027          if (!cic)
03028             cic = defaultcic;
03029          if (!ozz || !cic) {
03030             ast_log(LOG_WARNING, "Unable to dial channel of type feature group D MF tandem access without CIC or OZZ set\n");
03031             ast_mutex_unlock(&p->lock);
03032             return -1;
03033          }
03034          snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%s%s#", ozz, cic);
03035          snprintf(p->finaldial, sizeof(p->finaldial), "M*%s#", c);
03036          p->whichwink = 0;
03037       }
03038          break;
03039       case SIG_E911:
03040          ast_copy_string(p->dop.dialstr, "M*911#", sizeof(p->dop.dialstr));
03041          break;
03042       case SIG_FGC_CAMA:
03043          snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "P%s", c);
03044          break;
03045       case SIG_FGC_CAMAMF:
03046       case SIG_FEATB:
03047          snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%s#", c);
03048          break;
03049       default:
03050          if (p->pulse)
03051             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "P%sw", c);
03052          else
03053             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T%sw", c);
03054          break;
03055       }
03056 
03057       if (p->echotraining && (strlen(p->dop.dialstr) > 4)) {
03058          memset(p->echorest, 'w', sizeof(p->echorest) - 1);
03059          strcpy(p->echorest + (p->echotraining / 400) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2);
03060          p->echorest[sizeof(p->echorest) - 1] = '\0';
03061          p->echobreak = 1;
03062          p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0';
03063       } else
03064          p->echobreak = 0;
03065       if (!res) {
03066          if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_DIAL, &p->dop)) {
03067             int saveerr = errno;
03068 
03069             x = DAHDI_ONHOOK;
03070             ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x);
03071             ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(saveerr));
03072             ast_mutex_unlock(&p->lock);
03073             return -1;
03074          }
03075       } else
03076          ast_log(LOG_DEBUG, "Deferring dialing... (res %d)\n", res);
03077       p->dialing = 1;
03078       if (ast_strlen_zero(c))
03079          p->dialednone = 1;
03080       ast_setstate(ast, AST_STATE_DIALING);
03081       break;
03082    case 0:
03083       /* Special pseudo -- automatically up*/
03084       ast_setstate(ast, AST_STATE_UP);
03085       break;      
03086    case SIG_PRI:
03087    case SIG_MFCR2:
03088       /* We'll get it in a moment -- but use dialdest to store pre-setup_ack digits */
03089       p->dialdest[0] = '\0';
03090       p->dialing = 1;
03091       break;
03092    default:
03093       ast_log(LOG_DEBUG, "not yet implemented\n");
03094       ast_mutex_unlock(&p->lock);
03095       return -1;
03096    }
03097 
03098 #ifdef HAVE_OPENR2
03099    if (p->mfcr2) {
03100       int strip = p->stripmsd;
03101       int callres = 0;
03102       c = strchr(dest, '/');
03103       if (c) {
03104          c++;
03105       } else {
03106          c = dest;
03107       }
03108       if (!p->hidecallerid) {
03109          l = ast->cid.cid_num;
03110       } else {
03111          l = NULL;
03112       }
03113       if (strlen(c) < strip) {
03114          ast_log(LOG_WARNING, "Destiny number '%s' is shorter than stripmsd(%d)? hum, you should fix that. Assuming stripmsd = 0\n", c, strip);
03115          strip = 0;
03116       }
03117       p->dialing = 1;
03118       callres = openr2_chan_make_call(p->r2chan, l, (c + strip), dahdi_r2_get_channel_category(ast));
03119       if (-1 == callres) {
03120          ast_mutex_unlock(&p->lock);
03121          ast_log(LOG_ERROR, "unable to make new MFC/R2 call!\n");
03122          return -1;
03123       }
03124       ast_setstate(ast, AST_STATE_DIALING);
03125    }
03126 #endif /* HAVE_OPENR2 */
03127 
03128 #ifdef HAVE_PRI
03129    if (p->pri) {
03130       struct pri_sr *sr;
03131 #ifdef SUPPORT_USERUSER
03132       const char *useruser;
03133 #endif
03134       int pridialplan;
03135       int dp_strip;
03136       int prilocaldialplan;
03137       int ldp_strip;
03138       int exclusive;
03139       const char *rr_str;
03140       int redirect_reason;
03141 
03142       c = strchr(dest, '/');
03143       if (c) {
03144          c++;
03145       } else {
03146          c = "";
03147       }
03148 
03149       l = NULL;
03150       n = NULL;
03151       if (!p->hidecallerid) {
03152          l = ast->cid.cid_num;
03153          if (!p->hidecalleridname) {
03154             n = ast->cid.cid_name;
03155          }
03156       }
03157 
03158 
03159       if (strlen(c) < p->stripmsd) {
03160          ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
03161          ast_mutex_unlock(&p->lock);
03162          return -1;
03163       }
03164       if (mysig != SIG_FXSKS) {
03165          p->dop.op = DAHDI_DIAL_OP_REPLACE;
03166          s = strchr(c + p->stripmsd, 'w');
03167          if (s) {
03168             if (strlen(s) > 1)
03169                snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T%s", s);
03170             else
03171                p->dop.dialstr[0] = '\0';
03172             *s = '\0';
03173          } else {
03174             p->dop.dialstr[0] = '\0';
03175          }
03176       }
03177       if (pri_grab(p, p->pri)) {
03178          ast_log(LOG_WARNING, "Failed to grab PRI!\n");
03179          ast_mutex_unlock(&p->lock);
03180          return -1;
03181       }
03182       if (!(p->call = pri_new_call(p->pri->pri))) {
03183          ast_log(LOG_WARNING, "Unable to create call on channel %d\n", p->channel);
03184          pri_rel(p->pri);
03185          ast_mutex_unlock(&p->lock);
03186          return -1;
03187       }
03188       if (!(sr = pri_sr_new())) {
03189          ast_log(LOG_WARNING, "Failed to allocate setup request channel %d\n", p->channel);
03190          pri_destroycall(p->pri->pri, p->call);
03191          p->call = NULL;
03192          pri_rel(p->pri);
03193          ast_mutex_unlock(&p->lock);
03194          return -1;
03195       }
03196       if (p->bearer || (mysig == SIG_FXSKS)) {
03197          if (p->bearer) {
03198             ast_log(LOG_DEBUG, "Oooh, I have a bearer on %d (%d:%d)\n", PVT_TO_CHANNEL(p->bearer), p->bearer->logicalspan, p->bearer->channel);
03199             p->bearer->call = p->call;
03200          } else
03201             ast_log(LOG_DEBUG, "I'm being setup with no bearer right now...\n");
03202          pri_set_crv(p->pri->pri, p->call, p->channel, 0);
03203       }
03204       p->digital = IS_DIGITAL(ast->transfercapability);
03205 
03206       /* Should the picked channel be used exclusively? */
03207       if (p->priexclusive || p->pri->nodetype == PRI_NETWORK) {
03208          exclusive = 1;
03209       } else {
03210          exclusive = 0;
03211       }
03212       
03213       pri_sr_set_channel(sr, p->bearer ? PVT_TO_CHANNEL(p->bearer) : PVT_TO_CHANNEL(p), exclusive, 1);
03214       pri_sr_set_bearer(sr, p->digital ? PRI_TRANS_CAP_DIGITAL : ast->transfercapability, 
03215                (p->digital ? -1 : 
03216                   ((p->law == DAHDI_LAW_ALAW) ? PRI_LAYER_1_ALAW : PRI_LAYER_1_ULAW)));
03217       if (p->pri->facilityenable)
03218          pri_facility_enable(p->pri->pri);
03219 
03220       if (option_verbose > 2)
03221          ast_verbose(VERBOSE_PREFIX_3 "Requested transfer capability: 0x%.2x - %s\n", ast->transfercapability, ast_transfercapability2str(ast->transfercapability));
03222       dp_strip = 0;
03223       pridialplan = p->pri->dialplan - 1;
03224       if (pridialplan == -2) { /* compute dynamically */
03225          if (strncmp(c + p->stripmsd, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) {
03226             dp_strip = strlen(p->pri->internationalprefix);
03227             pridialplan = PRI_INTERNATIONAL_ISDN;
03228          } else if (strncmp(c + p->stripmsd, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) {
03229             dp_strip = strlen(p->pri->nationalprefix);
03230             pridialplan = PRI_NATIONAL_ISDN;
03231          } else {
03232             pridialplan = PRI_LOCAL_ISDN;
03233          }
03234       }
03235       pri_sr_set_called(sr, c + p->stripmsd + dp_strip, pridialplan, s ? 1 : 0);
03236 
03237       ldp_strip = 0;
03238       prilocaldialplan = p->pri->localdialplan - 1;
03239       if ((l != NULL) && (prilocaldialplan == -2)) { /* compute dynamically */
03240          if (strncmp(l, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) {
03241             ldp_strip = strlen(p->pri->internationalprefix);
03242             prilocaldialplan = PRI_INTERNATIONAL_ISDN;
03243          } else if (strncmp(l, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) {
03244             ldp_strip = strlen(p->pri->nationalprefix);
03245             prilocaldialplan = PRI_NATIONAL_ISDN;
03246          } else {
03247             prilocaldialplan = PRI_LOCAL_ISDN;
03248          }
03249       }
03250       pri_sr_set_caller(sr, l ? (l + ldp_strip) : NULL, n, prilocaldialplan,
03251          p->use_callingpres ? ast->cid.cid_pres : (l ? PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN : PRES_NUMBER_NOT_AVAILABLE));
03252       if ((rr_str = pbx_builtin_getvar_helper(ast, "PRIREDIRECTREASON"))) {
03253          if (!strcasecmp(rr_str, "UNKNOWN"))
03254             redirect_reason = 0;
03255          else if (!strcasecmp(rr_str, "BUSY"))
03256             redirect_reason = 1;
03257          else if (!strcasecmp(rr_str, "NO_REPLY"))
03258             redirect_reason = 2;
03259          else if (!strcasecmp(rr_str, "UNCONDITIONAL"))
03260             redirect_reason = 15;
03261          else
03262             redirect_reason = PRI_REDIR_UNCONDITIONAL;
03263       } else
03264          redirect_reason = PRI_REDIR_UNCONDITIONAL;
03265       pri_sr_set_redirecting(sr, ast->cid.cid_rdnis, p->pri->localdialplan - 1, PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, redirect_reason);
03266 
03267 #ifdef SUPPORT_USERUSER
03268       /* User-user info */
03269       useruser = pbx_builtin_getvar_helper(p->owner, "USERUSERINFO");
03270 
03271       if (useruser)
03272          pri_sr_set_useruser(sr, useruser);
03273 #endif
03274 
03275       if (pri_setup(p->pri->pri, p->call, sr)) {
03276          ast_log(LOG_WARNING, "Unable to setup call to %s (using %s)\n", 
03277             c + p->stripmsd + dp_strip, dialplan2str(p->pri->dialplan));
03278          pri_destroycall(p->pri->pri, p->call);
03279          p->call = NULL;
03280          pri_rel(p->pri);
03281          ast_mutex_unlock(&p->lock);
03282          pri_sr_free(sr);
03283          return -1;
03284       }
03285       p->call_level = DAHDI_CALL_LEVEL_SETUP;
03286       pri_sr_free(sr);
03287       ast_setstate(ast, AST_STATE_DIALING);
03288       pri_rel(p->pri);
03289    }
03290 #endif      
03291    ast_mutex_unlock(&p->lock);
03292    return 0;
03293 }
03294 
03295 static void destroy_dahdi_pvt(struct dahdi_pvt **pvt)
03296 {
03297    struct dahdi_pvt *p = *pvt;
03298    /* Remove channel from the list */
03299    if (p->prev)
03300       p->prev->next = p->next;
03301    if (p->next)
03302       p->next->prev = p->prev;
03303 
03304    free(p->cidspill);
03305    if (p->use_smdi)
03306       ast_smdi_interface_unref(p->smdi_iface);
03307    ast_mutex_destroy(&p->lock);
03308    dahdi_close_sub(p, SUB_REAL);
03309    if (p->owner)
03310       p->owner->tech_pvt = NULL;
03311    free(p);
03312    *pvt = NULL;
03313 }
03314 
03315 static int destroy_channel(struct dahdi_pvt *prev, struct dahdi_pvt *cur, int now)
03316 {
03317    int owned = 0;
03318    int i = 0;
03319 
03320    if (!now) {
03321       if (cur->owner) {
03322          owned = 1;
03323       }
03324 
03325       for (i = 0; i < 3; i++) {
03326          if (cur->subs[i].owner) {
03327             owned = 1;
03328          }
03329       }
03330       if (!owned) {
03331          if (prev) {
03332             prev->next = cur->next;
03333             if (prev->next)
03334                prev->next->prev = prev;
03335             else
03336                ifend = prev;
03337          } else {
03338             iflist = cur->next;
03339             if (iflist)
03340                iflist->prev = NULL;
03341             else
03342                ifend = NULL;
03343          }
03344          destroy_dahdi_pvt(&cur);
03345       }
03346    } else {
03347       if (prev) {
03348          prev->next = cur->next;
03349          if (prev->next)
03350             prev->next->prev = prev;
03351          else
03352             ifend = prev;
03353       } else {
03354          iflist = cur->next;
03355          if (iflist)
03356             iflist->prev = NULL;
03357          else
03358             ifend = NULL;
03359       }
03360       destroy_dahdi_pvt(&cur);
03361    }
03362    return 0;
03363 }
03364 
03365 static void destroy_all_channels(void)
03366 {
03367    int x;
03368    struct dahdi_pvt *p, *pl;
03369 
03370    while (num_restart_pending) {
03371       usleep(1);
03372    }
03373 
03374    ast_mutex_lock(&iflock);
03375    /* Destroy all the interfaces and free their memory */
03376    p = iflist;
03377    while (p) {
03378       pl = p;
03379       p = p->next;
03380       x = pl->channel;
03381       /* Free associated memory */
03382       destroy_dahdi_pvt(&pl);
03383       if (option_verbose > 2) 
03384          ast_verbose(VERBOSE_PREFIX_2 "Unregistered channel %d\n", x);
03385    }
03386    iflist = NULL;
03387    ifcount = 0;
03388    ast_mutex_unlock(&iflock);
03389 }
03390 
03391 #ifdef HAVE_PRI
03392 static char *dahdi_send_keypad_facility_app = "DAHDISendKeypadFacility";
03393 static char *zap_send_keypad_facility_app = "ZapSendKeypadFacility";
03394 
03395 static char *dahdi_send_keypad_facility_synopsis = "Send digits out of band over a PRI";
03396 static char *zap_send_keypad_facility_synopsis = "Send digits out of band over a PRI";
03397 
03398 static char *dahdi_send_keypad_facility_descrip = 
03399 "  DAHDISendKeypadFacility(): This application will send the given string of digits in a Keypad Facility\n"
03400 "  IE over the current channel.\n";
03401 static char *zap_send_keypad_facility_descrip = 
03402 "  ZapSendKeypadFacility(): This application will send the given string of digits in a Keypad Facility\n"
03403 "  IE over the current channel.\n";
03404 
03405 static int send_keypad_facility_exec(struct ast_channel *chan, void *data)
03406 {
03407    /* Data will be our digit string */
03408    struct dahdi_pvt *p;
03409    char *digits = (char *) data;
03410 
03411    if (ast_strlen_zero(digits)) {
03412       ast_log(LOG_DEBUG, "No digit string sent to application!\n");
03413       return -1;
03414    }
03415 
03416    p = (struct dahdi_pvt *)chan->tech_pvt;
03417 
03418    if (!p) {
03419       ast_log(LOG_DEBUG, "Unable to find technology private\n");
03420       return -1;
03421    }
03422 
03423    ast_mutex_lock(&p->lock);
03424 
03425    if (!p->pri || !p->call) {
03426       ast_log(LOG_DEBUG, "Unable to find pri or call on channel!\n");
03427       ast_mutex_unlock(&p->lock);
03428       return -1;
03429    }
03430 
03431    if (!pri_grab(p, p->pri)) {
03432       pri_keypad_facility(p->pri->pri, p->call, digits);
03433       pri_rel(p->pri);
03434    } else {
03435       ast_log(LOG_DEBUG, "Unable to grab pri to send keypad facility!\n");
03436       ast_mutex_unlock(&p->lock);
03437       return -1;
03438    }
03439 
03440    ast_mutex_unlock(&p->lock);
03441 
03442    return 0;
03443 }
03444 
03445 static int dahdi_send_keypad_facility_exec(struct ast_channel *chan, void *data)
03446 {
03447    return send_keypad_facility_exec(chan, data);
03448 }
03449 
03450 static int zap_send_keypad_facility_exec(struct ast_channel *chan, void *data)
03451 {
03452    ast_log(LOG_WARNING, "Use of the command %s is deprecated, please use %s instead.\n", zap_send_keypad_facility_app, dahdi_send_keypad_facility_app);  
03453    return send_keypad_facility_exec(chan, data);
03454 }
03455 
03456 static int pri_is_up(struct dahdi_pri *pri)
03457 {
03458    int x;
03459    for (x = 0; x < NUM_DCHANS; x++) {
03460       if (pri->dchanavail[x] == DCHAN_AVAILABLE)
03461          return 1;
03462    }
03463    return 0;
03464 }
03465 
03466 static int pri_assign_bearer(struct dahdi_pvt *crv, struct dahdi_pri *pri, struct dahdi_pvt *bearer)
03467 {
03468    bearer->owner = &inuse;
03469    bearer->realcall = crv;
03470    crv->subs[SUB_REAL].dfd = bearer->subs[SUB_REAL].dfd;
03471    if (crv->subs[SUB_REAL].owner)
03472       crv->subs[SUB_REAL].owner->fds[0] = crv->subs[SUB_REAL].dfd;
03473    crv->bearer = bearer;
03474    crv->call = bearer->call;
03475    crv->pri = pri;
03476    return 0;
03477 }
03478 
03479 static char *pri_order(int level)
03480 {
03481    switch (level) {
03482    case 0:
03483       return "Primary";
03484    case 1:
03485       return "Secondary";
03486    case 2:
03487       return "Tertiary";
03488    case 3:
03489       return "Quaternary";
03490    default:
03491       return "<Unknown>";
03492    }     
03493 }
03494 
03495 /* Returns fd of the active dchan */
03496 static int pri_active_dchan_fd(struct dahdi_pri *pri)
03497 {
03498    int x = -1;
03499 
03500    for (x = 0; x < NUM_DCHANS; x++) {
03501       if ((pri->dchans[x] == pri->pri))
03502          break;
03503    }
03504 
03505    return pri->fds[x];
03506 }
03507 
03508 static int pri_find_dchan(struct dahdi_pri *pri)
03509 {
03510    int oldslot = -1;
03511    struct pri *old;
03512    int newslot = -1;
03513    int x;
03514    old = pri->pri;
03515    for (x = 0; x < NUM_DCHANS; x++) {
03516       if ((pri->dchanavail[x] == DCHAN_AVAILABLE) && (newslot < 0))
03517          newslot = x;
03518       if (pri->dchans[x] == old) {
03519          oldslot = x;
03520       }
03521    }
03522    if (newslot < 0) {
03523       newslot = 0;
03524       if (!pri->no_d_channels) {
03525          pri->no_d_channels = 1;
03526          ast_log(LOG_WARNING,
03527             "No D-channels available!  Using Primary channel %d as D-channel anyway!\n",
03528             pri->dchannels[newslot]);
03529       }
03530    } else {
03531       pri->no_d_channels = 0;
03532    }
03533    if (old && (oldslot != newslot))
03534       ast_log(LOG_NOTICE, "Switching from from d-channel %d to channel %d!\n",
03535          pri->dchannels[oldslot], pri->dchannels[newslot]);
03536    pri->pri = pri->dchans[newslot];
03537    return 0;
03538 }
03539 #endif
03540  
03541 #ifdef HAVE_OPENR2
03542 static char *dahdi_accept_r2_call_app = "DAHDIAcceptR2Call";
03543 static char *zap_accept_r2_call_app = "ZapAcceptR2Call";
03544 
03545 static char *dahdi_accept_r2_call_synopsis = "Accept an R2 call if its not already accepted (you still need to answer it)";
03546 static char *zap_accept_r2_call_synopsis = "Accept an R2 call if its not already accepted (you still need to answer it)";
03547 
03548 static char *dahdi_accept_r2_call_descrip = 
03549 "  DAHDIAcceptR2Call(): This application will accept the current MFC/R2 call\n"
03550 "  You can specify yes or no as argument to accept with or without charge.\n";
03551 
03552 static char *zap_accept_r2_call_descrip = 
03553 "  ZapAcceptR2Call(): This application will accept the current MFC/R2 call\n"
03554 "  You can specify yes or no as argument to accept with or without charge.\n";
03555 
03556 static int dahdi_accept_r2_call_exec(struct ast_channel *chan, void *data)
03557 {
03558    /* data is whether to accept with charge or no charge */
03559    openr2_call_mode_t accept_mode;
03560    int res, timeout, maxloops;
03561    struct ast_frame *f;
03562    struct dahdi_pvt *p;
03563    char *parse;
03564    AST_DECLARE_APP_ARGS(args,
03565          AST_APP_ARG(charge);
03566    );
03567 
03568    if (ast_strlen_zero(data)) {
03569       ast_log(LOG_DEBUG, "No data sent to application!\n");
03570       return -1;
03571    }
03572 
03573    if (chan->tech != &dahdi_tech) {
03574       ast_log(LOG_DEBUG, "Only DAHDI technology accepted!\n");
03575       return -1;
03576    }
03577 
03578    p = (struct dahdi_pvt *)chan->tech_pvt;
03579    if (!p) {
03580       ast_log(LOG_DEBUG, "Unable to find technology private!\n");
03581       return -1;
03582    }
03583 
03584    parse = ast_strdupa(data);
03585    AST_STANDARD_APP_ARGS(args, parse);
03586 
03587    if (ast_strlen_zero(args.charge)) {
03588       ast_log(LOG_WARNING, "DAHDIAcceptR2Call requires 'yes' or 'no' for the charge parameter\n");
03589       return -1;
03590    }
03591 
03592    ast_mutex_lock(&p->lock);
03593    if (!p->mfcr2 || !p->mfcr2call) {
03594       ast_mutex_unlock(&p->lock);
03595       ast_log(LOG_DEBUG, "Channel %s does not seems to be an R2 active channel!\n", chan->name);
03596       return -1;
03597    }
03598 
03599    if (p->mfcr2_call_accepted) {
03600       ast_mutex_unlock(&p->lock);
03601       ast_log(LOG_DEBUG, "MFC/R2 call already accepted on channel %s!\n", chan->name);
03602       return 0;
03603    }
03604    accept_mode = ast_true(args.charge) ? OR2_CALL_WITH_CHARGE : OR2_CALL_NO_CHARGE;
03605    if (openr2_chan_accept_call(p->r2chan, accept_mode)) {
03606       ast_mutex_unlock(&p->lock);
03607       ast_log(LOG_WARNING, "Failed to accept MFC/R2 call!\n");
03608       return -1;
03609    }
03610    ast_mutex_unlock(&p->lock);
03611 
03612    res = 0;
03613    timeout = 100;
03614    maxloops = 50; /* wait up to 5 seconds */
03615    /* we need to read() until the call is accepted */
03616    while (maxloops > 0) {
03617       maxloops--;
03618       if (ast_check_hangup(chan)) {
03619          break;
03620       }
03621       res = ast_waitfor(chan, timeout);
03622       if (res < 0) {
03623          ast_log(LOG_DEBUG, "ast_waitfor failed on channel %s, going out ...\n", chan->name);
03624          res = -1;
03625          break;
03626       }
03627       if (res == 0) {
03628          continue;
03629       }
03630       f = ast_read(chan);
03631       if (!f) {
03632          ast_log(LOG_DEBUG, "No frame read on channel %s, going out ...\n", chan->name);
03633          res = -1;
03634          break;
03635       }
03636       if (f->frametype == AST_FRAME_CONTROL && f->subclass == AST_CONTROL_HANGUP) {
03637          ast_log(LOG_DEBUG, "Got HANGUP frame on channel %s, going out ...\n", chan->name);
03638          ast_frfree(f);
03639          res = -1;
03640          break;
03641       }
03642       ast_frfree(f);
03643       ast_mutex_lock(&p->lock);
03644       if (p->mfcr2_call_accepted) {
03645          ast_mutex_unlock(&p->lock);
03646          ast_log(LOG_DEBUG, "Accepted MFC/R2 call!\n");
03647          break;
03648       }
03649       ast_mutex_unlock(&p->lock);
03650    }
03651    if (res == -1) {
03652       ast_log(LOG_WARNING, "Failed to accept MFC/R2 call!\n");
03653    }
03654    return res;
03655 }
03656 
03657 static int zap_accept_r2_call_exec(struct ast_channel *chan, void *data)
03658 {
03659    return dahdi_accept_r2_call_exec(chan, data);
03660 }
03661 
03662 static openr2_call_disconnect_cause_t dahdi_ast_cause_to_r2_cause(int cause)
03663 {
03664    openr2_call_disconnect_cause_t r2cause = OR2_CAUSE_NORMAL_CLEARING;
03665    switch (cause) {
03666    case AST_CAUSE_USER_BUSY:
03667    case AST_CAUSE_CALL_REJECTED:
03668    case AST_CAUSE_INTERWORKING: /* I don't know wtf is this but is used sometimes when ekiga rejects a call */
03669       r2cause = OR2_CAUSE_BUSY_NUMBER;
03670       break;
03671 
03672    case AST_CAUSE_NORMAL_CIRCUIT_CONGESTION:
03673    case AST_CAUSE_SWITCH_CONGESTION:
03674       r2cause = OR2_CAUSE_NETWORK_CONGESTION;
03675       break;
03676 
03677    case AST_CAUSE_UNALLOCATED:
03678       r2cause = OR2_CAUSE_UNALLOCATED_NUMBER;
03679       break;
03680 
03681    case AST_CAUSE_NETWORK_OUT_OF_ORDER:
03682    case AST_CAUSE_DESTINATION_OUT_OF_ORDER:
03683       r2cause = OR2_CAUSE_OUT_OF_ORDER;
03684       break;
03685 
03686    case AST_CAUSE_NO_ANSWER:
03687    case AST_CAUSE_NO_USER_RESPONSE:
03688       r2cause = OR2_CAUSE_NO_ANSWER;
03689       break;
03690 
03691    default:
03692       r2cause = OR2_CAUSE_NORMAL_CLEARING;
03693       break;
03694    }
03695    ast_log(LOG_DEBUG, "dahdi_ast_cause_to_r2_cause returned %d/%s for ast cause %d\n", 
03696          r2cause, openr2_proto_get_disconnect_string(r2cause), cause);
03697    return r2cause;
03698 }
03699 #endif
03700 
03701 static int dahdi_hangup(struct ast_channel *ast)
03702 {
03703    int res;
03704    int index,x, law;
03705    /*static int restore_gains(struct dahdi_pvt *p);*/
03706    struct dahdi_pvt *p = ast->tech_pvt;
03707    struct dahdi_pvt *tmp = NULL;
03708    struct dahdi_pvt *prev = NULL;
03709    struct dahdi_params par;
03710 
03711    if (option_debug)
03712       ast_log(LOG_DEBUG, "dahdi_hangup(%s)\n", ast->name);
03713    if (!ast->tech_pvt) {
03714       ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
03715       return 0;
03716    }
03717    
03718    ast_mutex_lock(&p->lock);
03719    
03720    index = dahdi_get_index(ast, p, 1);
03721 
03722    if (p->sig == SIG_PRI) {
03723       x = 1;
03724       ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0);
03725       p->cid_num[0] = '\0';
03726       p->cid_name[0] = '\0';
03727    }
03728 
03729    x = 0;
03730    dahdi_confmute(p, 0);
03731    restore_gains(p);
03732    if (p->origcid_num) {
03733       ast_copy_string(p->cid_num, p->origcid_num, sizeof(p->cid_num));
03734       free(p->origcid_num);
03735       p->origcid_num = NULL;
03736    }  
03737    if (p->origcid_name) {
03738       ast_copy_string(p->cid_name, p->origcid_name, sizeof(p->cid_name));
03739       free(p->origcid_name);
03740       p->origcid_name = NULL;
03741    }  
03742    if (p->dsp)
03743       ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax);
03744    p->exten[0] = '\0';
03745 
03746    if (option_debug)
03747       ast_log(LOG_DEBUG, "Hangup: channel: %d index = %d, normal = %d, callwait = %d, thirdcall = %d\n",
03748       p->channel, index, p->subs[SUB_REAL].dfd, p->subs[SUB_CALLWAIT].dfd, p->subs[SUB_THREEWAY].dfd);
03749    p->ignoredtmf = 0;
03750    
03751    if (index > -1) {
03752       /* Real channel, do some fixup */
03753       p->subs[index].owner = NULL;
03754       p->subs[index].needanswer = 0;
03755       p->subs[index].needflash = 0;
03756       p->subs[index].needringing = 0;
03757       p->subs[index].needbusy = 0;
03758       p->subs[index].needcongestion = 0;
03759       p->subs[index].linear = 0;
03760       p->subs[index].needcallerid = 0;
03761       p->polarity = POLARITY_IDLE;
03762       dahdi_setlinear(p->subs[index].dfd, 0);
03763       switch (index) {
03764       case SUB_REAL:
03765          if ((p->subs[SUB_CALLWAIT].dfd > -1) && (p->subs[SUB_THREEWAY].dfd > -1)) {
03766             ast_log(LOG_DEBUG, "Normal call hung up with both three way call and a call waiting call in place?\n");
03767             if (p->subs[SUB_CALLWAIT].inthreeway) {
03768                /* We had flipped over to answer a callwait and now it's gone */
03769                ast_log(LOG_DEBUG, "We were flipped over to the callwait, moving back and unowning.\n");
03770                /* Move to the call-wait, but un-own us until they flip back. */
03771                swap_subs(p, SUB_CALLWAIT, SUB_REAL);
03772                unalloc_sub(p, SUB_CALLWAIT);
03773                p->owner = NULL;
03774             } else {
03775                /* The three way hung up, but we still have a call wait */
03776                ast_log(LOG_DEBUG, "We were in the threeway and have a callwait still.  Ditching the threeway.\n");
03777                swap_subs(p, SUB_THREEWAY, SUB_REAL);
03778                unalloc_sub(p, SUB_THREEWAY);
03779                if (p->subs[SUB_REAL].inthreeway) {
03780                   /* This was part of a three way call.  Immediately make way for
03781                      another call */
03782                   ast_log(LOG_DEBUG, "Call was complete, setting owner to former third call\n");
03783                   p->subs[SUB_REAL].inthreeway = 0;
03784                   p->owner = p->subs[SUB_REAL].owner;
03785                } else {
03786                   /* This call hasn't been completed yet...  Set owner to NULL */
03787                   ast_log(LOG_DEBUG, "Call was incomplete, setting owner to NULL\n");
03788                   p->owner = NULL;
03789                }
03790             }
03791          } else if (p->subs[SUB_CALLWAIT].dfd > -1) {
03792             /* Need to hold the lock for real-call, private, and call-waiting call */
03793             dahdi_lock_sub_owner(p, SUB_CALLWAIT);
03794             if (!p->subs[SUB_CALLWAIT].owner) {
03795                /* The call waiting call dissappeared. */
03796                p->owner = NULL;
03797                break;
03798             }
03799 
03800             /* Move to the call-wait and switch back to them. */
03801             swap_subs(p, SUB_CALLWAIT, SUB_REAL);
03802             unalloc_sub(p, SUB_CALLWAIT);
03803             p->owner = p->subs[SUB_REAL].owner;
03804             if (p->owner->_state != AST_STATE_UP)
03805                p->subs[SUB_REAL].needanswer = 1;
03806             if (ast_bridged_channel(p->subs[SUB_REAL].owner))
03807                ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
03808             /* Unlock the call-waiting call that we swapped to real-call. */
03809             ast_mutex_unlock(&p->subs[SUB_REAL].owner->lock);
03810          } else if (p->subs[SUB_THREEWAY].dfd > -1) {
03811             swap_subs(p, SUB_THREEWAY, SUB_REAL);
03812             unalloc_sub(p, SUB_THREEWAY);
03813             if (p->subs[SUB_REAL].inthreeway) {
03814                /* This was part of a three way call.  Immediately make way for
03815                   another call */
03816                ast_log(LOG_DEBUG, "Call was complete, setting owner to former third call\n");
03817                p->subs[SUB_REAL].inthreeway = 0;
03818                p->owner = p->subs[SUB_REAL].owner;
03819             } else {
03820                /* This call hasn't been completed yet...  Set owner to NULL */
03821                ast_log(LOG_DEBUG, "Call was incomplete, setting owner to NULL\n");
03822                p->owner = NULL;
03823             }
03824          }
03825          break;
03826       case SUB_CALLWAIT:
03827          /* Ditch the holding callwait call, and immediately make it availabe */
03828          if (p->subs[SUB_CALLWAIT].inthreeway) {
03829             /* Need to hold the lock for call-waiting call, private, and 3-way call */
03830             dahdi_lock_sub_owner(p, SUB_THREEWAY);
03831 
03832             /* This is actually part of a three way, placed on hold.  Place the third part
03833                on music on hold now */
03834             if (p->subs[SUB_THREEWAY].owner && ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
03835                ast_queue_control_data(p->subs[SUB_THREEWAY].owner, AST_CONTROL_HOLD, 
03836                   S_OR(p->mohsuggest, NULL),
03837                   !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
03838             }
03839             p->subs[SUB_THREEWAY].inthreeway = 0;
03840             /* Make it the call wait now */
03841             swap_subs(p, SUB_CALLWAIT, SUB_THREEWAY);
03842             unalloc_sub(p, SUB_THREEWAY);
03843             if (p->subs[SUB_CALLWAIT].owner) {
03844                /* Unlock the 3-way call that we swapped to call-waiting call. */
03845                ast_mutex_unlock(&p->subs[SUB_CALLWAIT].owner->lock);
03846             }
03847          } else
03848             unalloc_sub(p, SUB_CALLWAIT);
03849          break;
03850       case SUB_THREEWAY:
03851          /* Need to hold the lock for 3-way call, private, and call-waiting call */
03852          dahdi_lock_sub_owner(p, SUB_CALLWAIT);
03853          if (p->subs[SUB_CALLWAIT].inthreeway) {
03854             /* The other party of the three way call is currently in a call-wait state.
03855                Start music on hold for them, and take the main guy out of the third call */
03856             p->subs[SUB_CALLWAIT].inthreeway = 0;
03857             if (p->subs[SUB_CALLWAIT].owner && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner)) {
03858                ast_queue_control_data(p->subs[SUB_CALLWAIT].owner, AST_CONTROL_HOLD, 
03859                   S_OR(p->mohsuggest, NULL),
03860                   !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
03861             }
03862          }
03863          if (p->subs[SUB_CALLWAIT].owner) {
03864             ast_mutex_unlock(&p->subs[SUB_CALLWAIT].owner->lock);
03865          }
03866          p->subs[SUB_REAL].inthreeway = 0;
03867          /* If this was part of a three way call index, let us make
03868             another three way call */
03869          unalloc_sub(p, SUB_THREEWAY);
03870          break;
03871       default:
03872          /*
03873           * Should never happen.
03874           * This wasn't any sort of call, so how are we an index?
03875           */
03876          ast_log(LOG_ERROR, "Index found but not any type of call?\n");
03877          break;
03878       }
03879    }
03880 
03881    if (!p->subs[SUB_REAL].owner && !p->subs[SUB_CALLWAIT].owner && !p->subs[SUB_THREEWAY].owner) {
03882       p->ringt = 0;
03883       p->distinctivering = 0;
03884       p->confirmanswer = 0;
03885       p->cidrings = 1;
03886       p->outgoing = 0;
03887       p->digital = 0;
03888       p->faxhandled = 0;
03889       p->pulsedial = 0;
03890       p->onhooktime = time(NULL);
03891 #ifdef HAVE_PRI
03892       p->dialing = 0;
03893       p->progress = 0;
03894       p->call_level = DAHDI_CALL_LEVEL_IDLE;
03895 #endif      
03896       if (p->dsp) {
03897          ast_dsp_free(p->dsp);
03898          p->dsp = NULL;
03899       }
03900 
03901       if (p->bufferoverrideinuse) {
03902          /* faxbuffers are in use, revert them */
03903          struct dahdi_bufferinfo bi = {
03904             .txbufpolicy = p->buf_policy,
03905             .rxbufpolicy = p->buf_policy,
03906             .bufsize = p->bufsize,
03907             .numbufs = p->buf_no
03908          };
03909          int bpres;
03910 
03911          if ((bpres = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SET_BUFINFO, &bi)) < 0) {
03912             ast_log(LOG_WARNING, "Channel '%s' unable to revert faxbuffer policy: %s\n", ast->name, strerror(errno));
03913          }
03914          p->bufferoverrideinuse = 0;   
03915       }
03916 
03917       law = DAHDI_LAW_DEFAULT;
03918       res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETLAW, &law);
03919       if (res < 0) 
03920          ast_log(LOG_WARNING, "Unable to set law on channel %d to default: %s\n", p->channel, strerror(errno));
03921       /* Perform low level hangup if no owner left */
03922 
03923 #ifdef HAVE_OPENR2
03924       if (p->mfcr2 && p->mfcr2call && openr2_chan_get_direction(p->r2chan) != OR2_DIR_STOPPED) {
03925          ast_log(LOG_DEBUG, "disconnecting MFC/R2 call on chan %d\n", p->channel);
03926          ast_log(LOG_DEBUG, "ast->hangupcause is %d\n", ast->hangupcause);
03927          if (openr2_chan_get_direction(p->r2chan) == OR2_DIR_BACKWARD && p->mfcr2_forced_release) {
03928             dahdi_r2_disconnect_call(p, OR2_CAUSE_FORCED_RELEASE);
03929          } else {
03930             const char *r2causestr = pbx_builtin_getvar_helper(ast,"MFCR2_CAUSE");
03931             int r2cause_user = r2causestr ? atoi(r2causestr) : 0;
03932             openr2_call_disconnect_cause_t r2cause = r2cause_user
03933                                ? dahdi_ast_cause_to_r2_cause(r2cause_user)
03934                                : dahdi_ast_cause_to_r2_cause(ast->hangupcause);
03935             dahdi_r2_disconnect_call(p, r2cause);
03936          }
03937       } else if (p->mfcr2call) {
03938          ast_log(LOG_DEBUG, "Clearing call request on channel %d\n", p->channel);
03939          p->mfcr2call = 0;
03940       }
03941 #endif
03942 
03943 #if defined(HAVE_PRI)
03944       if (p->pri) {
03945 #ifdef SUPPORT_USERUSER
03946          const char *useruser = pbx_builtin_getvar_helper(ast,"USERUSERINFO");
03947 #endif
03948 
03949          /* Make sure we have a call (or REALLY have a call in the case of a PRI) */
03950          pri_grab(p, p->pri);
03951          if (p->call && (!p->bearer || (p->bearer->call == p->call))) {
03952             if (p->alreadyhungup) {
03953                ast_log(LOG_DEBUG, "Already hungup...  Calling hangup once, and clearing call\n");
03954 
03955 #ifdef SUPPORT_USERUSER
03956                pri_call_set_useruser(p->call, useruser);
03957 #endif
03958 
03959                pri_hangup(p->pri->pri, p->call, -1);
03960                p->call = NULL;
03961                if (p->bearer)
03962                   p->bearer->call = NULL;
03963             } else {
03964                const char *cause = pbx_builtin_getvar_helper(ast,"PRI_CAUSE");
03965                int icause = ast->hangupcause ? ast->hangupcause : -1;
03966                ast_log(LOG_DEBUG, "Not yet hungup...  Calling hangup once with icause, and clearing call\n");
03967 
03968 #ifdef SUPPORT_USERUSER
03969                pri_call_set_useruser(p->call, useruser);
03970 #endif
03971 
03972                p->alreadyhungup = 1;
03973                if (p->bearer)
03974                   p->bearer->alreadyhungup = 1;
03975                if (cause) {
03976                   if (atoi(cause))
03977                      icause = atoi(cause);
03978                }
03979                pri_hangup(p->pri->pri, p->call, icause);
03980             }
03981          } else {
03982             if (p->bearer)
03983                ast_log(LOG_DEBUG, "Bearer call is %p, while ours is still %p\n", p->bearer->call, p->call);
03984             p->call = NULL;
03985          }
03986          p->allocated = 0;
03987          p->owner = NULL;
03988          pri_rel(p->pri);
03989          res = 0;
03990       } else
03991 #endif   /* defined(HAVE_PRI) */
03992       {
03993          p->owner = NULL;
03994       }
03995       if (p->sig && (p->sig != SIG_PRI) && (p->sig != SIG_MFCR2))
03996          res = dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_ONHOOK);
03997       if (res < 0) {
03998          ast_log(LOG_WARNING, "Unable to hangup line %s\n", ast->name);
03999       }
04000       switch (p->sig) {
04001       case SIG_FXOGS:
04002       case SIG_FXOLS:
04003       case SIG_FXOKS:
04004          memset(&par, 0, sizeof(par));
04005          res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &par);
04006          if (!res) {
04007 #if 0
04008             ast_log(LOG_DEBUG, "Hanging up channel %d, offhook = %d\n", p->channel, par.rxisoffhook);
04009 #endif
04010             /* If they're off hook, try playing congestion */
04011             if ((par.rxisoffhook) && (!(p->radio || (p->oprmode < 0))))
04012                tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION);
04013             else
04014                tone_zone_play_tone(p->subs[SUB_REAL].dfd, -1);
04015          }
04016          break;
04017       case SIG_FXSGS:
04018       case SIG_FXSLS:
04019       case SIG_FXSKS:
04020          /* Make sure we're not made available for at least two seconds assuming
04021             we were actually used for an inbound or outbound call. */
04022          if (ast->_state != AST_STATE_RESERVED) {
04023             time(&p->guardtime);
04024             p->guardtime += 2;
04025          }
04026          break;
04027       default:
04028          tone_zone_play_tone(p->subs[SUB_REAL].dfd, -1);
04029       }
04030       free(p->cidspill);
04031       p->cidspill = NULL;
04032       if (p->sig)
04033          dahdi_disable_ec(p);
04034       x = 0;
04035       ast_channel_setoption(ast,AST_OPTION_TONE_VERIFY,&x,sizeof(char),0);
04036       ast_channel_setoption(ast,AST_OPTION_TDD,&x,sizeof(char),0);
04037       p->didtdd = 0;
04038       p->callwaitcas = 0;
04039       p->callwaiting = p->permcallwaiting;
04040       p->hidecallerid = p->permhidecallerid;
04041       p->dialing = 0;
04042       p->rdnis[0] = '\0';
04043       update_conf(p);
04044       reset_conf(p);
04045       /* Restore data mode */
04046       if (p->sig == SIG_PRI) {
04047          x = 0;
04048          ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0);
04049       }
04050 #ifdef HAVE_PRI
04051       if (p->bearer) {
04052          ast_log(LOG_DEBUG, "Freeing up bearer channel %d\n", p->bearer->channel);
04053          /* Free up the bearer channel as well, and
04054             don't use its file descriptor anymore */
04055          update_conf(p->bearer);
04056          reset_conf(p->bearer);
04057          p->bearer->owner = NULL;
04058          p->bearer->realcall = NULL;
04059          p->bearer = NULL;
04060          p->subs[SUB_REAL].dfd = -1;
04061          p->pri = NULL;
04062       }
04063 #endif
04064       if (num_restart_pending == 0)
04065          restart_monitor();
04066    }
04067 
04068    p->callwaitingrepeat = 0;
04069    p->cidcwexpire = 0;
04070    p->cid_suppress_expire = 0;
04071    p->oprmode = 0;
04072    ast->tech_pvt = NULL;
04073    ast_mutex_unlock(&p->lock);
04074    if (option_verbose > 2) 
04075       ast_verbose( VERBOSE_PREFIX_3 "Hungup '%s'\n", ast->name);
04076 
04077    ast_mutex_lock(&iflock);
04078    if (p->restartpending) {
04079       num_restart_pending--;
04080    }
04081 
04082    tmp = iflist;
04083    prev = NULL;
04084    if (p->destroy) {
04085       while (tmp) {
04086          if (tmp == p) {
04087             destroy_channel(prev, tmp, 0);
04088             break;
04089          } else {
04090             prev = tmp;
04091             tmp = tmp->next;
04092          }
04093       }
04094    }
04095    ast_mutex_unlock(&iflock);
04096 
04097    ast_module_unref(ast_module_info->self);
04098    return 0;
04099 }
04100 
04101 static int dahdi_answer(struct ast_channel *ast)
04102 {
04103    struct dahdi_pvt *p = ast->tech_pvt;
04104    int res = 0;
04105    int index;
04106    int oldstate = ast->_state;
04107    ast_setstate(ast, AST_STATE_UP);
04108    ast_mutex_lock(&p->lock);
04109    index = dahdi_get_index(ast, p, 0);
04110    if (index < 0)
04111       index = SUB_REAL;
04112    /* nothing to do if a radio channel */
04113    if ((p->radio || (p->oprmode < 0))) {
04114       ast_mutex_unlock(&p->lock);
04115       return 0;
04116    }
04117    switch (p->sig) {
04118    case SIG_FXSLS:
04119    case SIG_FXSGS:
04120    case SIG_FXSKS:
04121       p->ringt = 0;
04122       /* Fall through */
04123    case SIG_EM:
04124    case SIG_EM_E1:
04125    case SIG_EMWINK:
04126    case SIG_FEATD:
04127    case SIG_FEATDMF:
04128    case SIG_FEATDMF_TA:
04129    case SIG_E911:
04130    case SIG_FGC_CAMA:
04131    case SIG_FGC_CAMAMF:
04132    case SIG_FEATB:
04133    case SIG_SF:
04134    case SIG_SFWINK:
04135    case SIG_SF_FEATD:
04136    case SIG_SF_FEATDMF:
04137    case SIG_SF_FEATB:
04138    case SIG_FXOLS:
04139    case SIG_FXOGS:
04140    case SIG_FXOKS:
04141       /* Pick up the line */
04142       ast_log(LOG_DEBUG, "Took %s off hook\n", ast->name);
04143       if (p->hanguponpolarityswitch) {
04144          gettimeofday(&p->polaritydelaytv, NULL);
04145       }
04146       res = dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_OFFHOOK);
04147       tone_zone_play_tone(p->subs[index].dfd, -1);
04148       p->dialing = 0;
04149       if ((index == SUB_REAL) && p->subs[SUB_THREEWAY].inthreeway) {
04150          if (oldstate == AST_STATE_RINGING) {
04151             ast_log(LOG_DEBUG, "Finally swapping real and threeway\n");
04152             tone_zone_play_tone(p->subs[SUB_THREEWAY].dfd, -1);
04153             swap_subs(p, SUB_THREEWAY, SUB_REAL);
04154             p->owner = p->subs[SUB_REAL].owner;
04155          }
04156       }
04157       if (p->sig & __DAHDI_SIG_FXS) {
04158          dahdi_enable_ec(p);
04159          dahdi_train_ec(p);
04160       }
04161       break;
04162 #ifdef HAVE_PRI
04163    case SIG_PRI:
04164       /* Send a pri acknowledge */
04165       if (!pri_grab(p, p->pri)) {
04166          if (p->call_level < DAHDI_CALL_LEVEL_CONNECT) {
04167             p->call_level = DAHDI_CALL_LEVEL_CONNECT;
04168          }
04169          p->dialing = 0;
04170          res = pri_answer(p->pri->pri, p->call, 0, !p->digital);
04171          pri_rel(p->pri);
04172       } else {
04173          ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
04174          res = -1;
04175       }
04176       break;
04177 #endif
04178 
04179 #ifdef HAVE_OPENR2
04180    case SIG_MFCR2:
04181       if (!p->mfcr2_accept_on_offer) {
04182          /* the call was not accepted on offer, so it must be accepted now before answering,
04183             the answer will be executed when the callback on_call_accepted is executed */
04184          if (p->mfcr2_charge_calls) {
04185             ast_log(LOG_DEBUG, "Accepting MFC/R2 call before answering with charge on chan %d\n", p->channel);
04186             openr2_chan_accept_call(p->r2chan, OR2_CALL_WITH_CHARGE);
04187          } else {
04188             ast_log(LOG_DEBUG, "Accepting MFC/R2 call before answering with no charge on chan %d\n", p->channel);
04189             openr2_chan_accept_call(p->r2chan, OR2_CALL_NO_CHARGE);
04190          }
04191       } else {
04192          ast_log(LOG_DEBUG, "Answering MFC/R2 call on chan %d\n", p->channel);
04193          res = dahdi_r2_answer(p);
04194       }
04195       break;
04196 #endif
04197 
04198    case 0:
04199       ast_mutex_unlock(&p->lock);
04200       return 0;
04201    default:
04202       ast_log(LOG_WARNING, "Don't know how to answer signalling %d (channel %d)\n", p->sig, p->channel);
04203       res = -1;
04204    }
04205    ast_mutex_unlock(&p->lock);
04206    return res;
04207 }
04208 
04209 static int dahdi_setoption(struct ast_channel *chan, int option, void *data, int datalen)
04210 {
04211    char *cp;
04212    signed char *scp;
04213    int x;
04214    int index;
04215    struct dahdi_pvt *p = chan->tech_pvt, *pp;
04216    struct oprmode *oprmode;
04217    
04218 
04219    /* all supported options require data */
04220    if (!data || (datalen < 1)) {
04221       errno = EINVAL;
04222       return -1;
04223    }
04224 
04225    switch (option) {
04226    case AST_OPTION_TXGAIN:
04227       scp = (signed char *) data;
04228       index = dahdi_get_index(chan, p, 0);
04229       if (index < 0) {
04230          ast_log(LOG_WARNING, "No index in TXGAIN?\n");
04231          return -1;
04232       }
04233       if (option_debug)
04234          ast_log(LOG_DEBUG, "Setting actual tx gain on %s to %f\n", chan->name, p->txgain + (float) *scp);
04235       return set_actual_txgain(p->subs[index].dfd, 0, p->txgain + (float) *scp, p->law);
04236    case AST_OPTION_RXGAIN:
04237       scp = (signed char *) data;
04238       index = dahdi_get_index(chan, p, 0);
04239       if (index < 0) {
04240          ast_log(LOG_WARNING, "No index in RXGAIN?\n");
04241          return -1;
04242       }
04243       if (option_debug)
04244          ast_log(LOG_DEBUG, "Setting actual rx gain on %s to %f\n", chan->name, p->rxgain + (float) *scp);
04245       return set_actual_rxgain(p->subs[index].dfd, 0, p->rxgain + (float) *scp, p->law);
04246    case AST_OPTION_TONE_VERIFY:
04247       if (!p->dsp)
04248          break;
04249       cp = (char *) data;
04250       switch (*cp) {
04251       case 1:
04252          ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: MUTECONF(1) on %s\n",chan->name);
04253          ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MUTECONF | p->dtmfrelax);  /* set mute mode if desired */
04254          break;
04255       case 2:
04256          ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: MUTECONF/MAX(2) on %s\n",chan->name);
04257          ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX | p->dtmfrelax);  /* set mute mode if desired */
04258          break;
04259       default:
04260          ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: OFF(0) on %s\n",chan->name);
04261          ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax);  /* set mute mode if desired */
04262          break;
04263       }
04264       break;
04265    case AST_OPTION_TDD:
04266       /* turn on or off TDD */
04267       cp = (char *) data;
04268       p->mate = 0;
04269       if (!*cp) { /* turn it off */
04270          if (option_debug)
04271             ast_log(LOG_DEBUG, "Set option TDD MODE, value: OFF(0) on %s\n",chan->name);
04272          if (p->tdd)
04273             tdd_free(p->tdd);
04274          p->tdd = 0;
04275          break;
04276       }
04277       ast_log(LOG_DEBUG, "Set option TDD MODE, value: %s(%d) on %s\n",
04278          (*cp == 2) ? "MATE" : "ON", (int) *cp, chan->name);
04279       dahdi_disable_ec(p);
04280       /* otherwise, turn it on */
04281       if (!p->didtdd) { /* if havent done it yet */
04282          unsigned char mybuf[41000];/*! \todo XXX This is an abuse of the stack!! */
04283          unsigned char *buf;
04284          int size, res, fd, len;
04285          struct pollfd fds[1];
04286 
04287          buf = mybuf;
04288          memset(buf, 0x7f, sizeof(mybuf)); /* set to silence */
04289          ast_tdd_gen_ecdisa(buf + 16000, 16000);  /* put in tone */
04290          len = 40000;
04291          index = dahdi_get_index(chan, p, 0);
04292          if (index < 0) {
04293             ast_log(LOG_WARNING, "No index in TDD?\n");
04294             return -1;
04295          }
04296          fd = p->subs[index].dfd;
04297          while (len) {
04298             if (ast_check_hangup(chan))
04299                return -1;
04300             size = len;
04301             if (size > READ_SIZE)
04302                size = READ_SIZE;
04303             fds[0].fd = fd;
04304             fds[0].events = POLLPRI | POLLOUT;
04305             fds[0].revents = 0;
04306             res = poll(fds, 1, -1);
04307             if (!res) {
04308                ast_log(LOG_DEBUG, "poll (for write) ret. 0 on channel %d\n", p->channel);
04309                continue;
04310             }
04311             /* if got exception */
04312             if (fds[0].revents & POLLPRI)
04313                return -1;
04314             if (!(fds[0].revents & POLLOUT)) {
04315                ast_log(LOG_DEBUG, "write fd not ready on channel %d\n", p->channel);
04316                continue;
04317             }
04318             res = write(fd, buf, size);
04319             if (res != size) {
04320                if (res == -1) return -1;
04321                ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
04322                break;
04323             }
04324             len -= size;
04325             buf += size;
04326          }
04327          p->didtdd = 1; /* set to have done it now */    
04328       }
04329       if (*cp == 2) { /* Mate mode */
04330          if (p->tdd)
04331             tdd_free(p->tdd);
04332          p->tdd = 0;
04333          p->mate = 1;
04334          break;
04335       }     
04336       if (!p->tdd) { /* if we dont have one yet */
04337          p->tdd = tdd_new(); /* allocate one */
04338       }     
04339       break;
04340    case AST_OPTION_RELAXDTMF:  /* Relax DTMF decoding (or not) */
04341       if (!p->dsp)
04342          break;
04343       cp = (char *) data;
04344       ast_log(LOG_DEBUG, "Set option RELAX DTMF, value: %s(%d) on %s\n",
04345          *cp ? "ON" : "OFF", (int) *cp, chan->name);
04346                 p->dtmfrelax = 0;
04347                 if (*cp) p->dtmfrelax = DSP_DIGITMODE_RELAXDTMF;
04348                 ast_dsp_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax);
04349       break;
04350    case AST_OPTION_AUDIO_MODE:  /* Set AUDIO mode (or not) */
04351       cp = (char *) data;
04352       if (!*cp) {    
04353          ast_log(LOG_DEBUG, "Set option AUDIO MODE, value: OFF(0) on %s\n", chan->name);
04354          x = 0;
04355          dahdi_disable_ec(p);
04356       } else {    
04357          ast_log(LOG_DEBUG, "Set option AUDIO MODE, value: ON(1) on %s\n", chan->name);
04358          x = 1;
04359       }
04360       if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &x) == -1)
04361          ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d: %s\n", p->channel, x, strerror(errno));
04362       break;
04363    case AST_OPTION_OPRMODE:  /* Operator services mode */
04364       oprmode = (struct oprmode *) data;
04365       pp = oprmode->peer->tech_pvt;
04366       p->oprmode = pp->oprmode = 0;
04367       /* setup peers */
04368       p->oprpeer = pp;
04369       pp->oprpeer = p;
04370       /* setup modes, if any */
04371       if (oprmode->mode) 
04372       {
04373          pp->oprmode = oprmode->mode;
04374          p->oprmode = -oprmode->mode;
04375       }
04376       ast_log(LOG_DEBUG, "Set Operator Services mode, value: %d on %s/%s\n",
04377          oprmode->mode, chan->name,oprmode->peer->name);;
04378       break;
04379    case AST_OPTION_ECHOCAN:
04380       cp = (char *) data;
04381       if (*cp) {
04382          ast_log(LOG_DEBUG, "Enabling echo cancellation on %s\n", chan->name);
04383          dahdi_enable_ec(p);
04384       } else {
04385          ast_log(LOG_DEBUG, "Disabling echo cancellation on %s\n", chan->name);
04386          dahdi_disable_ec(p);
04387       }
04388       break;
04389    }
04390    errno = 0;
04391 
04392    return 0;
04393 }
04394 
04395 static int dahdi_func_read(struct ast_channel *chan, char *function, char *data, char *buf, size_t len)
04396 {
04397    struct dahdi_pvt *p = chan->tech_pvt;
04398    int res = 0;
04399    
04400    if (!strcasecmp(data, "rxgain")) {
04401       ast_mutex_lock(&p->lock);
04402       snprintf(buf, len, "%f", p->rxgain);
04403       ast_mutex_unlock(&p->lock);   
04404    } else if (!strcasecmp(data, "txgain")) {
04405       ast_mutex_lock(&p->lock);
04406       snprintf(buf, len, "%f", p->txgain);
04407       ast_mutex_unlock(&p->lock);   
04408    } else {
04409       ast_copy_string(buf, "", len);
04410       res = -1;
04411    }
04412 
04413    return res;
04414 }
04415 
04416 
04417 static int parse_buffers_policy(const char *parse, int *num_buffers, int *policy)
04418 {
04419    int res;
04420    char policy_str[21] = "";
04421    
04422    if (((res = sscanf(parse, "%d,%20s", num_buffers, policy_str)) != 2) &&
04423       ((res = sscanf(parse, "%d|%20s", num_buffers, policy_str)) != 2)) {
04424       ast_log(LOG_WARNING, "Parsing buffer string '%s' failed.\n", parse);
04425       return 1;
04426    }
04427    if (*num_buffers < 0) {
04428       ast_log(LOG_WARNING, "Invalid buffer count given '%d'.\n", *num_buffers);
04429       return -1;
04430    }
04431    if (!strcasecmp(policy_str, "full")) {
04432       *policy = DAHDI_POLICY_WHEN_FULL;
04433    } else if (!strcasecmp(policy_str, "immediate")) {
04434       *policy = DAHDI_POLICY_IMMEDIATE;
04435 #ifdef DAHDI_POLICY_HALF_FULL
04436    } else if (!strcasecmp(policy_str, "half")) {
04437       *policy = DAHDI_POLICY_HALF_FULL;
04438 #endif
04439    } else {
04440       ast_log(LOG_WARNING, "Invalid policy name given '%s'.\n", policy_str);
04441       return -1;
04442    }
04443 
04444    return 0;
04445 }
04446 
04447 static int dahdi_func_write(struct ast_channel *chan, char *function, char *data, const char *value)
04448 {
04449    struct dahdi_pvt *p = chan->tech_pvt;
04450    int res = 0;
04451 
04452    if (!strcasecmp(data, "buffers")) {
04453       int num_bufs, policy;
04454 
04455       if (!(parse_buffers_policy(value, &num_bufs, &policy))) {
04456          struct dahdi_bufferinfo bi = {
04457             .txbufpolicy = policy,
04458             .rxbufpolicy = policy,
04459             .bufsize = p->bufsize,
04460             .numbufs = num_bufs,
04461          };
04462          int bpres;
04463 
04464          if ((bpres = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SET_BUFINFO, &bi)) < 0) {
04465             ast_log(LOG_WARNING, "Channel '%d' unable to override buffer policy: %s\n", p->channel, strerror(errno));
04466          } else {
04467             p->bufferoverrideinuse = 1;
04468          }
04469       } else {
04470          res = -1;
04471       }
04472    } else {
04473       res = -1;
04474    }
04475 
04476    return res;
04477 }
04478 
04479 static void dahdi_unlink(struct dahdi_pvt *slave, struct dahdi_pvt *master, int needlock)
04480 {
04481    /* Unlink a specific slave or all slaves/masters from a given master */
04482    int x;
04483    int hasslaves;
04484    if (!master)
04485       return;
04486    if (needlock) {
04487       ast_mutex_lock(&master->lock);
04488       if (slave) {
04489          while (ast_mutex_trylock(&slave->lock)) {
04490             DEADLOCK_AVOIDANCE(&master->lock);
04491          }
04492       }
04493    }
04494    hasslaves = 0;
04495    for (x = 0; x < MAX_SLAVES; x++) {
04496       if (master->slaves[x]) {
04497          if (!slave || (master->slaves[x] == slave)) {
04498             /* Take slave out of the conference */
04499             ast_log(LOG_DEBUG, "Unlinking slave %d from %d\n", master->slaves[x]->channel, master->channel);
04500             conf_del(master, &master->slaves[x]->subs[SUB_REAL], SUB_REAL);
04501             conf_del(master->slaves[x], &master->subs[SUB_REAL], SUB_REAL);
04502             master->slaves[x]->master = NULL;
04503             master->slaves[x] = NULL;
04504          } else
04505             hasslaves = 1;
04506       }
04507       if (!hasslaves)
04508          master->inconference = 0;
04509    }
04510    if (!slave) {
04511       if (master->master) {
04512          /* Take master out of the conference */
04513          conf_del(master->master, &master->subs[SUB_REAL], SUB_REAL);
04514          conf_del(master, &master->master->subs[SUB_REAL], SUB_REAL);
04515          hasslaves = 0;
04516          for (x = 0; x < MAX_SLAVES; x++) {
04517             if (master->master->slaves[x] == master)
04518                master->master->slaves[x] = NULL;
04519             else if (master->master->slaves[x])
04520                hasslaves = 1;
04521          }
04522          if (!hasslaves)
04523             master->master->inconference = 0;
04524       }
04525       master->master = NULL;
04526    }
04527    update_conf(master);
04528    if (needlock) {
04529       if (slave)
04530          ast_mutex_unlock(&slave->lock);
04531       ast_mutex_unlock(&master->lock);
04532    }
04533 }
04534 
04535 static void dahdi_link(struct dahdi_pvt *slave, struct dahdi_pvt *master) {
04536    int x;
04537    if (!slave || !master) {
04538       ast_log(LOG_WARNING, "Tried to link to/from NULL??\n");
04539       return;
04540    }
04541    for (x = 0; x < MAX_SLAVES; x++) {
04542       if (!master->slaves[x]) {
04543          master->slaves[x] = slave;
04544          break;
04545       }
04546    }
04547    if (x >= MAX_SLAVES) {
04548       ast_log(LOG_WARNING, "Replacing slave %d with new slave, %d\n", master->slaves[MAX_SLAVES - 1]->channel, slave->channel);
04549       master->slaves[MAX_SLAVES - 1] = slave;
04550    }
04551    if (slave->master) 
04552       ast_log(LOG_WARNING, "Replacing master %d with new master, %d\n", slave->master->channel, master->channel);
04553    slave->master = master;
04554    
04555    ast_log(LOG_DEBUG, "Making %d slave to master %d at %d\n", slave->channel, master->channel, x);
04556 }
04557 
04558 static void disable_dtmf_detect(struct dahdi_pvt *p)
04559 {
04560 #ifdef DAHDI_TONEDETECT
04561    int val;
04562 #endif
04563 
04564    p->ignoredtmf = 1;
04565 
04566 #ifdef DAHDI_TONEDETECT
04567    val = 0;
04568    ioctl(p->subs[SUB_REAL].dfd, DAHDI_TONEDETECT, &val);
04569 #endif      
04570    if (!p->hardwaredtmf && p->dsp) {
04571       p->dsp_features &= ~DSP_FEATURE_DTMF_DETECT;
04572       ast_dsp_set_features(p->dsp, p->dsp_features);
04573    }
04574 }
04575 
04576 static void enable_dtmf_detect(struct dahdi_pvt *p)
04577 {
04578 #ifdef DAHDI_TONEDETECT
04579    int val;
04580 #endif
04581 
04582    if (p->channel == CHAN_PSEUDO)
04583       return;
04584 
04585    p->ignoredtmf = 0;
04586 
04587 #ifdef DAHDI_TONEDETECT
04588    val = DAHDI_TONEDETECT_ON | DAHDI_TONEDETECT_MUTE;
04589    ioctl(p->subs[SUB_REAL].dfd, DAHDI_TONEDETECT, &val);
04590 #endif      
04591    if (!p->hardwaredtmf && p->dsp) {
04592       p->dsp_features |= DSP_FEATURE_DTMF_DETECT;
04593       ast_dsp_set_features(p->dsp, p->dsp_features);
04594    }
04595 }
04596 
04597 static enum ast_bridge_result dahdi_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms)
04598 {
04599    struct ast_channel *who;
04600    struct dahdi_pvt *p0, *p1, *op0, *op1;
04601    struct dahdi_pvt *master = NULL, *slave = NULL;
04602    struct ast_frame *f;
04603    int inconf = 0;
04604    int nothingok = 1;
04605    int ofd0, ofd1;
04606    int oi0, oi1, i0 = -1, i1 = -1, t0, t1;
04607    int os0 = -1, os1 = -1;
04608    int priority = 0;
04609    struct ast_channel *oc0, *oc1;
04610    enum ast_bridge_result res;
04611 
04612 #ifdef PRI_2BCT
04613    int triedtopribridge = 0;
04614 #endif
04615 
04616    /* For now, don't attempt to native bridge if either channel needs DTMF detection.
04617       There is code below to handle it properly until DTMF is actually seen,
04618       but due to currently unresolved issues it's ignored...
04619    */
04620 
04621    if (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))
04622       return AST_BRIDGE_FAILED_NOWARN;
04623 
04624    ast_mutex_lock(&c0->lock);
04625    while (ast_mutex_trylock(&c1->lock)) {
04626       DEADLOCK_AVOIDANCE(&c0->lock);
04627    }
04628 
04629    p0 = c0->tech_pvt;
04630    p1 = c1->tech_pvt;
04631    /* cant do pseudo-channels here */
04632    if (!p0 || (!p0->sig) || !p1 || (!p1->sig)) {
04633       ast_mutex_unlock(&c0->lock);
04634       ast_mutex_unlock(&c1->lock);
04635       return AST_BRIDGE_FAILED_NOWARN;
04636    }
04637 
04638    oi0 = dahdi_get_index(c0, p0, 0);
04639    oi1 = dahdi_get_index(c1, p1, 0);
04640    if ((oi0 < 0) || (oi1 < 0)) {
04641       ast_mutex_unlock(&c0->lock);
04642       ast_mutex_unlock(&c1->lock);
04643       return AST_BRIDGE_FAILED;
04644    }
04645 
04646    op0 = p0 = c0->tech_pvt;
04647    op1 = p1 = c1->tech_pvt;
04648    ofd0 = c0->fds[0];
04649    ofd1 = c1->fds[0];
04650    oc0 = p0->owner;
04651    oc1 = p1->owner;
04652 
04653    if (ast_mutex_trylock(&p0->lock)) {
04654       /* Don't block, due to potential for deadlock */
04655       ast_mutex_unlock(&c0->lock);
04656       ast_mutex_unlock(&c1->lock);
04657       ast_log(LOG_NOTICE, "Avoiding deadlock...\n");
04658       return AST_BRIDGE_RETRY;
04659    }
04660    if (ast_mutex_trylock(&p1->lock)) {
04661       /* Don't block, due to potential for deadlock */
04662       ast_mutex_unlock(&p0->lock);
04663       ast_mutex_unlock(&c0->lock);
04664       ast_mutex_unlock(&c1->lock);
04665       ast_log(LOG_NOTICE, "Avoiding deadlock...\n");
04666       return AST_BRIDGE_RETRY;
04667    }
04668 
04669    if ((p0->callwaiting && p0->callwaitingcallerid)
04670       || (p1->callwaiting && p1->callwaitingcallerid)) {
04671       /*
04672        * Call Waiting Caller ID requires DTMF detection to know if it
04673        * can send the CID spill.
04674        *
04675        * For now, don't attempt to native bridge if either channel
04676        * needs DTMF detection.  There is code below to handle it
04677        * properly until DTMF is actually seen, but due to currently
04678        * unresolved issues it's ignored...
04679        */
04680       ast_mutex_unlock(&p0->lock);
04681       ast_mutex_unlock(&p1->lock);
04682       ast_mutex_unlock(&c0->lock);
04683       ast_mutex_unlock(&c1->lock);
04684       return AST_BRIDGE_FAILED_NOWARN;
04685    }
04686 
04687    if ((oi0 == SUB_REAL) && (oi1 == SUB_REAL)) {
04688       if (p0->owner && p1->owner) {
04689          /* If we don't have a call-wait in a 3-way, and we aren't in a 3-way, we can be master */
04690          if (!p0->subs[SUB_CALLWAIT].inthreeway && !p1->subs[SUB_REAL].inthreeway) {
04691             master = p0;
04692             slave = p1;
04693             inconf = 1;
04694          } else if (!p1->subs[SUB_CALLWAIT].inthreeway && !p0->subs[SUB_REAL].inthreeway) {
04695             master = p1;
04696             slave = p0;
04697             inconf = 1;
04698          } else {
04699             ast_log(LOG_WARNING, "Huh?  Both calls are callwaits or 3-ways?  That's clever...?\n");
04700             ast_log(LOG_WARNING, "p0: chan %d/%d/CW%d/3W%d, p1: chan %d/%d/CW%d/3W%d\n",
04701                p0->channel,
04702                oi0, (p0->subs[SUB_CALLWAIT].dfd > -1) ? 1 : 0,
04703                p0->subs[SUB_REAL].inthreeway, p0->channel,
04704                oi0, (p1->subs[SUB_CALLWAIT].dfd > -1) ? 1 : 0,
04705                p1->subs[SUB_REAL].inthreeway);
04706          }
04707          nothingok = 0;
04708       }
04709    } else if ((oi0 == SUB_REAL) && (oi1 == SUB_THREEWAY)) {
04710       if (p1->subs[SUB_THREEWAY].inthreeway) {
04711          master = p1;
04712          slave = p0;
04713          nothingok = 0;
04714       }
04715    } else if ((oi0 == SUB_THREEWAY) && (oi1 == SUB_REAL)) {
04716       if (p0->subs[SUB_THREEWAY].inthreeway) {
04717          master = p0;
04718          slave = p1;
04719          nothingok = 0;
04720       }
04721    } else if ((oi0 == SUB_REAL) && (oi1 == SUB_CALLWAIT)) {
04722       /* We have a real and a call wait.  If we're in a three way call, put us in it, otherwise, 
04723          don't put us in anything */
04724       if (p1->subs[SUB_CALLWAIT].inthreeway) {
04725          master = p1;
04726          slave = p0;
04727          nothingok = 0;
04728       }
04729    } else if ((oi0 == SUB_CALLWAIT) && (oi1 == SUB_REAL)) {
04730       /* Same as previous */
04731       if (p0->subs[SUB_CALLWAIT].inthreeway) {
04732          master = p0;
04733          slave = p1;
04734          nothingok = 0;
04735       }
04736    }
04737    ast_log(LOG_DEBUG, "master: %d, slave: %d, nothingok: %d\n",
04738       master ? master->channel : 0, slave ? slave->channel : 0, nothingok);
04739    if (master && slave) {
04740       /* Stop any tones, or play ringtone as appropriate.  If they're bridged
04741          in an active threeway call with a channel that is ringing, we should
04742          indicate ringing. */
04743       if ((oi1 == SUB_THREEWAY) && 
04744           p1->subs[SUB_THREEWAY].inthreeway && 
04745           p1->subs[SUB_REAL].owner && 
04746           p1->subs[SUB_REAL].inthreeway && 
04747           (p1->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)) {
04748          ast_log(LOG_DEBUG,
04749             "Playing ringback on %d/%d(%s) since %d/%d(%s) is in a ringing three-way\n",
04750             p0->channel, oi0, c0->name, p1->channel, oi1, c1->name);
04751          tone_zone_play_tone(p0->subs[oi0].dfd, DAHDI_TONE_RINGTONE);
04752          os1 = p1->subs[SUB_REAL].owner->_state;
04753       } else {
04754          ast_log(LOG_DEBUG, "Stopping tones on %d/%d(%s) talking to %d/%d(%s)\n",
04755             p0->channel, oi0, c0->name, p1->channel, oi1, c1->name);
04756          tone_zone_play_tone(p0->subs[oi0].dfd, -1);
04757       }
04758       if ((oi0 == SUB_THREEWAY) && 
04759           p0->subs[SUB_THREEWAY].inthreeway && 
04760           p0->subs[SUB_REAL].owner && 
04761           p0->subs[SUB_REAL].inthreeway && 
04762           (p0->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)) {
04763          ast_log(LOG_DEBUG,
04764             "Playing ringback on %d/%d(%s) since %d/%d(%s) is in a ringing three-way\n",
04765             p1->channel, oi1, c1->name, p0->channel, oi0, c0->name);
04766          tone_zone_play_tone(p1->subs[oi1].dfd, DAHDI_TONE_RINGTONE);
04767          os0 = p0->subs[SUB_REAL].owner->_state;
04768       } else {
04769          ast_log(LOG_DEBUG, "Stopping tones on %d/%d(%s) talking to %d/%d(%s)\n",
04770             p1->channel, oi1, c1->name, p0->channel, oi0, c0->name);
04771          tone_zone_play_tone(p1->subs[oi1].dfd, -1);
04772       }
04773       if ((oi0 == SUB_REAL) && (oi1 == SUB_REAL)) {
04774          if (!p0->echocanbridged || !p1->echocanbridged) {
04775             /* Disable echo cancellation if appropriate */
04776             dahdi_disable_ec(p0);
04777             dahdi_disable_ec(p1);
04778          }
04779       }
04780       dahdi_link(slave, master);
04781       master->inconference = inconf;
04782    } else if (!nothingok)
04783       ast_log(LOG_WARNING, "Can't link %d/%s with %d/%s\n", p0->channel, subnames[oi0], p1->channel, subnames[oi1]);
04784 
04785    update_conf(p0);
04786    update_conf(p1);
04787    t0 = p0->subs[SUB_REAL].inthreeway;
04788    t1 = p1->subs[SUB_REAL].inthreeway;
04789 
04790    ast_mutex_unlock(&p0->lock);
04791    ast_mutex_unlock(&p1->lock);
04792 
04793    ast_mutex_unlock(&c0->lock);
04794    ast_mutex_unlock(&c1->lock);
04795 
04796    /* Native bridge failed */
04797    if ((!master || !slave) && !nothingok) {
04798       dahdi_enable_ec(p0);
04799       dahdi_enable_ec(p1);
04800       return AST_BRIDGE_FAILED;
04801    }
04802    
04803    if (option_verbose > 2) 
04804       ast_verbose(VERBOSE_PREFIX_3 "Native bridging %s and %s\n", c0->name, c1->name);
04805 
04806    if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0) && (oi0 == SUB_REAL))
04807       disable_dtmf_detect(op0);
04808 
04809    if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1) && (oi1 == SUB_REAL))
04810       disable_dtmf_detect(op1);
04811 
04812    for (;;) {
04813       struct ast_channel *c0_priority[2] = {c0, c1};
04814       struct ast_channel *c1_priority[2] = {c1, c0};
04815 
04816       /* Here's our main loop...  Start by locking things, looking for private parts, 
04817          and then balking if anything is wrong */
04818       ast_mutex_lock(&c0->lock);
04819       while (ast_mutex_trylock(&c1->lock)) {
04820          DEADLOCK_AVOIDANCE(&c0->lock);
04821       }
04822 
04823       p0 = c0->tech_pvt;
04824       p1 = c1->tech_pvt;
04825 
04826       if (op0 == p0)
04827          i0 = dahdi_get_index(c0, p0, 1);
04828       if (op1 == p1)
04829          i1 = dahdi_get_index(c1, p1, 1);
04830       ast_mutex_unlock(&c0->lock);
04831       ast_mutex_unlock(&c1->lock);
04832 
04833       if (!timeoutms || 
04834           (op0 != p0) ||
04835           (op1 != p1) || 
04836           (ofd0 != c0->fds[0]) || 
04837           (ofd1 != c1->fds[0]) ||
04838           (p0->subs[SUB_REAL].owner && (os0 > -1) && (os0 != p0->subs[SUB_REAL].owner->_state)) || 
04839           (p1->subs[SUB_REAL].owner && (os1 > -1) && (os1 != p1->subs[SUB_REAL].owner->_state)) || 
04840           (oc0 != p0->owner) || 
04841           (oc1 != p1->owner) ||
04842           (t0 != p0->subs[SUB_REAL].inthreeway) ||
04843           (t1 != p1->subs[SUB_REAL].inthreeway) ||
04844           (oi0 != i0) ||
04845           (oi1 != i1)) {
04846          ast_log(LOG_DEBUG, "Something changed out on %d/%d to %d/%d, returning -3 to restart\n",
04847             op0->channel, oi0, op1->channel, oi1);
04848          res = AST_BRIDGE_RETRY;
04849          goto return_from_bridge;
04850       }
04851 
04852 #ifdef PRI_2BCT
04853       if (!triedtopribridge) {
04854          triedtopribridge = 1;
04855          if (p0->pri && p0->pri == p1->pri && p0->transfer && p1->transfer) {
04856             ast_mutex_lock(&p0->pri->lock);
04857             if (p0->call && p1->call) {
04858                pri_channel_bridge(p0->call, p1->call);
04859             }
04860             ast_mutex_unlock(&p0->pri->lock);
04861          }
04862       }
04863 #endif
04864 
04865       who = ast_waitfor_n(priority ? c0_priority : c1_priority, 2, &timeoutms);
04866       if (!who) {
04867          ast_log(LOG_DEBUG, "Ooh, empty read...\n");
04868          continue;
04869       }
04870       f = ast_read(who);
04871       if (!f || (f->frametype == AST_FRAME_CONTROL)) {
04872          *fo = f;
04873          *rc = who;
04874          res = AST_BRIDGE_COMPLETE;
04875          goto return_from_bridge;
04876       }
04877       if (f->frametype == AST_FRAME_DTMF) {
04878          if ((who == c0) && p0->pulsedial) {
04879             ast_write(c1, f);
04880          } else if ((who == c1) && p1->pulsedial) {
04881             ast_write(c0, f);
04882          } else {
04883             *fo = f;
04884             *rc = who;
04885             res = AST_BRIDGE_COMPLETE;
04886             goto return_from_bridge;
04887          }
04888       }
04889       ast_frfree(f);
04890       
04891       /* Swap who gets priority */
04892       priority = !priority;
04893    }
04894 
04895 return_from_bridge:
04896    if (op0 == p0)
04897       dahdi_enable_ec(p0);
04898 
04899    if (op1 == p1)
04900       dahdi_enable_ec(p1);
04901 
04902    if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0) && (oi0 == SUB_REAL))
04903       enable_dtmf_detect(op0);
04904 
04905    if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1) && (oi1 == SUB_REAL))
04906       enable_dtmf_detect(op1);
04907 
04908    dahdi_unlink(slave, master, 1);
04909 
04910    return res;
04911 }
04912 
04913 static int dahdi_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
04914 {
04915    struct dahdi_pvt *p = newchan->tech_pvt;
04916    int x;
04917    ast_mutex_lock(&p->lock);
04918    ast_log(LOG_DEBUG, "New owner for channel %d is %s\n", p->channel, newchan->name);
04919    if (p->owner == oldchan) {
04920       p->owner = newchan;
04921    }
04922    for (x = 0; x < 3; x++)
04923       if (p->subs[x].owner == oldchan) {
04924          if (!x)
04925             dahdi_unlink(NULL, p, 0);
04926          p->subs[x].owner = newchan;
04927       }
04928    update_conf(p);
04929    ast_mutex_unlock(&p->lock);
04930    if (newchan->_state == AST_STATE_RINGING) 
04931       dahdi_indicate(newchan, AST_CONTROL_RINGING, NULL, 0);
04932    return 0;
04933 }
04934 
04935 static int dahdi_ring_phone(struct dahdi_pvt *p)
04936 {
04937    int x;
04938    int res;
04939    /* Make sure our transmit state is on hook */
04940    x = 0;
04941    x = DAHDI_ONHOOK;
04942    res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x);
04943    do {
04944       x = DAHDI_RING;
04945       res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x);
04946       if (res) {
04947          switch (errno) {
04948          case EBUSY:
04949          case EINTR:
04950             /* Wait just in case */
04951             usleep(10000);
04952             continue;
04953          case EINPROGRESS:
04954             res = 0;
04955             break;
04956          default:
04957             ast_log(LOG_WARNING, "Couldn't ring the phone: %s\n", strerror(errno));
04958             res = 0;
04959          }
04960       }
04961    } while (res);
04962    return res;
04963 }
04964 
04965 static void *ss_thread(void *data);
04966 
04967 /*!
04968  * \internal
04969  * \brief Attempt to transfer 3-way call.
04970  *
04971  * \param p private structure.
04972  *
04973  * \note
04974  * On entry these locks are held: real-call, private, 3-way call.
04975  *
04976  * \retval 1 Transfer successful.  3-way call is unlocked and subchannel is unalloced.
04977  *         Swapped real and 3-way subchannel.
04978  * \retval 0 Transfer successful.  3-way call is unlocked and subchannel is unalloced.
04979  * \retval -1 on error.  Caller must unlock 3-way call.
04980  */
04981 static int attempt_transfer(struct dahdi_pvt *p)
04982 {
04983    /* In order to transfer, we need at least one of the channels to
04984       actually be in a call bridge.  We can't conference two applications
04985       together (but then, why would we want to?) */
04986    if (ast_bridged_channel(p->subs[SUB_REAL].owner)) {
04987       /* The three-way person we're about to transfer to could still be in MOH, so
04988          stop it now if appropriate */
04989       if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner))
04990          ast_queue_control(p->subs[SUB_THREEWAY].owner, AST_CONTROL_UNHOLD);
04991       if (p->subs[SUB_REAL].owner->_state == AST_STATE_RINGING) {
04992          /*
04993           * This may not be safe.
04994           * We currently hold the locks on the real-call, private, and 3-way call.
04995           * We could possibly avoid this here by using an ast_queue_control() instead.
04996           * However, the following ast_channel_masquerade() is going to be locking
04997           * the bridged channel again anyway.
04998           */
04999          ast_indicate(ast_bridged_channel(p->subs[SUB_REAL].owner), AST_CONTROL_RINGING);
05000       }
05001       if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RING) {
05002          tone_zone_play_tone(p->subs[SUB_THREEWAY].dfd, DAHDI_TONE_RINGTONE);
05003       }
05004        if (ast_channel_masquerade(p->subs[SUB_THREEWAY].owner, ast_bridged_channel(p->subs[SUB_REAL].owner))) {
05005          ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
05006                ast_bridged_channel(p->subs[SUB_REAL].owner)->name, p->subs[SUB_THREEWAY].owner->name);
05007          return -1;
05008       }
05009       /* Orphan the channel after releasing the lock */
05010       ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
05011       unalloc_sub(p, SUB_THREEWAY);
05012    } else if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
05013       ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
05014       if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RINGING) {
05015          /*
05016           * This may not be safe.
05017           * We currently hold the locks on the real-call, private, and 3-way call.
05018           * We could possibly avoid this here by using an ast_queue_control() instead.
05019           * However, the following ast_channel_masquerade() is going to be locking
05020           * the bridged channel again anyway.
05021           */
05022          ast_indicate(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), AST_CONTROL_RINGING);
05023       }
05024       if (p->subs[SUB_REAL].owner->_state == AST_STATE_RING) {
05025          tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_RINGTONE);
05026       }
05027       if (ast_channel_masquerade(p->subs[SUB_REAL].owner, ast_bridged_channel(p->subs[SUB_THREEWAY].owner))) {
05028          ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
05029                ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->name, p->subs[SUB_REAL].owner->name);
05030          return -1;
05031       }
05032       /* Three-way is now the REAL */
05033       swap_subs(p, SUB_THREEWAY, SUB_REAL);
05034       ast_mutex_unlock(&p->subs[SUB_REAL].owner->lock);
05035       unalloc_sub(p, SUB_THREEWAY);
05036       /* Tell the caller not to hangup */
05037       return 1;
05038    } else {
05039       ast_log(LOG_DEBUG, "Neither %s nor %s are in a bridge, nothing to transfer\n",
05040                p->subs[SUB_REAL].owner->name, p->subs[SUB_THREEWAY].owner->name);
05041       return -1;
05042    }
05043    return 0;
05044 }
05045 
05046 static int check_for_conference(struct dahdi_pvt *p)
05047 {
05048    struct dahdi_confinfo ci;
05049    /* Fine if we already have a master, etc */
05050    if (p->master || (p->confno > -1))
05051       return 0;
05052    memset(&ci, 0, sizeof(ci));
05053    if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_GETCONF, &ci)) {
05054       ast_log(LOG_WARNING, "Failed to get conference info on channel %d: %s\n", p->channel, strerror(errno));
05055       return 0;
05056    }
05057    /* If we have no master and don't have a confno, then 
05058       if we're in a conference, it's probably a MeetMe room or
05059       some such, so don't let us 3-way out! */
05060    if ((p->subs[SUB_REAL].curconf.confno != ci.confno) || (p->subs[SUB_REAL].curconf.confmode != ci.confmode)) {
05061       if (option_verbose > 2) 
05062          ast_verbose(VERBOSE_PREFIX_3 "Avoiding 3-way call when in an external conference\n");
05063       return 1;
05064    }
05065    return 0;
05066 }
05067 
05068 static int get_alarms(struct dahdi_pvt *p)
05069 {
05070    int res;
05071    struct dahdi_spaninfo zi;
05072 #if !defined(HAVE_ZAPTEL) || defined(HAVE_ZAPTEL_CHANALARMS)
05073    /*
05074     * The conditional compilation is needed only in asterisk-1.4 for
05075     * backward compatibility with old zaptel drivers that don't have
05076     * a DAHDI_PARAMS.chan_alarms field.
05077     */
05078    struct dahdi_params params;
05079 #endif
05080 
05081    memset(&zi, 0, sizeof(zi));
05082    zi.spanno = p->span;
05083 
05084    /* First check for span alarms */
05085    if((res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SPANSTAT, &zi)) < 0) {
05086       ast_log(LOG_WARNING, "Unable to determine alarm on channel %d: %s\n", p->channel, strerror(errno));
05087       return 0;
05088    }
05089    if (zi.alarms != DAHDI_ALARM_NONE)
05090       return zi.alarms;
05091 #if !defined(HAVE_ZAPTEL) || defined(HAVE_ZAPTEL_CHANALARMS)
05092    /* No alarms on the span. Check for channel alarms. */
05093    memset(&params, 0, sizeof(params));
05094    if ((res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &params)) >= 0)
05095       return params.chan_alarms;
05096    /* ioctl failed */
05097    ast_log(LOG_WARNING, "Unable to determine alarm on channel %d\n", p->channel);
05098 #endif
05099    return DAHDI_ALARM_NONE;
05100 }
05101 
05102 static void dahdi_handle_dtmf(struct ast_channel *ast, int index, struct ast_frame **dest)
05103 {
05104    struct dahdi_pvt *p = ast->tech_pvt;
05105    struct ast_frame *f = *dest;
05106 
05107    if (option_debug)
05108       ast_log(LOG_DEBUG, "%s DTMF digit: 0x%02X '%c' on %s\n",
05109          f->frametype == AST_FRAME_DTMF_BEGIN ? "Begin" : "End",
05110          f->subclass, f->subclass, ast->name);
05111 
05112    if (p->confirmanswer) {
05113       if (f->frametype == AST_FRAME_DTMF_END) {
05114          if (option_debug)
05115             ast_log(LOG_DEBUG, "Confirm answer on %s!\n", ast->name);
05116          /* Upon receiving a DTMF digit, consider this an answer confirmation instead
05117             of a DTMF digit */
05118          p->subs[index].f.frametype = AST_FRAME_CONTROL;
05119          p->subs[index].f.subclass = AST_CONTROL_ANSWER;
05120          /* Reset confirmanswer so DTMF's will behave properly for the duration of the call */
05121          p->confirmanswer = 0;
05122       } else {
05123          p->subs[index].f.frametype = AST_FRAME_NULL;
05124          p->subs[index].f.subclass = 0;
05125       }
05126       *dest = &p->subs[index].f;
05127    } else if (p->callwaitcas) {
05128       if (f->frametype == AST_FRAME_DTMF_END) {
05129          if ((f->subclass == 'A') || (f->subclass == 'D')) {
05130             if (option_debug)
05131                ast_log(LOG_DEBUG, "Got some DTMF, but it's for the CAS\n");
05132             free(p->cidspill);
05133             p->cidspill = NULL;
05134             send_cwcidspill(p);
05135          }
05136          if ((f->subclass != 'm') && (f->subclass != 'u')) 
05137             p->callwaitcas = 0;
05138       }
05139       p->subs[index].f.frametype = AST_FRAME_NULL;
05140       p->subs[index].f.subclass = 0;
05141       *dest = &p->subs[index].f;
05142    } else if (f->subclass == 'f') {
05143       if (f->frametype == AST_FRAME_DTMF_END) {
05144          /* Fax tone -- Handle and return NULL */
05145          if ((p->callprogress & 0x6) && !p->faxhandled) {
05146             p->faxhandled = 1;
05147             if (strcmp(ast->exten, "fax")) {
05148                const char *target_context = S_OR(ast->macrocontext, ast->context);
05149 
05150                /* We need to unlock 'ast' here because ast_exists_extension has the
05151                 * potential to start autoservice on the channel. Such action is prone
05152                 * to deadlock.
05153                 */
05154                ast_mutex_unlock(&p->lock);
05155                ast_channel_unlock(ast);
05156                if (ast_exists_extension(ast, target_context, "fax", 1, ast->cid.cid_num)) {
05157                   ast_channel_lock(ast);
05158                   ast_mutex_lock(&p->lock);
05159                   if (option_verbose > 2)
05160                      ast_verbose(VERBOSE_PREFIX_3 "Redirecting %s to fax extension\n", ast->name);
05161                   /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */
05162                   pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast->exten);
05163                   if (ast_async_goto(ast, target_context, "fax", 1))
05164                      ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, target_context);
05165                } else {
05166                   ast_channel_lock(ast);
05167                   ast_mutex_lock(&p->lock);
05168                   ast_log(LOG_NOTICE, "Fax detected, but no fax extension\n");
05169                }
05170             } else if (option_debug)
05171                ast_log(LOG_DEBUG, "Already in a fax extension, not redirecting\n");
05172          } else if (option_debug)
05173             ast_log(LOG_DEBUG, "Fax already handled\n");
05174          dahdi_confmute(p, 0);
05175       }
05176       p->subs[index].f.frametype = AST_FRAME_NULL;
05177       p->subs[index].f.subclass = 0;
05178       *dest = &p->subs[index].f;
05179    } else if (f->subclass == 'm') {
05180       if (f->frametype == AST_FRAME_DTMF_END) {
05181          /* Confmute request */
05182          dahdi_confmute(p, 1);
05183       }
05184       p->subs[index].f.frametype = AST_FRAME_NULL;
05185       p->subs[index].f.subclass = 0;
05186       *dest = &p->subs[index].f;    
05187    } else if (f->subclass == 'u') {
05188       if (f->frametype == AST_FRAME_DTMF_END) {
05189          /* Unmute */
05190          dahdi_confmute(p, 0);
05191       }
05192       p->subs[index].f.frametype = AST_FRAME_NULL;
05193       p->subs[index].f.subclass = 0;
05194       *dest = &p->subs[index].f;    
05195    } else {
05196       if (f->frametype == AST_FRAME_DTMF_END) {
05197          dahdi_confmute(p, 0);
05198       }
05199    }
05200 }
05201          
05202 static void handle_alarms(struct dahdi_pvt *p, int alarms)
05203 {
05204    const char *alarm_str = alarm2str(alarms);
05205    
05206    /* hack alert! Zaptel 1.4 and DAHDI expose FXO battery as an alarm, but this code
05207     * doesn't know what to do with it.  Don't confuse users with log messages. */
05208    if (!strcasecmp(alarm_str, "No Alarm") || !strcasecmp(alarm_str, "Unknown Alarm")) {
05209       p->unknown_alarm = 1;
05210       return;
05211    } else {
05212       p->unknown_alarm = 0;
05213    }
05214    
05215    ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", p->channel, alarm_str);
05216    manager_event(EVENT_FLAG_SYSTEM, "Alarm",
05217             "Alarm: %s\r\n"
05218             "Channel: %d\r\n",
05219             alarm_str, p->channel);
05220 }
05221 
05222 static struct ast_frame *dahdi_handle_event(struct ast_channel *ast)
05223 {
05224    int res, x;
05225    int index, mysig;
05226    char *c;
05227    struct dahdi_pvt *p = ast->tech_pvt;
05228    pthread_t threadid;
05229    pthread_attr_t attr;
05230    struct ast_channel *chan;
05231    struct ast_frame *f;
05232 
05233    index = dahdi_get_index(ast, p, 0);
05234    if (index < 0) {
05235       return &ast_null_frame;
05236    }
05237    if (index != SUB_REAL) {
05238       ast_log(LOG_ERROR, "We got an event on a non real sub.  Fix it!\n");
05239    }
05240 
05241    mysig = p->sig;
05242    if (p->outsigmod > -1)
05243       mysig = p->outsigmod;
05244 
05245    p->subs[index].f.frametype = AST_FRAME_NULL;
05246    p->subs[index].f.subclass = 0;
05247    p->subs[index].f.datalen = 0;
05248    p->subs[index].f.samples = 0;
05249    p->subs[index].f.mallocd = 0;
05250    p->subs[index].f.offset = 0;
05251    p->subs[index].f.src = "dahdi_handle_event";
05252    p->subs[index].f.data = NULL;
05253    f = &p->subs[index].f;
05254 
05255    if (p->fake_event) {
05256       res = p->fake_event;
05257       p->fake_event = 0;
05258    } else
05259       res = dahdi_get_event(p->subs[index].dfd);
05260 
05261    if (option_debug)
05262       ast_log(LOG_DEBUG, "Got event %s(%d) on channel %d (index %d)\n", event2str(res), res, p->channel, index);
05263 
05264    if (res & (DAHDI_EVENT_PULSEDIGIT | DAHDI_EVENT_DTMFUP)) {
05265       p->pulsedial =  (res & DAHDI_EVENT_PULSEDIGIT) ? 1 : 0;
05266 
05267       ast_log(LOG_DEBUG, "Detected %sdigit '%c'\n", p->pulsedial ? "pulse ": "", res & 0xff);
05268 #ifdef HAVE_PRI
05269       if (p->sig == SIG_PRI
05270          && p->call_level < DAHDI_CALL_LEVEL_PROCEEDING
05271          && p->pri
05272          && (p->pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)) {
05273          /* absorb event */
05274       } else
05275 #endif
05276       {
05277          p->subs[index].f.frametype = AST_FRAME_DTMF_END;
05278          p->subs[index].f.subclass = res & 0xff;
05279          dahdi_handle_dtmf(ast, index, &f);
05280       }
05281       return f;
05282    }
05283 
05284    if (res & DAHDI_EVENT_DTMFDOWN) {
05285       if (option_debug)
05286          ast_log(LOG_DEBUG, "DTMF Down '%c'\n", res & 0xff);
05287 #ifdef HAVE_PRI
05288       if (p->sig == SIG_PRI
05289          && p->call_level < DAHDI_CALL_LEVEL_PROCEEDING
05290          && p->pri
05291          && (p->pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)) {
05292          /* absorb event */
05293       } else
05294 #endif
05295       {
05296          /* Mute conference */
05297          dahdi_confmute(p, 1);
05298          p->subs[index].f.frametype = AST_FRAME_DTMF_BEGIN;
05299          p->subs[index].f.subclass = res & 0xff;
05300          dahdi_handle_dtmf(ast, index, &f);
05301       }
05302       return &p->subs[index].f;
05303    }
05304 
05305    switch (res) {
05306 #ifdef DAHDI_EVENT_EC_DISABLED
05307       case DAHDI_EVENT_EC_DISABLED:
05308          if (option_verbose > 2) 
05309             ast_verbose(VERBOSE_PREFIX_3 "Channel %d echo canceler disabled due to CED detection\n", p->channel);
05310          p->echocanon = 0;
05311          break;
05312 #endif
05313       case DAHDI_EVENT_BITSCHANGED:
05314 #ifdef HAVE_OPENR2
05315          if (p->sig != SIG_MFCR2) {
05316             ast_log(LOG_WARNING, "Recieved bits changed on %s signalling?\n", sig2str(p->sig));
05317          } else {
05318             ast_log(LOG_DEBUG, "bits changed in chan %d\n", p->channel);
05319             openr2_chan_handle_cas(p->r2chan);
05320          }
05321 #else
05322          ast_log(LOG_WARNING, "Received bits changed on %s signalling?\n", sig2str(p->sig));
05323 #endif
05324       case DAHDI_EVENT_PULSE_START:
05325          /* Stop tone if there's a pulse start and the PBX isn't started */
05326          if (!ast->pbx)
05327             tone_zone_play_tone(p->subs[index].dfd, -1);
05328          break;   
05329       case DAHDI_EVENT_DIALCOMPLETE:
05330 #ifdef HAVE_OPENR2
05331          if ((p->sig & SIG_MFCR2) && p->r2chan && ast->_state != AST_STATE_UP) {
05332             /* we don't need to do anything for this event for R2 signaling 
05333                if the call is being setup */
05334             break;
05335          }
05336 #endif
05337          if (p->inalarm) break;
05338          if ((p->radio || (p->oprmode < 0))) break;
05339          if (ioctl(p->subs[index].dfd,DAHDI_DIALING,&x) == -1) {
05340             ast_log(LOG_DEBUG, "DAHDI_DIALING ioctl failed on %s: %s\n",ast->name, strerror(errno));
05341             return NULL;
05342          }
05343          if (!x) { /* if not still dialing in driver */
05344             dahdi_enable_ec(p);
05345             if (p->echobreak) {
05346                dahdi_train_ec(p);
05347                ast_copy_string(p->dop.dialstr, p->echorest, sizeof(p->dop.dialstr));
05348                p->dop.op = DAHDI_DIAL_OP_REPLACE;
05349                res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_DIAL, &p->dop);
05350                p->echobreak = 0;
05351             } else {
05352                p->dialing = 0;
05353                if ((mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF)) {
05354                   /* if thru with dialing after offhook */
05355                   if (ast->_state == AST_STATE_DIALING_OFFHOOK) {
05356                      ast_setstate(ast, AST_STATE_UP);
05357                      p->subs[index].f.frametype = AST_FRAME_CONTROL;
05358                      p->subs[index].f.subclass = AST_CONTROL_ANSWER;
05359                      break;
05360                   } else { /* if to state wait for offhook to dial rest */
05361                      /* we now wait for off hook */
05362                      ast_setstate(ast,AST_STATE_DIALING_OFFHOOK);
05363                   }
05364                }
05365                if (ast->_state == AST_STATE_DIALING) {
05366                   if ((p->callprogress & 1) && CANPROGRESSDETECT(p) && p->dsp && p->outgoing) {
05367                      ast_log(LOG_DEBUG, "Done dialing, but waiting for progress detection before doing more...\n");
05368                   } else if (p->confirmanswer || (!p->dialednone && ((mysig == SIG_EM) || (mysig == SIG_EM_E1) ||  (mysig == SIG_EMWINK) || (mysig == SIG_FEATD) || (mysig == SIG_FEATDMF_TA) || (mysig == SIG_FEATDMF) || (mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF) || (mysig == SIG_FEATB) || (mysig == SIG_SF) || (mysig == SIG_SFWINK) || (mysig == SIG_SF_FEATD) || (mysig == SIG_SF_FEATDMF) || (mysig == SIG_SF_FEATB)))) {
05369                      ast_setstate(ast, AST_STATE_RINGING);
05370                   } else if (!p->answeronpolarityswitch) {
05371                      ast_setstate(ast, AST_STATE_UP);
05372                      p->subs[index].f.frametype = AST_FRAME_CONTROL;
05373                      p->subs[index].f.subclass = AST_CONTROL_ANSWER;
05374                      /* If aops=0 and hops=1, this is necessary */
05375                      p->polarity = POLARITY_REV;
05376                   } else {
05377                      /* Start clean, so we can catch the change to REV polarity when party answers */
05378                      p->polarity = POLARITY_IDLE;
05379                   }
05380                }
05381             }
05382          }
05383          break;
05384       case DAHDI_EVENT_ALARM:
05385 #ifdef HAVE_PRI
05386          if (!p->pri || !p->pri->pri || (pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0)) {
05387             /* T309 is not enabled : destroy calls when alarm occurs */
05388             if (p->call) {
05389                if (p->pri && p->pri->pri) {
05390                   pri_grab(p, p->pri);
05391                   pri_destroycall(p->pri->pri, p->call);
05392                   p->call = NULL;
05393                   pri_rel(p->pri);
05394                } else
05395                   ast_log(LOG_WARNING, "The PRI Call has not been destroyed\n");
05396             }
05397             if (p->owner)
05398                p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
05399          }
05400          if (p->bearer) {
05401             p->bearer->inalarm = 1;
05402             p->bearer->resetting = 0;
05403          } else
05404 #endif
05405          {
05406             p->inalarm = 1;
05407 #if defined(HAVE_PRI)
05408             p->resetting = 0;
05409 #endif   /* defined(HAVE_PRI) */
05410          }
05411          res = get_alarms(p);
05412          handle_alarms(p, res);
05413 #ifdef HAVE_PRI
05414          if (!p->pri || !p->pri->pri || pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0) {
05415             /* fall through intentionally */
05416          } else {
05417             break;
05418          }
05419 #endif
05420 
05421 #ifdef HAVE_OPENR2
05422          if (p->sig == SIG_MFCR2)
05423             break;
05424 #endif
05425 
05426       case DAHDI_EVENT_ONHOOK:
05427          if (p->radio) {
05428             p->subs[index].f.frametype = AST_FRAME_CONTROL;
05429             p->subs[index].f.subclass = AST_CONTROL_RADIO_UNKEY;
05430             break;
05431          }
05432          if (p->oprmode < 0)
05433          {
05434             if (p->oprmode != -1) break;
05435             if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS))
05436             {
05437                /* Make sure it starts ringing */
05438                dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_RINGOFF);
05439                dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_RING);
05440                save_conference(p->oprpeer);
05441                tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].dfd, DAHDI_TONE_RINGTONE);
05442             }
05443             break;
05444          }
05445          switch (p->sig) {
05446          case SIG_FXOLS:
05447          case SIG_FXOGS:
05448          case SIG_FXOKS:
05449             p->onhooktime = time(NULL);
05450             p->msgstate = -1;
05451             /* Check for some special conditions regarding call waiting */
05452             if (index == SUB_REAL) {
05453                /* The normal line was hung up */
05454                if (p->subs[SUB_CALLWAIT].owner) {
05455                   /* Need to hold the lock for real-call, private, and call-waiting call */
05456                   dahdi_lock_sub_owner(p, SUB_CALLWAIT);
05457                   if (!p->subs[SUB_CALLWAIT].owner) {
05458                      /*
05459                       * The call waiting call dissappeared.
05460                       * This is now a normal hangup.
05461                       */
05462                      dahdi_disable_ec(p);
05463                      return NULL;
05464                   }
05465 
05466                   /* There's a call waiting call, so ring the phone, but make it unowned in the mean time */
05467                   swap_subs(p, SUB_CALLWAIT, SUB_REAL);
05468                   if (option_verbose > 2) 
05469                      ast_verbose(VERBOSE_PREFIX_3 "Channel %d still has (callwait) call, ringing phone\n", p->channel);
05470                   unalloc_sub(p, SUB_CALLWAIT); 
05471 #if 0
05472                   p->subs[index].needanswer = 0;
05473                   p->subs[index].needringing = 0;
05474 #endif                  
05475                   p->callwaitingrepeat = 0;
05476                   p->cidcwexpire = 0;
05477                   p->cid_suppress_expire = 0;
05478                   p->owner = NULL;
05479                   /* Don't start streaming audio yet if the incoming call isn't up yet */
05480                   if (p->subs[SUB_REAL].owner->_state != AST_STATE_UP)
05481                      p->dialing = 1;
05482                   /* Unlock the call-waiting call that we swapped to real-call. */
05483                   ast_mutex_unlock(&p->subs[SUB_REAL].owner->lock);
05484                   dahdi_ring_phone(p);
05485                } else if (p->subs[SUB_THREEWAY].owner) {
05486                   unsigned int mssinceflash;
05487 
05488                   /* Need to hold the lock for real-call, private, and 3-way call */
05489                   dahdi_lock_sub_owner(p, SUB_THREEWAY);
05490                   if (!p->subs[SUB_THREEWAY].owner) {
05491                      ast_log(LOG_NOTICE, "Whoa, threeway disappeared kinda randomly.\n");
05492                      /* Just hangup */
05493                      return NULL;
05494                   }
05495                   if (p->owner != ast) {
05496                      ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
05497                      ast_log(LOG_WARNING, "This isn't good...\n");
05498                      /* Just hangup */
05499                      return NULL;
05500                   }
05501 
05502                   mssinceflash = ast_tvdiff_ms(ast_tvnow(), p->flashtime);
05503                   ast_log(LOG_DEBUG, "Last flash was %d ms ago\n", mssinceflash);
05504                   if (mssinceflash < MIN_MS_SINCE_FLASH) {
05505                      /* It hasn't been long enough since the last flashook.  This is probably a bounce on 
05506                         hanging up.  Hangup both channels now */
05507                      ast_log(LOG_DEBUG, "Looks like a bounced flash, hanging up both calls on %d\n", p->channel);
05508                      ast_queue_hangup(p->subs[SUB_THREEWAY].owner);
05509                      p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
05510                      ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
05511                   } else if ((ast->pbx) || (ast->_state == AST_STATE_UP)) {
05512                      if (p->transfer) {
05513                         /* In any case this isn't a threeway call anymore */
05514                         p->subs[SUB_REAL].inthreeway = 0;
05515                         p->subs[SUB_THREEWAY].inthreeway = 0;
05516                         /* Only attempt transfer if the phone is ringing; why transfer to busy tone eh? */
05517                         if (!p->transfertobusy && ast->_state == AST_STATE_BUSY) {
05518                            /* Swap subs and dis-own channel */
05519                            swap_subs(p, SUB_THREEWAY, SUB_REAL);
05520                            /* Unlock the 3-way call that we swapped to real-call. */
05521                            ast_mutex_unlock(&p->subs[SUB_REAL].owner->lock);
05522                            p->owner = NULL;
05523                            /* Ring the phone */
05524                            dahdi_ring_phone(p);
05525                         } else {
05526                            res = attempt_transfer(p);
05527                            if (res < 0) {
05528                               /* Transfer attempt failed. */
05529                               p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
05530                               ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
05531                            } else if (res) {
05532                               /* Don't actually hang up at this point */
05533                               break;
05534                            }
05535                         }
05536                      } else {
05537                         p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
05538                         ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
05539                      }
05540                   } else {
05541                      /* Swap subs and dis-own channel */
05542                      swap_subs(p, SUB_THREEWAY, SUB_REAL);
05543                      /* Unlock the 3-way call that we swapped to real-call. */
05544                      ast_mutex_unlock(&p->subs[SUB_REAL].owner->lock);
05545                      p->owner = NULL;
05546                      /* Ring the phone */
05547                      dahdi_ring_phone(p);
05548                   }
05549                }
05550             } else {
05551                ast_log(LOG_WARNING, "Got a hangup and my index is %d?\n", index);
05552             }
05553             /* Fall through */
05554          default:
05555             dahdi_disable_ec(p);
05556             return NULL;
05557          }
05558          break;
05559       case DAHDI_EVENT_RINGOFFHOOK:
05560          if (p->inalarm) break;
05561          if (p->oprmode < 0)
05562          {
05563             if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS))
05564             {
05565                /* Make sure it stops ringing */
05566                dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_RINGOFF);
05567                tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].dfd, -1);
05568                restore_conference(p->oprpeer);
05569             }
05570             break;
05571          }
05572          if (p->radio)
05573          {
05574             p->subs[index].f.frametype = AST_FRAME_CONTROL;
05575             p->subs[index].f.subclass = AST_CONTROL_RADIO_KEY;
05576             break;
05577          }
05578          /* for E911, its supposed to wait for offhook then dial
05579             the second half of the dial string */
05580          if (((mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF)) && (ast->_state == AST_STATE_DIALING_OFFHOOK)) {
05581             c = strchr(p->dialdest, '/');
05582             if (c)
05583                c++;
05584             else
05585                c = p->dialdest;
05586             if (*c) snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*0%s#", c);
05587             else ast_copy_string(p->dop.dialstr,"M*2#", sizeof(p->dop.dialstr));
05588             if (strlen(p->dop.dialstr) > 4) {
05589                memset(p->echorest, 'w', sizeof(p->echorest) - 1);
05590                strcpy(p->echorest + (p->echotraining / 401) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2);
05591                p->echorest[sizeof(p->echorest) - 1] = '\0';
05592                p->echobreak = 1;
05593                p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0';
05594             } else
05595                p->echobreak = 0;
05596             if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_DIAL, &p->dop)) {
05597                int saveerr = errno;
05598 
05599                x = DAHDI_ONHOOK;
05600                ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x);
05601                ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(saveerr));
05602                return NULL;
05603                }
05604             p->dialing = 1;
05605             return &p->subs[index].f;
05606          }
05607          switch (p->sig) {
05608          case SIG_FXOLS:
05609          case SIG_FXOGS:
05610          case SIG_FXOKS:
05611             switch (ast->_state) {
05612             case AST_STATE_RINGING:
05613                dahdi_enable_ec(p);
05614                dahdi_train_ec(p);
05615                p->subs[index].f.frametype = AST_FRAME_CONTROL;
05616                p->subs[index].f.subclass = AST_CONTROL_ANSWER;
05617                /* Make sure it stops ringing */
05618                dahdi_set_hook(p->subs[index].dfd, DAHDI_OFFHOOK);
05619                p->subs[SUB_REAL].needringing = 0;
05620                ast_log(LOG_DEBUG, "channel %d answered\n", p->channel);
05621 
05622                /* Cancel any running CallerID spill */
05623                free(p->cidspill);
05624                p->cidspill = NULL;
05625                restore_conference(p);
05626 
05627                p->dialing = 0;
05628                p->callwaitcas = 0;
05629                if (p->confirmanswer) {
05630                   /* Ignore answer if "confirm answer" is enabled */
05631                   p->subs[index].f.frametype = AST_FRAME_NULL;
05632                   p->subs[index].f.subclass = 0;
05633                } else if (!ast_strlen_zero(p->dop.dialstr)) {
05634                   /* nick@dccinc.com 4/3/03 - fxo should be able to do deferred dialing */
05635                   res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_DIAL, &p->dop);
05636                   if (res < 0) {
05637                      ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d: %s\n", p->channel, strerror(errno));
05638                      p->dop.dialstr[0] = '\0';
05639                      return NULL;
05640                   } else {
05641                      ast_log(LOG_DEBUG, "Sent FXO deferred digit string: %s\n", p->dop.dialstr);
05642                      p->subs[index].f.frametype = AST_FRAME_NULL;
05643                      p->subs[index].f.subclass = 0;
05644                      p->dialing = 1;
05645                   }
05646                   p->dop.dialstr[0] = '\0';
05647                   ast_setstate(ast, AST_STATE_DIALING);
05648                } else
05649                   ast_setstate(ast, AST_STATE_UP);
05650                return &p->subs[index].f;
05651             case AST_STATE_DOWN:
05652                ast_setstate(ast, AST_STATE_RING);
05653                ast->rings = 1;
05654                p->subs[index].f.frametype = AST_FRAME_CONTROL;
05655                p->subs[index].f.subclass = AST_CONTROL_OFFHOOK;
05656                ast_log(LOG_DEBUG, "channel %d picked up\n", p->channel);
05657                return &p->subs[index].f;
05658             case AST_STATE_UP:
05659                /* Make sure it stops ringing */
05660                dahdi_set_hook(p->subs[index].dfd, DAHDI_OFFHOOK);
05661                /* Okay -- probably call waiting*/
05662                if (ast_bridged_channel(p->owner))
05663                   ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
05664                p->subs[index].needunhold = 1;
05665                break;
05666             case AST_STATE_RESERVED:
05667                /* Start up dialtone */
05668                if (has_voicemail(p))
05669                   res = tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_STUTTER);
05670                else
05671                   res = tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_DIALTONE);
05672                break;
05673             default:
05674                ast_log(LOG_WARNING, "FXO phone off hook in weird state %d??\n", ast->_state);
05675             }
05676             break;
05677          case SIG_FXSLS:
05678          case SIG_FXSGS:
05679          case SIG_FXSKS:
05680             if (ast->_state == AST_STATE_RING) {
05681                p->ringt = p->ringt_base;
05682             }
05683 
05684             /* Fall through */
05685          case SIG_EM:
05686          case SIG_EM_E1:
05687          case SIG_EMWINK:
05688          case SIG_FEATD:
05689          case SIG_FEATDMF:
05690          case SIG_FEATDMF_TA:
05691          case SIG_E911:
05692          case SIG_FGC_CAMA:
05693          case SIG_FGC_CAMAMF:
05694          case SIG_FEATB:
05695          case SIG_SF:
05696          case SIG_SFWINK:
05697          case SIG_SF_FEATD:
05698          case SIG_SF_FEATDMF:
05699          case SIG_SF_FEATB:
05700             if (ast->_state == AST_STATE_PRERING)
05701                ast_setstate(ast, AST_STATE_RING);
05702             if ((ast->_state == AST_STATE_DOWN) || (ast->_state == AST_STATE_RING)) {
05703                if (option_debug)
05704                   ast_log(LOG_DEBUG, "Ring detected\n");
05705                p->subs[index].f.frametype = AST_FRAME_CONTROL;
05706                p->subs[index].f.subclass = AST_CONTROL_RING;
05707             } else if (p->outgoing && ((ast->_state == AST_STATE_RINGING) || (ast->_state == AST_STATE_DIALING))) {
05708                if (option_debug)
05709                   ast_log(LOG_DEBUG, "Line answered\n");
05710                if (p->confirmanswer) {
05711                   p->subs[index].f.frametype = AST_FRAME_NULL;
05712                   p->subs[index].f.subclass = 0;
05713                } else {
05714                   p->subs[index].f.frametype = AST_FRAME_CONTROL;
05715                   p->subs[index].f.subclass = AST_CONTROL_ANSWER;
05716                   ast_setstate(ast, AST_STATE_UP);
05717                }
05718             } else if (ast->_state != AST_STATE_RING)
05719                ast_log(LOG_WARNING, "Ring/Off-hook in strange state %d on channel %d\n", ast->_state, p->channel);
05720             break;
05721          default:
05722             ast_log(LOG_WARNING, "Don't know how to handle ring/off hook for signalling %d\n", p->sig);
05723          }
05724          break;
05725 #ifdef DAHDI_EVENT_RINGBEGIN
05726       case DAHDI_EVENT_RINGBEGIN:
05727          switch (p->sig) {
05728          case SIG_FXSLS:
05729          case SIG_FXSGS:
05730          case SIG_FXSKS:
05731             if (ast->_state == AST_STATE_RING) {
05732                p->ringt = p->ringt_base;
05733             }
05734             break;
05735          }
05736          break;
05737 #endif         
05738       case DAHDI_EVENT_RINGEROFF:
05739          if (p->inalarm) break;
05740          if ((p->radio || (p->oprmode < 0))) break;
05741          ast->rings++;
05742          if ((ast->rings > p->cidrings) && (p->cidspill)) {
05743             ast_log(LOG_WARNING, "Didn't finish Caller-ID spill.  Cancelling.\n");
05744             free(p->cidspill);
05745             p->cidspill = NULL;
05746             p->callwaitcas = 0;
05747          }
05748          p->subs[index].f.frametype = AST_FRAME_CONTROL;
05749          p->subs[index].f.subclass = AST_CONTROL_RINGING;
05750          break;
05751       case DAHDI_EVENT_RINGERON:
05752          break;
05753       case DAHDI_EVENT_NOALARM:
05754          p->inalarm = 0;
05755 #ifdef HAVE_PRI
05756          p->resetting = 0;
05757          /* Extremely unlikely but just in case */
05758          if (p->bearer) {
05759             p->bearer->inalarm = 0;
05760             p->bearer->resetting = 0;
05761          }
05762 #endif            
05763          if (!p->unknown_alarm) {
05764             ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", p->channel);
05765             manager_event(EVENT_FLAG_SYSTEM, "AlarmClear",
05766                "Channel: %d\r\n", p->channel);
05767          } else {
05768             p->unknown_alarm = 0;
05769          }
05770          break;
05771       case DAHDI_EVENT_WINKFLASH:
05772          if (p->inalarm) break;
05773          if (p->radio) break;
05774          if (p->oprmode < 0) break;
05775          if (p->oprmode > 1)
05776          {
05777             struct dahdi_params par;
05778 
05779             memset(&par, 0, sizeof(par));
05780             if (ioctl(p->oprpeer->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &par) != -1)
05781             {
05782                if (!par.rxisoffhook)
05783                {
05784                   /* Make sure it stops ringing */
05785                   dahdi_set_hook(p->oprpeer->subs[SUB_REAL].dfd, DAHDI_RINGOFF);
05786                   dahdi_set_hook(p->oprpeer->subs[SUB_REAL].dfd, DAHDI_RING);
05787                   save_conference(p);
05788                   tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_RINGTONE);
05789                }
05790             }
05791             break;
05792          }
05793          /* Remember last time we got a flash-hook */
05794          gettimeofday(&p->flashtime, NULL);
05795          switch (mysig) {
05796          case SIG_FXOLS:
05797          case SIG_FXOGS:
05798          case SIG_FXOKS:
05799             ast_log(LOG_DEBUG, "Winkflash, index: %d, normal: %d, callwait: %d, thirdcall: %d\n",
05800                index, p->subs[SUB_REAL].dfd, p->subs[SUB_CALLWAIT].dfd, p->subs[SUB_THREEWAY].dfd);
05801 
05802             /* Cancel any running CallerID spill */
05803             free(p->cidspill);
05804             p->cidspill = NULL;
05805             restore_conference(p);
05806             p->callwaitcas = 0;
05807 
05808             if (index != SUB_REAL) {
05809                ast_log(LOG_WARNING, "Got flash hook with index %d on channel %d?!?\n", index, p->channel);
05810                goto winkflashdone;
05811             }
05812             
05813             if (p->subs[SUB_CALLWAIT].owner) {
05814                /* Need to hold the lock for real-call, private, and call-waiting call */
05815                dahdi_lock_sub_owner(p, SUB_CALLWAIT);
05816                if (!p->subs[SUB_CALLWAIT].owner) {
05817                   /*
05818                    * The call waiting call dissappeared.
05819                    * Let's just ignore this flash-hook.
05820                    */
05821                   ast_log(LOG_NOTICE, "Whoa, the call-waiting call disappeared.\n");
05822                   goto winkflashdone;
05823                }
05824 
05825                /* Swap to call-wait */
05826                swap_subs(p, SUB_REAL, SUB_CALLWAIT);
05827                tone_zone_play_tone(p->subs[SUB_REAL].dfd, -1);
05828                p->owner = p->subs[SUB_REAL].owner;
05829                ast_log(LOG_DEBUG, "Making %s the new owner\n", p->owner->name);
05830                if (p->owner->_state == AST_STATE_RINGING) {
05831                   ast_setstate(p->owner, AST_STATE_UP);
05832                   p->subs[SUB_REAL].needanswer = 1;
05833                }
05834                p->callwaitingrepeat = 0;
05835                p->cidcwexpire = 0;
05836                p->cid_suppress_expire = 0;
05837 
05838                /* Start music on hold if appropriate */
05839                if (!p->subs[SUB_CALLWAIT].inthreeway && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner)) {
05840                   ast_queue_control_data(p->subs[SUB_CALLWAIT].owner, AST_CONTROL_HOLD,
05841                      S_OR(p->mohsuggest, NULL),
05842                      !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
05843                }
05844                p->subs[SUB_CALLWAIT].needhold = 1;
05845                if (ast_bridged_channel(p->subs[SUB_REAL].owner)) {
05846                   ast_queue_control_data(p->subs[SUB_REAL].owner, AST_CONTROL_HOLD,
05847                      S_OR(p->mohsuggest, NULL),
05848                      !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
05849                }
05850                p->subs[SUB_REAL].needunhold = 1;
05851 
05852                /* Unlock the call-waiting call that we swapped to real-call. */
05853                ast_mutex_unlock(&p->subs[SUB_REAL].owner->lock);
05854             } else if (!p->subs[SUB_THREEWAY].owner) {
05855                if (!p->threewaycalling) {
05856                   /* Just send a flash if no 3-way calling */
05857                   p->subs[SUB_REAL].needflash = 1;
05858                   goto winkflashdone;
05859                } else if (!check_for_conference(p)) {
05860                   char cid_num[256];
05861                   char cid_name[256];
05862 
05863                   cid_num[0] = 0;
05864                   cid_name[0] = 0;
05865                   if (p->dahditrcallerid && p->owner) {
05866                      if (p->owner->cid.cid_num)
05867                         ast_copy_string(cid_num, p->owner->cid.cid_num, sizeof(cid_num));
05868                      if (p->owner->cid.cid_name)
05869                         ast_copy_string(cid_name, p->owner->cid.cid_name, sizeof(cid_name));
05870                   }
05871                   /* XXX This section needs much more error checking!!! XXX */
05872                   /* Start a 3-way call if feasible */
05873                   if (!((ast->pbx) ||
05874                         (ast->_state == AST_STATE_UP) ||
05875                         (ast->_state == AST_STATE_RING))) {
05876                      ast_log(LOG_DEBUG, "Flash when call not up or ringing\n");
05877                         goto winkflashdone;
05878                   }
05879                   if (alloc_sub(p, SUB_THREEWAY)) {
05880                      ast_log(LOG_WARNING, "Unable to allocate three-way subchannel\n");
05881                      goto winkflashdone;
05882                   }
05883                   /* Make new channel */
05884                   chan = dahdi_new(p, AST_STATE_RESERVED, 0, SUB_THREEWAY, 0, 0);
05885                   if (!chan) {
05886                      ast_log(LOG_WARNING,
05887                         "Cannot allocate new call structure on channel %d\n",
05888                         p->channel);
05889                      unalloc_sub(p, SUB_THREEWAY);
05890                      goto winkflashdone;
05891                   }
05892                   if (p->dahditrcallerid) {
05893                      if (!p->origcid_num)
05894                         p->origcid_num = ast_strdup(p->cid_num);
05895                      if (!p->origcid_name)
05896                         p->origcid_name = ast_strdup(p->cid_name);
05897                      ast_copy_string(p->cid_num, cid_num, sizeof(p->cid_num));
05898                      ast_copy_string(p->cid_name, cid_name, sizeof(p->cid_name));
05899                   }
05900                   /* Swap things around between the three-way and real call */
05901                   swap_subs(p, SUB_THREEWAY, SUB_REAL);
05902                   /* Disable echo canceller for better dialing */
05903                   dahdi_disable_ec(p);
05904                   res = tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_DIALRECALL);
05905                   if (res)
05906                      ast_log(LOG_WARNING, "Unable to start dial recall tone on channel %d\n", p->channel);
05907                   p->owner = chan;
05908                   pthread_attr_init(&attr);
05909                   pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
05910                   if (ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
05911                      ast_log(LOG_WARNING, "Unable to start simple switch on channel %d\n", p->channel);
05912                      res = tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION);
05913                      dahdi_enable_ec(p);
05914                      ast_hangup(chan);
05915                   } else {
05916                      if (option_verbose > 2) 
05917                         ast_verbose(VERBOSE_PREFIX_3 "Started three way call on channel %d\n", p->channel);
05918                      /* Start music on hold if appropriate */
05919                      if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
05920                         ast_queue_control_data(p->subs[SUB_THREEWAY].owner, AST_CONTROL_HOLD,
05921                            S_OR(p->mohsuggest, NULL),
05922                            !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
05923                      }
05924                      p->subs[SUB_THREEWAY].needhold = 1;
05925                   }
05926                   pthread_attr_destroy(&attr);
05927                }
05928             } else {
05929                /* Already have a 3 way call */
05930                int orig_3way_sub;
05931 
05932                /* Need to hold the lock for real-call, private, and 3-way call */
05933                dahdi_lock_sub_owner(p, SUB_THREEWAY);
05934                if (!p->subs[SUB_THREEWAY].owner) {
05935                   /*
05936                    * The 3-way call dissappeared.
05937                    * Let's just ignore this flash-hook.
05938                    */
05939                   ast_log(LOG_NOTICE, "Whoa, the 3-way call disappeared.\n");
05940                   goto winkflashdone;
05941                }
05942                orig_3way_sub = SUB_THREEWAY;
05943 
05944                if (p->subs[SUB_THREEWAY].inthreeway) {
05945                   /* Call is already up, drop the last person */
05946                   if (option_debug)
05947                      ast_log(LOG_DEBUG, "Got flash with three way call up, dropping last call on %d\n", p->channel);
05948                   /* If the primary call isn't answered yet, use it */
05949                   if ((p->subs[SUB_REAL].owner->_state != AST_STATE_UP) && (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_UP)) {
05950                      /* Swap back -- we're dropping the real 3-way that isn't finished yet*/
05951                      swap_subs(p, SUB_THREEWAY, SUB_REAL);
05952                      orig_3way_sub = SUB_REAL;
05953                      p->owner = p->subs[SUB_REAL].owner;
05954                   }
05955                   /* Drop the last call and stop the conference */
05956                   if (option_verbose > 2)
05957                      ast_verbose(VERBOSE_PREFIX_3 "Dropping three-way call on %s\n", p->subs[SUB_THREEWAY].owner->name);
05958                   p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
05959                   p->subs[SUB_REAL].inthreeway = 0;
05960                   p->subs[SUB_THREEWAY].inthreeway = 0;
05961                } else {
05962                   /* Lets see what we're up to */
05963                   if (((ast->pbx) || (ast->_state == AST_STATE_UP)) && 
05964                       (p->transfertobusy || (ast->_state != AST_STATE_BUSY))) {
05965                      if (option_verbose > 2) {
05966                         ast_verbose(VERBOSE_PREFIX_3 "Building conference call with %s and %s\n",
05967                            p->subs[SUB_THREEWAY].owner->name,
05968                            p->subs[SUB_REAL].owner->name);
05969                      }
05970                      /* Put them in the threeway, and flip */
05971                      p->subs[SUB_THREEWAY].inthreeway = 1;
05972                      p->subs[SUB_REAL].inthreeway = 1;
05973                      if (ast->_state == AST_STATE_UP) {
05974                         swap_subs(p, SUB_THREEWAY, SUB_REAL);
05975                         orig_3way_sub = SUB_REAL;
05976                      }
05977                      if (ast_bridged_channel(p->subs[orig_3way_sub].owner)) {
05978                         ast_queue_control(p->subs[orig_3way_sub].owner, AST_CONTROL_UNHOLD);
05979                      }
05980                      p->subs[orig_3way_sub].needunhold = 1;
05981                      p->owner = p->subs[SUB_REAL].owner;
05982                   } else {
05983                      if (option_verbose > 2)
05984                         ast_verbose(VERBOSE_PREFIX_3 "Dumping incomplete call on %s\n", p->subs[SUB_THREEWAY].owner->name);
05985                      swap_subs(p, SUB_THREEWAY, SUB_REAL);
05986                      orig_3way_sub = SUB_REAL;
05987                      p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
05988                      p->owner = p->subs[SUB_REAL].owner;
05989                      if (ast_bridged_channel(p->subs[SUB_REAL].owner)) {
05990                         ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
05991                      }
05992                      p->subs[SUB_REAL].needunhold = 1;
05993                      dahdi_enable_ec(p);
05994                   }
05995                      
05996                }
05997                ast_mutex_unlock(&p->subs[orig_3way_sub].owner->lock);
05998             }
05999 winkflashdone:
06000             update_conf(p);
06001             break;
06002          case SIG_EM:
06003          case SIG_EM_E1:
06004          case SIG_FEATD:
06005          case SIG_SF:
06006          case SIG_SFWINK:
06007          case SIG_SF_FEATD:
06008          case SIG_FXSLS:
06009          case SIG_FXSGS:
06010             if (p->dialing)
06011                ast_log(LOG_DEBUG, "Ignoring wink on channel %d\n", p->channel);
06012             else
06013                ast_log(LOG_DEBUG, "Got wink in weird state %d on channel %d\n", ast->_state, p->channel);
06014             break;
06015          case SIG_FEATDMF_TA:
06016             switch (p->whichwink) {
06017             case 0:
06018                ast_log(LOG_DEBUG, "ANI2 set to '%d' and ANI is '%s'\n", p->owner->cid.cid_ani2, p->owner->cid.cid_ani);
06019                snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%d%s#", p->owner->cid.cid_ani2, p->owner->cid.cid_ani);
06020                break;
06021             case 1:
06022                ast_copy_string(p->dop.dialstr, p->finaldial, sizeof(p->dop.dialstr));
06023                break;
06024             case 2:
06025                ast_log(LOG_WARNING, "Received unexpected wink on channel of type SIG_FEATDMF_TA\n");
06026                return NULL;
06027             }
06028             p->whichwink++;
06029             /* Fall through */
06030          case SIG_FEATDMF:
06031          case SIG_E911:
06032          case SIG_FGC_CAMAMF:
06033          case SIG_FGC_CAMA:
06034          case SIG_FEATB:
06035          case SIG_SF_FEATDMF:
06036          case SIG_SF_FEATB:
06037          case SIG_EMWINK:
06038             /* FGD MF and EMWINK *Must* wait for wink */
06039             if (!ast_strlen_zero(p->dop.dialstr)) {
06040                res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_DIAL, &p->dop);
06041                if (res < 0) {
06042                   ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d: %s\n", p->channel, strerror(errno));
06043                   p->dop.dialstr[0] = '\0';
06044                   return NULL;
06045                } else 
06046                   ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", p->dop.dialstr);
06047             }
06048             p->dop.dialstr[0] = '\0';
06049             break;
06050          default:
06051             ast_log(LOG_WARNING, "Don't know how to handle ring/off hoook for signalling %d\n", p->sig);
06052          }
06053          break;
06054       case DAHDI_EVENT_HOOKCOMPLETE:
06055          if (p->inalarm) break;
06056          if ((p->radio || (p->oprmode < 0))) break;
06057          switch (mysig) {
06058          case SIG_FXSLS:  /* only interesting for FXS */
06059          case SIG_FXSGS:
06060          case SIG_FXSKS:
06061          case SIG_EM:
06062          case SIG_EM_E1:
06063          case SIG_EMWINK:
06064          case SIG_FEATD:
06065          case SIG_SF:
06066          case SIG_SFWINK:
06067          case SIG_SF_FEATD:
06068             if (!ast_strlen_zero(p->dop.dialstr)) {
06069                res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_DIAL, &p->dop);
06070                if (res < 0) {
06071                   ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d: %s\n", p->channel, strerror(errno));
06072                   p->dop.dialstr[0] = '\0';
06073                   return NULL;
06074                } else 
06075                   ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", p->dop.dialstr);
06076             }
06077             p->dop.dialstr[0] = '\0';
06078             p->dop.op = DAHDI_DIAL_OP_REPLACE;
06079             break;
06080          case SIG_FEATDMF:
06081          case SIG_FEATDMF_TA:
06082          case SIG_E911:
06083          case SIG_FGC_CAMA:
06084          case SIG_FGC_CAMAMF:
06085          case SIG_FEATB:
06086          case SIG_SF_FEATDMF:
06087          case SIG_SF_FEATB:
06088             ast_log(LOG_DEBUG, "Got hook complete in MF FGD, waiting for wink now on channel %d\n",p->channel);
06089             break;
06090          default:
06091             break;
06092          }
06093          break;
06094       case DAHDI_EVENT_POLARITY:
06095          /*
06096           * If we get a Polarity Switch event, check to see
06097           * if we should change the polarity state and
06098           * mark the channel as UP or if this is an indication
06099           * of remote end disconnect.
06100           */
06101          if (p->polarity == POLARITY_IDLE) {
06102             p->polarity = POLARITY_REV;
06103             if (p->answeronpolarityswitch &&
06104                 ((ast->_state == AST_STATE_DIALING) ||
06105                 (ast->_state == AST_STATE_RINGING))) {
06106                ast_log(LOG_DEBUG, "Answering on polarity switch!\n");
06107                ast_setstate(p->owner, AST_STATE_UP);
06108                if (p->hanguponpolarityswitch) {
06109                   gettimeofday(&p->polaritydelaytv, NULL);
06110                }
06111             } else
06112                ast_log(LOG_DEBUG, "Ignore switch to REVERSED Polarity on channel %d, state %d\n", p->channel, ast->_state);
06113          } 
06114          /* Removed else statement from here as it was preventing hangups from ever happening*/
06115          /* Added AST_STATE_RING in if statement below to deal with calling party hangups that take place when ringing */
06116          if (p->hanguponpolarityswitch &&
06117             (p->polarityonanswerdelay > 0) &&
06118                 (p->polarity == POLARITY_REV) &&
06119             ((ast->_state == AST_STATE_UP) || (ast->_state == AST_STATE_RING)) ) {
06120                                 /* Added log_debug information below to provide a better indication of what is going on */
06121             ast_log(LOG_DEBUG, "Polarity Reversal event occured - DEBUG 1: channel %d, state %d, pol= %d, aonp= %d, honp= %d, pdelay= %d, tv= %d\n", p->channel, ast->_state, p->polarity, p->answeronpolarityswitch, p->hanguponpolarityswitch, p->polarityonanswerdelay, ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) );
06122          
06123             if (ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) > p->polarityonanswerdelay) {
06124                ast_log(LOG_DEBUG, "Polarity Reversal detected and now Hanging up on channel %d\n", p->channel);
06125                ast_softhangup(p->owner, AST_SOFTHANGUP_EXPLICIT);
06126                p->polarity = POLARITY_IDLE;
06127             } else {
06128                ast_log(LOG_DEBUG, "Polarity Reversal detected but NOT hanging up (too close to answer event) on channel %d, state %d\n", p->channel, ast->_state);
06129             }
06130          } else {
06131             p->polarity = POLARITY_IDLE;
06132             ast_log(LOG_DEBUG, "Ignoring Polarity switch to IDLE on channel %d, state %d\n", p->channel, ast->_state);
06133          }
06134                         /* Added more log_debug information below to provide a better indication of what is going on */
06135          ast_log(LOG_DEBUG, "Polarity Reversal event occured - DEBUG 2: channel %d, state %d, pol= %d, aonp= %d, honp= %d, pdelay= %d, tv= %d\n", p->channel, ast->_state, p->polarity, p->answeronpolarityswitch, p->hanguponpolarityswitch, p->polarityonanswerdelay, ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) );
06136          break;
06137       default:
06138          ast_log(LOG_DEBUG, "Dunno what to do with event %d on channel %d\n", res, p->channel);
06139    }
06140    return &p->subs[index].f;
06141 }
06142 
06143 static struct ast_frame *__dahdi_exception(struct ast_channel *ast)
06144 {
06145    struct dahdi_pvt *p = ast->tech_pvt;
06146    int res;
06147    int index;
06148    struct ast_frame *f;
06149 
06150 
06151    index = dahdi_get_index(ast, p, 1);
06152    if (index < 0) {
06153       index = SUB_REAL;
06154    }
06155    
06156    p->subs[index].f.frametype = AST_FRAME_NULL;
06157    p->subs[index].f.datalen = 0;
06158    p->subs[index].f.samples = 0;
06159    p->subs[index].f.mallocd = 0;
06160    p->subs[index].f.offset = 0;
06161    p->subs[index].f.subclass = 0;
06162    p->subs[index].f.delivery = ast_tv(0,0);
06163    p->subs[index].f.src = "dahdi_exception";
06164    p->subs[index].f.data = NULL;
06165    
06166    if ((!p->owner) && (!(p->radio || (p->oprmode < 0)))) {
06167       /* If nobody owns us, absorb the event appropriately, otherwise
06168          we loop indefinitely.  This occurs when, during call waiting, the
06169          other end hangs up our channel so that it no longer exists, but we
06170          have neither FLASH'd nor ONHOOK'd to signify our desire to
06171          change to the other channel. */
06172       if (p->fake_event) {
06173          res = p->fake_event;
06174          p->fake_event = 0;
06175       } else
06176          res = dahdi_get_event(p->subs[SUB_REAL].dfd);
06177       /* Switch to real if there is one and this isn't something really silly... */
06178       if ((res != DAHDI_EVENT_RINGEROFF) && (res != DAHDI_EVENT_RINGERON) &&
06179          (res != DAHDI_EVENT_HOOKCOMPLETE)) {
06180          ast_log(LOG_DEBUG, "Restoring owner of channel %d on event %d\n", p->channel, res);
06181          p->owner = p->subs[SUB_REAL].owner;
06182          if (p->owner && ast != p->owner) {
06183             /*
06184              * Could this even happen?
06185              * Possible deadlock because we do not have the real-call lock.
06186              */
06187             ast_log(LOG_WARNING, "Event %s on %s is not restored owner %s\n",
06188                event2str(res), ast->name, p->owner->name);
06189          }
06190          if (p->owner && ast_bridged_channel(p->owner))
06191             ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
06192          p->subs[SUB_REAL].needunhold = 1;
06193       }
06194       switch (res) {
06195       case DAHDI_EVENT_ONHOOK:
06196          dahdi_disable_ec(p);
06197          if (p->owner) {
06198             if (option_verbose > 2) 
06199                ast_verbose(VERBOSE_PREFIX_3 "Channel %s still has call, ringing phone\n", p->owner->name);
06200             dahdi_ring_phone(p);
06201             p->callwaitingrepeat = 0;
06202             p->cidcwexpire = 0;
06203             p->cid_suppress_expire = 0;
06204          } else {
06205             ast_log(LOG_WARNING, "Absorbed %s, but nobody is left!?!?\n",
06206                event2str(res));
06207          }
06208          update_conf(p);
06209          break;
06210       case DAHDI_EVENT_RINGOFFHOOK:
06211          dahdi_enable_ec(p);
06212          dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_OFFHOOK);
06213          if (p->owner && (p->owner->_state == AST_STATE_RINGING)) {
06214             p->subs[SUB_REAL].needanswer = 1;
06215             p->dialing = 0;
06216          }
06217          break;
06218       case DAHDI_EVENT_HOOKCOMPLETE:
06219       case DAHDI_EVENT_RINGERON:
06220       case DAHDI_EVENT_RINGEROFF:
06221          /* Do nothing */
06222          break;
06223       case DAHDI_EVENT_WINKFLASH:
06224          gettimeofday(&p->flashtime, NULL);
06225          if (p->owner) {
06226             if (option_verbose > 2) 
06227                ast_verbose(VERBOSE_PREFIX_3 "Channel %d flashed to other channel %s\n", p->channel, p->owner->name);
06228             if (p->owner->_state != AST_STATE_UP) {
06229                /* Answer if necessary */
06230                p->subs[SUB_REAL].needanswer = 1;
06231                ast_setstate(p->owner, AST_STATE_UP);
06232             }
06233             p->callwaitingrepeat = 0;
06234             p->cidcwexpire = 0;
06235             p->cid_suppress_expire = 0;
06236             if (ast_bridged_channel(p->owner))
06237                ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
06238             p->subs[SUB_REAL].needunhold = 1;
06239          } else {
06240             ast_log(LOG_WARNING, "Absorbed %s, but nobody is left!?!?\n",
06241                event2str(res));
06242          }
06243          update_conf(p);
06244          break;
06245       default:
06246          ast_log(LOG_WARNING, "Don't know how to absorb event %s\n", event2str(res));
06247          break;
06248       }
06249       f = &p->subs[index].f;
06250       return f;
06251    }
06252    if (!(p->radio || (p->oprmode < 0)) && option_debug) 
06253       ast_log(LOG_DEBUG, "Exception on %d, channel %d\n", ast->fds[0],p->channel);
06254    /* If it's not us, return NULL immediately */
06255    if (ast != p->owner) {
06256       ast_log(LOG_WARNING, "We're %s, not %s\n", ast->name, p->owner->name);
06257       f = &p->subs[index].f;
06258       return f;
06259    }
06260    f = dahdi_handle_event(ast);
06261    return f;
06262 }
06263 
06264 static struct ast_frame *dahdi_exception(struct ast_channel *ast)
06265 {
06266    struct dahdi_pvt *p = ast->tech_pvt;
06267    struct ast_frame *f;
06268    ast_mutex_lock(&p->lock);
06269    f = __dahdi_exception(ast);
06270    ast_mutex_unlock(&p->lock);
06271    return f;
06272 }
06273 
06274 static struct ast_frame  *dahdi_read(struct ast_channel *ast)
06275 {
06276    struct dahdi_pvt *p;
06277    int res;
06278    int index;
06279    void *readbuf;
06280    struct ast_frame *f;
06281 
06282    /*
06283     * For analog channels, we must do deadlock avoidance because
06284     * analog ports can have more than one Asterisk channel using
06285     * the same private structure.
06286     */
06287    p = ast->tech_pvt;
06288    while (ast_mutex_trylock(&p->lock)) {
06289       DEADLOCK_AVOIDANCE(&ast->lock);
06290 
06291       /*
06292        * For PRI channels, we must refresh the private pointer because
06293        * the call could move to another B channel while the Asterisk
06294        * channel is unlocked.
06295        */
06296       p = ast->tech_pvt;
06297    }
06298 
06299    index = dahdi_get_index(ast, p, 0);
06300    
06301    /* Hang up if we don't really exist */
06302    if (index < 0) {
06303       ast_log(LOG_WARNING, "We don't exist?\n");
06304       ast_mutex_unlock(&p->lock);
06305       return NULL;
06306    }
06307    
06308    if ((p->radio || (p->oprmode < 0)) && p->inalarm) {
06309       ast_mutex_unlock(&p->lock);
06310       return NULL;
06311    }
06312 
06313    p->subs[index].f.frametype = AST_FRAME_NULL;
06314    p->subs[index].f.datalen = 0;
06315    p->subs[index].f.samples = 0;
06316    p->subs[index].f.mallocd = 0;
06317    p->subs[index].f.offset = 0;
06318    p->subs[index].f.subclass = 0;
06319    p->subs[index].f.delivery = ast_tv(0,0);
06320    p->subs[index].f.src = "dahdi_read";
06321    p->subs[index].f.data = NULL;
06322    
06323    /* make sure it sends initial key state as first frame */
06324    if ((p->radio || (p->oprmode < 0)) && (!p->firstradio))
06325    {
06326       struct dahdi_params ps;
06327 
06328       memset(&ps, 0, sizeof(ps));
06329       ps.channo = p->channel;
06330       if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &ps) < 0) {
06331          ast_mutex_unlock(&p->lock);
06332          return NULL;
06333       }
06334       p->firstradio = 1;
06335       p->subs[index].f.frametype = AST_FRAME_CONTROL;
06336       if (ps.rxisoffhook)
06337       {
06338          p->subs[index].f.subclass = AST_CONTROL_RADIO_KEY;
06339       }
06340       else
06341       {
06342          p->subs[index].f.subclass = AST_CONTROL_RADIO_UNKEY;
06343       }
06344       ast_mutex_unlock(&p->lock);
06345       return &p->subs[index].f;
06346    }
06347    if (p->ringt == 1) {
06348       ast_mutex_unlock(&p->lock);
06349       return NULL;
06350    }
06351    else if (p->ringt > 0) 
06352       p->ringt--;
06353 
06354 #ifdef HAVE_OPENR2
06355    if (p->mfcr2) {
06356       openr2_chan_process_event(p->r2chan);
06357    }  
06358 #endif
06359    
06360    if (p->subs[index].needringing) {
06361       /* Send ringing frame if requested */
06362       p->subs[index].needringing = 0;
06363       p->subs[index].f.frametype = AST_FRAME_CONTROL;
06364       p->subs[index].f.subclass = AST_CONTROL_RINGING;
06365       ast_setstate(ast, AST_STATE_RINGING);
06366       ast_mutex_unlock(&p->lock);
06367       return &p->subs[index].f;
06368    }
06369 
06370    if (p->subs[index].needbusy) {
06371       /* Send busy frame if requested */
06372       p->subs[index].needbusy = 0;
06373       p->subs[index].f.frametype = AST_FRAME_CONTROL;
06374       p->subs[index].f.subclass = AST_CONTROL_BUSY;
06375       ast_mutex_unlock(&p->lock);
06376       return &p->subs[index].f;
06377    }
06378 
06379    if (p->subs[index].needcongestion) {
06380       /* Send congestion frame if requested */
06381       p->subs[index].needcongestion = 0;
06382       p->subs[index].f.frametype = AST_FRAME_CONTROL;
06383       p->subs[index].f.subclass = AST_CONTROL_CONGESTION;
06384       ast_mutex_unlock(&p->lock);
06385       return &p->subs[index].f;
06386    }
06387 
06388    if (p->subs[index].needcallerid && !ast->cid.cid_tns) {
06389       ast_set_callerid(ast, S_OR(p->lastcid_num, NULL),
06390                      S_OR(p->lastcid_name, NULL),
06391                      S_OR(p->lastcid_num, NULL)
06392                      );
06393       p->subs[index].needcallerid = 0;
06394    }
06395    
06396    if (p->subs[index].needanswer) {
06397       /* Send answer frame if requested */
06398       p->subs[index].needanswer = 0;
06399       p->subs[index].f.frametype = AST_FRAME_CONTROL;
06400       p->subs[index].f.subclass = AST_CONTROL_ANSWER;
06401       ast_mutex_unlock(&p->lock);
06402       return &p->subs[index].f;
06403    }  
06404 
06405 #ifdef HAVE_OPENR2
06406    if (p->mfcr2 && openr2_chan_get_read_enabled(p->r2chan)) {
06407       /* openr2 took care of reading and handling any event 
06408         (needanswer, needbusy etc), if we continue we will read()
06409         twice, lets just return a null frame. This should only
06410         happen when openr2 is dialing out */
06411       p->subs[index].f.frametype = AST_FRAME_NULL;
06412       p->subs[index].f.subclass = 0;
06413       p->subs[index].f.samples = 0;
06414       p->subs[index].f.mallocd = 0;
06415       p->subs[index].f.offset = 0;
06416       p->subs[index].f.data = NULL;
06417       p->subs[index].f.datalen= 0;
06418       ast_mutex_unlock(&p->lock);
06419       return &p->subs[index].f;
06420    }
06421 #endif
06422 
06423    if (p->subs[index].needflash) {
06424       /* Send answer frame if requested */
06425       p->subs[index].needflash = 0;
06426       p->subs[index].f.frametype = AST_FRAME_CONTROL;
06427       p->subs[index].f.subclass = AST_CONTROL_FLASH;
06428       ast_mutex_unlock(&p->lock);
06429       return &p->subs[index].f;
06430    }  
06431    
06432    if (p->subs[index].needhold) {
06433       /* Send answer frame if requested */
06434       p->subs[index].needhold = 0;
06435       p->subs[index].f.frametype = AST_FRAME_CONTROL;
06436       p->subs[index].f.subclass = AST_CONTROL_HOLD;
06437       ast_mutex_unlock(&p->lock);
06438       ast_log(LOG_DEBUG, "Sending hold on '%s'\n", ast->name);
06439       return &p->subs[index].f;
06440    }  
06441    
06442    if (p->subs[index].needunhold) {
06443       /* Send answer frame if requested */
06444       p->subs[index].needunhold = 0;
06445       p->subs[index].f.frametype = AST_FRAME_CONTROL;
06446       p->subs[index].f.subclass = AST_CONTROL_UNHOLD;
06447       ast_mutex_unlock(&p->lock);
06448       ast_log(LOG_DEBUG, "Sending unhold on '%s'\n", ast->name);
06449       return &p->subs[index].f;
06450    }  
06451    
06452    if (ast->rawreadformat == AST_FORMAT_SLINEAR) {
06453       if (!p->subs[index].linear) {
06454          p->subs[index].linear = 1;
06455          res = dahdi_setlinear(p->subs[index].dfd, p->subs[index].linear);
06456          if (res) 
06457             ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to linear mode.\n", p->channel, index);
06458       }
06459    } else if ((ast->rawreadformat == AST_FORMAT_ULAW) ||
06460          (ast->rawreadformat == AST_FORMAT_ALAW)) {
06461       if (p->subs[index].linear) {
06462          p->subs[index].linear = 0;
06463          res = dahdi_setlinear(p->subs[index].dfd, p->subs[index].linear);
06464          if (res) 
06465             ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to companded mode.\n", p->channel, index);
06466       }
06467    } else {
06468       ast_log(LOG_WARNING, "Don't know how to read frames in format %s\n", ast_getformatname(ast->rawreadformat));
06469       ast_mutex_unlock(&p->lock);
06470       return NULL;
06471    }
06472    readbuf = ((unsigned char *)p->subs[index].buffer) + AST_FRIENDLY_OFFSET;
06473    CHECK_BLOCKING(ast);
06474    res = read(p->subs[index].dfd, readbuf, p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE);
06475    ast_clear_flag(ast, AST_FLAG_BLOCKING);
06476 
06477       if (p->use_callerid && (ast->_state == AST_STATE_PRERING &&
06478                    (p->cid_start == CID_START_POLARITY || p->cid_start == CID_START_DTMF_NOALERT))) {
06479          //ast_log(LOG_NOTICE, "use_callerid %u, cid_start %i\n", p->use_callerid, p->cid_start);
06480          if (!p->subs[index].linear) {
06481                int x, samplin;
06482                int mean, ssum;
06483                
06484                /* First calc mean signal (DC offset) */
06485                for (x = 0, ssum = 0; x < READ_SIZE; x++) {
06486                      //ssum += (ast->rawreadformat == AST_FORMAT_ULAW ? AST_MULAW((u_char *)readbuf) : AST_ALAW((u_char *)readbuf[x]));
06487                      ssum += AST_MULAW(((u_char *)readbuf)[x]);
06488                      if (option_verbose > 5 && (x % 10 == 0))
06489                            ast_log(LOG_NOTICE, "dahdi_read ssum %i, mean %i \n", ssum, ssum / READ_SIZE);
06490                }
06491                mean = ssum / READ_SIZE;
06492 
06493                if (option_verbose > 5)
06494                      ast_log(LOG_WARNING, "dahdi_read channel %s, mean %i \n", ast->name, mean);
06495                if (ast->rawreadformat == AST_FORMAT_ULAW) {
06496                      for (x = 0; x < READ_SIZE; x++) {
06497                            samplin = AST_MULAW(((u_char *)readbuf)[x]);
06498                            if (option_verbose > 6 && (x % 10 == 0))
06499                                  ast_log(LOG_NOTICE, "dahdi_read,x %i, samporig %i samplin %i, samplinconv %i, xconv %i\n", x, ((u_char *)readbuf)[x], samplin, samplin - mean, AST_LIN2MU(samplin - mean));
06500                            ((u_char *)readbuf)[x] = AST_LIN2MU(samplin - mean);
06501                      }
06502                }
06503          }
06504       }
06505 
06506    /* Check for hangup */
06507    if (res < 0) {
06508       f = NULL;
06509       if (res == -1)  {
06510          if (errno == EAGAIN) {
06511             /* Return "NULL" frame if there is nobody there */
06512             ast_mutex_unlock(&p->lock);
06513             return &p->subs[index].f;
06514          } else if (errno == ELAST) {
06515             f = __dahdi_exception(ast);
06516          } else
06517             ast_log(LOG_WARNING, "dahdi_rec: %s\n", strerror(errno));
06518       }
06519       ast_mutex_unlock(&p->lock);
06520       return f;
06521    }
06522    if (res != (p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE)) {
06523       ast_log(LOG_DEBUG, "Short read (%d/%d), must be an event...\n", res, p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE);
06524       f = __dahdi_exception(ast);
06525       ast_mutex_unlock(&p->lock);
06526       return f;
06527    }
06528    if (p->tdd) { /* if in TDD mode, see if we receive that */
06529       int c;
06530 
06531       c = tdd_feed(p->tdd,readbuf,READ_SIZE);
06532       if (c < 0) {
06533          ast_log(LOG_DEBUG,"tdd_feed failed\n");
06534          ast_mutex_unlock(&p->lock);
06535          return NULL;
06536       }
06537       if (c) { /* if a char to return */
06538          p->subs[index].f.subclass = 0;
06539          p->subs[index].f.frametype = AST_FRAME_TEXT;
06540          p->subs[index].f.mallocd = 0;
06541          p->subs[index].f.offset = AST_FRIENDLY_OFFSET;
06542          p->subs[index].f.data = p->subs[index].buffer + AST_FRIENDLY_OFFSET;
06543          p->subs[index].f.datalen = 1;
06544          *((char *) p->subs[index].f.data) = c;
06545          ast_mutex_unlock(&p->lock);
06546          return &p->subs[index].f;
06547       }
06548    }
06549    if (index == SUB_REAL) {
06550       /* Ensure the CW timers decrement only on a single subchannel */
06551       if (p->cidcwexpire) {
06552          if (!--p->cidcwexpire) {
06553             /* Expired CID/CW */
06554             if (option_verbose > 2)
06555                ast_verbose(VERBOSE_PREFIX_3 "CPE does not support Call Waiting Caller*ID.\n");
06556             restore_conference(p);
06557          }
06558       }
06559       if (p->cid_suppress_expire) {
06560          --p->cid_suppress_expire;
06561       }
06562       if (p->callwaitingrepeat) {
06563          if (!--p->callwaitingrepeat) {
06564             /* Expired, Repeat callwaiting tone */
06565             ++p->callwaitrings;
06566             dahdi_callwait(ast);
06567          }
06568       }
06569    }
06570    if (p->subs[index].linear) {
06571       p->subs[index].f.datalen = READ_SIZE * 2;
06572    } else 
06573       p->subs[index].f.datalen = READ_SIZE;
06574 
06575    /* Handle CallerID Transmission */
06576    if ((p->owner == ast) && p->cidspill &&((ast->_state == AST_STATE_UP) || (ast->rings == p->cidrings))) {
06577       send_callerid(p);
06578    }
06579 
06580    p->subs[index].f.frametype = AST_FRAME_VOICE;
06581    p->subs[index].f.subclass = ast->rawreadformat;
06582    p->subs[index].f.samples = READ_SIZE;
06583    p->subs[index].f.mallocd = 0;
06584    p->subs[index].f.offset = AST_FRIENDLY_OFFSET;
06585    p->subs[index].f.data = p->subs[index].buffer + AST_FRIENDLY_OFFSET / sizeof(p->subs[index].buffer[0]);
06586 #if 0
06587    ast_log(LOG_DEBUG, "Read %d of voice on %s\n", p->subs[index].f.datalen, ast->name);
06588 #endif   
06589    if (p->dialing || /* Transmitting something */
06590       (index && (ast->_state != AST_STATE_UP)) || /* Three-way or callwait that isn't up */
06591       ((index == SUB_CALLWAIT) && !p->subs[SUB_CALLWAIT].inthreeway) /* Inactive and non-confed call-wait */
06592       ) {
06593       /* Whoops, we're still dialing, or in a state where we shouldn't transmit....
06594          don't send anything */
06595       p->subs[index].f.frametype = AST_FRAME_NULL;
06596       p->subs[index].f.subclass = 0;
06597       p->subs[index].f.samples = 0;
06598       p->subs[index].f.mallocd = 0;
06599       p->subs[index].f.offset = 0;
06600       p->subs[index].f.data = NULL;
06601       p->subs[index].f.datalen= 0;
06602    }
06603    if (p->dsp && (!p->ignoredtmf || p->callwaitcas || p->busydetect  || p->callprogress) && !index) {
06604       /* Perform busy detection. etc on the dahdi line */
06605       f = ast_dsp_process(ast, p->dsp, &p->subs[index].f);
06606       if (f) {
06607          if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_BUSY)) {
06608             if ((ast->_state == AST_STATE_UP) && !p->outgoing) {
06609                /* Treat this as a "hangup" instead of a "busy" on the assumption that
06610                   a busy  */
06611                f = NULL;
06612             }
06613          } else if (f->frametype == AST_FRAME_DTMF_BEGIN
06614             || f->frametype == AST_FRAME_DTMF_END) {
06615 #ifdef HAVE_PRI
06616             if (p->sig == SIG_PRI
06617                && p->call_level < DAHDI_CALL_LEVEL_PROCEEDING
06618                && p->pri
06619                && ((!p->outgoing && (p->pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING))
06620                   || (p->outgoing && (p->pri->overlapdial & DAHDI_OVERLAPDIAL_OUTGOING)))) {
06621                /* Don't accept in-band DTMF when in overlap dial mode */
06622                ast_log(LOG_DEBUG,
06623                   "Absorbing inband %s DTMF digit: 0x%02X '%c' on %s\n",
06624                   f->frametype == AST_FRAME_DTMF_BEGIN ? "begin" : "end",
06625                   f->subclass, f->subclass, ast->name);
06626 
06627                f->frametype = AST_FRAME_NULL;
06628                f->subclass = 0;
06629             }
06630 #endif            
06631             /* DSP clears us of being pulse */
06632             p->pulsedial = 0;
06633          }
06634       }
06635    } else 
06636       f = &p->subs[index].f; 
06637 
06638    if (f) {
06639       switch (f->frametype) {
06640       case AST_FRAME_DTMF_BEGIN:
06641       case AST_FRAME_DTMF_END:
06642          dahdi_handle_dtmf(ast, index, &f);
06643          break;
06644       case AST_FRAME_VOICE:
06645          if (p->cidspill || p->cid_suppress_expire) {
06646             /* We are/were sending a caller id spill.  Suppress any echo. */
06647             p->subs[index].f.frametype = AST_FRAME_NULL;
06648             p->subs[index].f.subclass = 0;
06649             p->subs[index].f.samples = 0;
06650             p->subs[index].f.mallocd = 0;
06651             p->subs[index].f.offset = 0;
06652             p->subs[index].f.data = NULL;
06653             p->subs[index].f.datalen= 0;
06654          }
06655          break;
06656       default:
06657          break;
06658       }
06659    }
06660 
06661    /* If we have a fake_event, trigger exception to handle it */
06662    if (p->fake_event)
06663       ast_set_flag(ast, AST_FLAG_EXCEPTION);
06664 
06665    ast_mutex_unlock(&p->lock);
06666    return f;
06667 }
06668 
06669 static int my_dahdi_write(struct dahdi_pvt *p, unsigned char *buf, int len, int index, int linear)
06670 {
06671    int sent=0;
06672    int size;
06673    int res;
06674    int fd;
06675    fd = p->subs[index].dfd;
06676    while (len) {
06677       size = len;
06678       if (size > (linear ? READ_SIZE * 2 : READ_SIZE))
06679          size = (linear ? READ_SIZE * 2 : READ_SIZE);
06680       res = write(fd, buf, size);
06681       if (res != size) {
06682          if (option_debug)
06683             ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
06684          return sent;
06685       }
06686       len -= size;
06687       buf += size;
06688    }
06689    return sent;
06690 }
06691 
06692 static int dahdi_write(struct ast_channel *ast, struct ast_frame *frame)
06693 {
06694    struct dahdi_pvt *p = ast->tech_pvt;
06695    int res;
06696    int index;
06697    index = dahdi_get_index(ast, p, 0);
06698    if (index < 0) {
06699       ast_log(LOG_WARNING, "%s doesn't really exist?\n", ast->name);
06700       return -1;
06701    }
06702 
06703    /* Write a frame of (presumably voice) data */
06704    if (frame->frametype != AST_FRAME_VOICE) {
06705       if (frame->frametype != AST_FRAME_IMAGE)
06706          ast_log(LOG_WARNING, "Don't know what to do with frame type '%d'\n", frame->frametype);
06707       return 0;
06708    }
06709    if ((frame->subclass != AST_FORMAT_SLINEAR) && 
06710        (frame->subclass != AST_FORMAT_ULAW) &&
06711        (frame->subclass != AST_FORMAT_ALAW)) {
06712       ast_log(LOG_WARNING, "Cannot handle frames in %d format\n", frame->subclass);
06713       return -1;
06714    }
06715    if (p->dialing) {
06716       if (option_debug)
06717          ast_log(LOG_DEBUG, "Dropping frame since I'm still dialing on %s...\n",ast->name);
06718       return 0;
06719    }
06720    if (!p->owner) {
06721       if (option_debug)
06722          ast_log(LOG_DEBUG, "Dropping frame since there is no active owner on %s...\n",ast->name);
06723       return 0;
06724    }
06725    if (p->cidspill) {
06726       if (option_debug) {
06727          ast_log(LOG_DEBUG,
06728             "Dropping frame since I've still got a callerid spill on %s...\n",
06729             ast->name);
06730       }
06731       return 0;
06732    }
06733    /* Return if it's not valid data */
06734    if (!frame->data || !frame->datalen)
06735       return 0;
06736 
06737    if (frame->subclass == AST_FORMAT_SLINEAR) {
06738       if (!p->subs[index].linear) {
06739          p->subs[index].linear = 1;
06740          res = dahdi_setlinear(p->subs[index].dfd, p->subs[index].linear);
06741          if (res)
06742             ast_log(LOG_WARNING, "Unable to set linear mode on channel %d\n", p->channel);
06743       }
06744       res = my_dahdi_write(p, (unsigned char *)frame->data, frame->datalen, index, 1);
06745    } else {
06746       /* x-law already */
06747       if (p->subs[index].linear) {
06748          p->subs[index].linear = 0;
06749          res = dahdi_setlinear(p->subs[index].dfd, p->subs[index].linear);
06750          if (res)
06751             ast_log(LOG_WARNING, "Unable to set companded mode on channel %d\n", p->channel);
06752       }
06753       res = my_dahdi_write(p, (unsigned char *)frame->data, frame->datalen, index, 0);
06754    }
06755    if (res < 0) {
06756       ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno));
06757       return -1;
06758    } 
06759    return 0;
06760 }
06761 
06762 static int dahdi_indicate(struct ast_channel *chan, int condition, const void *data, size_t datalen)
06763 {
06764    struct dahdi_pvt *p = chan->tech_pvt;
06765    int res=-1;
06766    int index;
06767    int func = DAHDI_FLASH;
06768    ast_mutex_lock(&p->lock);
06769    index = dahdi_get_index(chan, p, 0);
06770    ast_log(LOG_DEBUG, "Requested indication %d on channel %s\n", condition, chan->name);
06771 #ifdef HAVE_OPENR2
06772    if (p->mfcr2 && !p->mfcr2_call_accepted) {
06773       ast_mutex_unlock(&p->lock);
06774       /* if this an R2 call and the call is not yet accepted we don't want the 
06775          tone indications to mess up with the MF tones */
06776       return 0;
06777    }
06778 #endif
06779    if (index == SUB_REAL) {
06780       switch (condition) {
06781       case AST_CONTROL_BUSY:
06782 #ifdef HAVE_PRI
06783          if (p->sig == SIG_PRI) {
06784             if (p->priindication_oob) {
06785                chan->hangupcause = AST_CAUSE_USER_BUSY;
06786                chan->_softhangup |= AST_SOFTHANGUP_DEV;
06787                res = 0;
06788                break;
06789             }
06790             res = tone_zone_play_tone(p->subs[index].dfd, DAHDI_TONE_BUSY);
06791             if (p->call_level < DAHDI_CALL_LEVEL_ALERTING && !p->outgoing) {
06792                chan->hangupcause = AST_CAUSE_USER_BUSY;
06793                p->progress = 1;/* No need to send plain PROGRESS after this. */
06794                if (p->pri && p->pri->pri) {
06795                   if (!pri_grab(p, p->pri)) {
06796                      pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
06797                      pri_rel(p->pri);
06798                   } else {
06799                      ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
06800                   }
06801                }
06802             }
06803             break;
06804          }
06805 #endif
06806          res = tone_zone_play_tone(p->subs[index].dfd, DAHDI_TONE_BUSY);
06807          break;
06808       case AST_CONTROL_RINGING:
06809 #ifdef HAVE_PRI
06810          if (p->sig == SIG_PRI
06811             && p->call_level < DAHDI_CALL_LEVEL_ALERTING && !p->outgoing) {
06812             p->call_level = DAHDI_CALL_LEVEL_ALERTING;
06813             if (p->pri && p->pri->pri) {
06814                if (!pri_grab(p, p->pri)) {
06815                   pri_acknowledge(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital);
06816                   pri_rel(p->pri);
06817                } else {
06818                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
06819                }
06820             }
06821          }
06822 #endif
06823          res = tone_zone_play_tone(p->subs[index].dfd, DAHDI_TONE_RINGTONE);
06824          if (chan->_state != AST_STATE_UP) {
06825             if ((chan->_state != AST_STATE_RING) ||
06826                ((p->sig != SIG_FXSKS) &&
06827                 (p->sig != SIG_FXSLS) &&
06828                 (p->sig != SIG_FXSGS)))
06829                ast_setstate(chan, AST_STATE_RINGING);
06830          }
06831          break;
06832       case AST_CONTROL_PROCEEDING:
06833          ast_log(LOG_DEBUG,"Received AST_CONTROL_PROCEEDING on %s\n",chan->name);
06834 #ifdef HAVE_PRI
06835          if (p->sig == SIG_PRI
06836             && p->call_level < DAHDI_CALL_LEVEL_PROCEEDING && !p->outgoing) {
06837             p->call_level = DAHDI_CALL_LEVEL_PROCEEDING;
06838             if (p->pri && p->pri->pri) {
06839                if (!pri_grab(p, p->pri)) {
06840                   pri_proceeding(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital);
06841                   pri_rel(p->pri);
06842                } else {
06843                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
06844                }
06845             }
06846             p->dialing = 0;
06847          }
06848 #endif
06849          /* don't continue in ast_indicate */
06850          res = 0;
06851          break;
06852       case AST_CONTROL_PROGRESS:
06853          ast_log(LOG_DEBUG,"Received AST_CONTROL_PROGRESS on %s\n",chan->name);
06854 #ifdef HAVE_PRI
06855          p->digital = 0;   /* Digital-only calls isn't allows any inband progress messages */
06856          if (p->sig == SIG_PRI
06857             && !p->progress && p->call_level < DAHDI_CALL_LEVEL_ALERTING
06858             && !p->outgoing) {
06859             p->progress = 1;/* No need to send plain PROGRESS again. */
06860             if (p->pri && p->pri->pri) {
06861                if (!pri_grab(p, p->pri)) {
06862                   pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
06863                   pri_rel(p->pri);
06864                } else {
06865                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
06866                }
06867             }
06868          }
06869 #endif
06870          /* don't continue in ast_indicate */
06871          res = 0;
06872          break;
06873       case AST_CONTROL_CONGESTION:
06874 #ifdef HAVE_PRI
06875          if (p->sig == SIG_PRI) {
06876             if (p->priindication_oob) {
06877                /* There are many cause codes that generate an AST_CONTROL_CONGESTION. */
06878                switch (chan->hangupcause) {
06879                case AST_CAUSE_USER_BUSY:
06880                case AST_CAUSE_NORMAL_CLEARING:
06881                case 0:/* Cause has not been set. */
06882                   /* Supply a more appropriate cause. */
06883                   chan->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
06884                   break;
06885                default:
06886                   break;
06887                }
06888                chan->_softhangup |= AST_SOFTHANGUP_DEV;
06889                res = 0;
06890                break;
06891             }
06892             res = tone_zone_play_tone(p->subs[index].dfd, DAHDI_TONE_CONGESTION);
06893             if (p->call_level < DAHDI_CALL_LEVEL_ALERTING && !p->outgoing) {
06894                /* There are many cause codes that generate an AST_CONTROL_CONGESTION. */
06895                switch (chan->hangupcause) {
06896                case AST_CAUSE_USER_BUSY:
06897                case AST_CAUSE_NORMAL_CLEARING:
06898                case 0:/* Cause has not been set. */
06899                   /* Supply a more appropriate cause. */
06900                   chan->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
06901                   break;
06902                default:
06903                   break;
06904                }
06905                p->progress = 1;/* No need to send plain PROGRESS after this. */
06906                if (p->pri && p->pri->pri) {
06907                   if (!pri_grab(p, p->pri)) {
06908                      pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
06909                      pri_rel(p->pri);
06910                   } else {
06911                      ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
06912                   }
06913                }
06914             }
06915             break;
06916          }
06917 #endif
06918          /* There are many cause codes that generate an AST_CONTROL_CONGESTION. */
06919          switch (chan->hangupcause) {
06920          case AST_CAUSE_USER_BUSY:
06921          case AST_CAUSE_NORMAL_CLEARING:
06922          case 0:/* Cause has not been set. */
06923             /* Supply a more appropriate cause. */
06924             chan->hangupcause = AST_CAUSE_CONGESTION;
06925             break;
06926          default:
06927             break;
06928          }
06929          res = tone_zone_play_tone(p->subs[index].dfd, DAHDI_TONE_CONGESTION);
06930          break;
06931       case AST_CONTROL_HOLD:
06932 #ifdef HAVE_PRI
06933          if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) {
06934             if (!pri_grab(p, p->pri)) {
06935                res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_HOLD);
06936                pri_rel(p->pri);
06937             } else
06938                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);       
06939          } else
06940 #endif
06941             ast_moh_start(chan, data, p->mohinterpret);
06942          break;
06943       case AST_CONTROL_UNHOLD:
06944 #ifdef HAVE_PRI
06945          if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) {
06946             if (!pri_grab(p, p->pri)) {
06947                res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_RETRIEVAL);
06948                pri_rel(p->pri);
06949             } else
06950                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);       
06951          } else
06952 #endif
06953             ast_moh_stop(chan);
06954          break;
06955       case AST_CONTROL_RADIO_KEY:
06956          if (p->radio) 
06957              res =  dahdi_set_hook(p->subs[index].dfd, DAHDI_OFFHOOK);
06958          res = 0;
06959          break;
06960       case AST_CONTROL_RADIO_UNKEY:
06961          if (p->radio)
06962              res =  dahdi_set_hook(p->subs[index].dfd, DAHDI_RINGOFF);
06963          res = 0;
06964          break;
06965       case AST_CONTROL_FLASH:
06966          /* flash hookswitch */
06967          if (ISTRUNK(p) && (p->sig != SIG_PRI)) {
06968             /* Clear out the dial buffer */
06969             p->dop.dialstr[0] = '\0';
06970             if ((ioctl(p->subs[SUB_REAL].dfd,DAHDI_HOOK,&func) == -1) && (errno != EINPROGRESS)) {
06971                ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n", 
06972                   chan->name, strerror(errno));
06973             } else
06974                res = 0;
06975          } else
06976             res = 0;
06977          break;
06978       case AST_CONTROL_SRCUPDATE:
06979          res = 0;
06980          break;
06981       case -1:
06982          res = tone_zone_play_tone(p->subs[index].dfd, -1);
06983          break;
06984       }
06985    } else
06986       res = 0;
06987    ast_mutex_unlock(&p->lock);
06988    return res;
06989 }
06990 
06991 static struct ast_channel *dahdi_new(struct dahdi_pvt *i, int state, int startpbx, int index, int law, int transfercapability)
06992 {
06993    struct ast_channel *tmp;
06994    int deflaw;
06995    int res;
06996    int x,y;
06997    int features;
06998    char *b2 = NULL;
06999    struct dahdi_params ps;
07000    char chanprefix[*dahdi_chan_name_len + 4];
07001 
07002    if (i->subs[index].owner) {
07003       ast_log(LOG_WARNING, "Channel %d already has a %s call\n", i->channel,subnames[index]);
07004       return NULL;
07005    }
07006    y = 1;
07007    do {
07008       if (b2)
07009          free(b2);
07010 #ifdef HAVE_PRI
07011       if (i->bearer || (i->pri && (i->sig == SIG_FXSKS)))
07012          b2 = ast_safe_string_alloc("%d:%d-%d", i->pri->trunkgroup, i->channel, y);
07013       else
07014 #endif
07015       if (i->channel == CHAN_PSEUDO)
07016          b2 = ast_safe_string_alloc("pseudo-%ld", ast_random());
07017       else  
07018          b2 = ast_safe_string_alloc("%d-%d", i->channel, y);
07019       for (x = 0; x < 3; x++) {
07020          if ((index != x) && i->subs[x].owner && !strcasecmp(b2, i->subs[x].owner->name + (!strncmp(i->subs[x].owner->name, "Zap", 3) ? 4 : 6)))
07021             break;
07022       }
07023       y++;
07024    } while (x < 3);
07025    strcpy(chanprefix, dahdi_chan_name);
07026    strcat(chanprefix, "/%s");
07027    tmp = ast_channel_alloc(0, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, i->amaflags, chanprefix, b2);
07028    if (b2) /*!> b2 can be freed now, it's been copied into the channel structure */
07029       free(b2);
07030    if (!tmp)
07031       return NULL;
07032    tmp->tech = chan_tech;
07033    memset(&ps, 0, sizeof(ps));
07034    ps.channo = i->channel;
07035    res = ioctl(i->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &ps);
07036    if (res) {
07037       ast_log(LOG_WARNING, "Unable to get parameters, assuming MULAW: %s\n", strerror(errno));
07038       ps.curlaw = DAHDI_LAW_MULAW;
07039    }
07040    if (ps.curlaw == DAHDI_LAW_ALAW)
07041       deflaw = AST_FORMAT_ALAW;
07042    else
07043       deflaw = AST_FORMAT_ULAW;
07044    if (law) {
07045       if (law == DAHDI_LAW_ALAW)
07046          deflaw = AST_FORMAT_ALAW;
07047       else
07048          deflaw = AST_FORMAT_ULAW;
07049    }
07050    tmp->fds[0] = i->subs[index].dfd;
07051    tmp->nativeformats = deflaw;
07052    /* Start out assuming ulaw since it's smaller :) */
07053    tmp->rawreadformat = deflaw;
07054    tmp->readformat = deflaw;
07055    tmp->rawwriteformat = deflaw;
07056    tmp->writeformat = deflaw;
07057    i->subs[index].linear = 0;
07058    dahdi_setlinear(i->subs[index].dfd, i->subs[index].linear);
07059    features = 0;
07060    if (index == SUB_REAL) {
07061       if (i->busydetect && CANBUSYDETECT(i))
07062          features |= DSP_FEATURE_BUSY_DETECT;
07063       if ((i->callprogress & 1) && CANPROGRESSDETECT(i))
07064          features |= DSP_FEATURE_CALL_PROGRESS;
07065       if ((!i->outgoing && (i->callprogress & 4)) || 
07066           (i->outgoing && (i->callprogress & 2))) {
07067          features |= DSP_FEATURE_FAX_DETECT;
07068       }
07069 #ifdef DAHDI_TONEDETECT
07070       x = DAHDI_TONEDETECT_ON | DAHDI_TONEDETECT_MUTE;
07071       if (ioctl(i->subs[index].dfd, DAHDI_TONEDETECT, &x)) {
07072 #endif      
07073          i->hardwaredtmf = 0;
07074          features |= DSP_FEATURE_DTMF_DETECT;
07075 #ifdef DAHDI_TONEDETECT
07076       } else if (NEED_MFDETECT(i)) {
07077          i->hardwaredtmf = 1;
07078          features |= DSP_FEATURE_DTMF_DETECT;
07079       }
07080 #endif
07081    }
07082    if (features) {
07083       if (i->dsp) {
07084          ast_log(LOG_DEBUG, "Already have a dsp on %s?\n", tmp->name);
07085       } else {
07086          if (i->channel != CHAN_PSEUDO)
07087             i->dsp = ast_dsp_new();
07088          else
07089             i->dsp = NULL;
07090          if (i->dsp) {
07091             i->dsp_features = features;
07092 #ifdef HAVE_PRI
07093             /* We cannot do progress detection until receives PROGRESS message */
07094             if (i->outgoing && (i->sig == SIG_PRI)) {
07095                /* Remember requested DSP features, don't treat
07096                   talking as ANSWER */
07097                i->dsp_features = features & ~DSP_PROGRESS_TALK;
07098                features = 0;
07099             }
07100 #endif
07101             ast_dsp_set_features(i->dsp, features);
07102             ast_dsp_digitmode(i->dsp, DSP_DIGITMODE_DTMF | i->dtmfrelax);
07103             if (!ast_strlen_zero(progzone))
07104                ast_dsp_set_call_progress_zone(i->dsp, progzone);
07105             if (i->busydetect && CANBUSYDETECT(i)) {
07106                if(i->silencethreshold > 0)
07107                   ast_dsp_set_threshold(i->dsp, i->silencethreshold);
07108                ast_dsp_set_busy_count(i->dsp, i->busycount);
07109                if(i->busytonelength > 0)
07110                   ast_dsp_set_busy_pattern(i->dsp, i->busytonelength, i->busyquietlength, i->busyfuzziness);
07111                if((i->busytonelength == i->busyquietlength) && i->busycompare)
07112                   ast_dsp_set_busy_compare(i->dsp, i->busycompare);
07113             }
07114          }
07115       }
07116    }
07117       
07118    if (state == AST_STATE_RING)
07119       tmp->rings = 1;
07120    tmp->tech_pvt = i;
07121    if ((i->sig == SIG_FXOKS) || (i->sig == SIG_FXOGS) || (i->sig == SIG_FXOLS)) {
07122       /* Only FXO signalled stuff can be picked up */
07123       tmp->callgroup = i->callgroup;
07124       tmp->pickupgroup = i->pickupgroup;
07125    }
07126    if (!ast_strlen_zero(i->language))
07127       ast_string_field_set(tmp, language, i->language);
07128    if (!i->owner)
07129       i->owner = tmp;
07130    if (!ast_strlen_zero(i->accountcode))
07131       ast_string_field_set(tmp, accountcode, i->accountcode);
07132    if (i->amaflags)
07133       tmp->amaflags = i->amaflags;
07134    i->subs[index].owner = tmp;
07135    ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
07136    ast_string_field_set(tmp, call_forward, i->call_forward);
07137    /* If we've been told "no ADSI" then enforce it */
07138    if (!i->adsi)
07139       tmp->adsicpe = AST_ADSI_UNAVAILABLE;
07140    if (!ast_strlen_zero(i->exten))
07141       ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
07142    if (!ast_strlen_zero(i->rdnis))
07143       tmp->cid.cid_rdnis = ast_strdup(i->rdnis);
07144    if (!ast_strlen_zero(i->dnid))
07145       tmp->cid.cid_dnid = ast_strdup(i->dnid);
07146 
07147    /* Don't use ast_set_callerid() here because it will
07148     * generate a needless NewCallerID event */
07149 #ifdef PRI_ANI
07150    if (!ast_strlen_zero(i->cid_ani))
07151       tmp->cid.cid_ani = ast_strdup(i->cid_ani);
07152    else  
07153       tmp->cid.cid_ani = ast_strdup(i->cid_num);
07154 #else
07155    tmp->cid.cid_ani = ast_strdup(i->cid_num);
07156 #endif
07157    tmp->cid.cid_pres = i->callingpres;
07158    tmp->cid.cid_ton = i->cid_ton;
07159 #ifdef HAVE_PRI
07160    tmp->transfercapability = transfercapability;
07161    pbx_builtin_setvar_helper(tmp, "TRANSFERCAPABILITY", ast_transfercapability2str(transfercapability));
07162    if (transfercapability & PRI_TRANS_CAP_DIGITAL)
07163       i->digital = 1;
07164    /* Assume calls are not idle calls unless we're told differently */
07165    i->isidlecall = 0;
07166    i->alreadyhungup = 0;
07167 #endif
07168    /* clear the fake event in case we posted one before we had ast_channel */
07169    i->fake_event = 0;
07170    /* Assure there is no confmute on this channel */
07171    dahdi_confmute(i, 0);
07172    /* Configure the new channel jb */
07173    ast_jb_configure(tmp, &global_jbconf);
07174    if (startpbx) {
07175 
07176 #ifdef HAVE_OPENR2
07177       if (i->mfcr2call) {
07178          pbx_builtin_setvar_helper(tmp, "MFCR2_CATEGORY", openr2_proto_get_category_string(i->mfcr2_recvd_category));
07179       }
07180 #endif
07181 
07182       if (ast_pbx_start(tmp)) {
07183          ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
07184          ast_hangup(tmp);
07185          i->owner = NULL;
07186          return NULL;
07187       }
07188    }
07189 
07190    ast_module_ref(ast_module_info->self);
07191    
07192    return tmp;
07193 }
07194 
07195 
07196 static int my_getsigstr(struct ast_channel *chan, char *str, const char *term, int ms)
07197 {
07198    char c;
07199 
07200    *str = 0; /* start with empty output buffer */
07201    for (;;)
07202    {
07203       /* Wait for the first digit (up to specified ms). */
07204       c = ast_waitfordigit(chan, ms);
07205       /* if timeout, hangup or error, return as such */
07206       if (c < 1)
07207          return c;
07208       *str++ = c;
07209       *str = 0;
07210       if (strchr(term, c))
07211          return 1;
07212    }
07213 }
07214 
07215 static int dahdi_wink(struct dahdi_pvt *p, int index)
07216 {
07217    int j;
07218    dahdi_set_hook(p->subs[index].dfd, DAHDI_WINK);
07219    for (;;)
07220    {
07221          /* set bits of interest */
07222       j = DAHDI_IOMUX_SIGEVENT;
07223           /* wait for some happening */
07224       if (ioctl(p->subs[index].dfd,DAHDI_IOMUX,&j) == -1) return(-1);
07225          /* exit loop if we have it */
07226       if (j & DAHDI_IOMUX_SIGEVENT) break;
07227    }
07228      /* get the event info */
07229    if (ioctl(p->subs[index].dfd,DAHDI_GETEVENT,&j) == -1) return(-1);
07230    return 0;
07231 }
07232 
07233 static void *ss_thread(void *data)
07234 {
07235    struct ast_channel *chan = data;
07236    struct dahdi_pvt *p = chan->tech_pvt;
07237    char exten[AST_MAX_EXTENSION] = "";
07238    char exten2[AST_MAX_EXTENSION] = "";
07239    unsigned char buf[256];
07240    char dtmfcid[300];
07241    char dtmfbuf[300];
07242    struct callerid_state *cs = NULL;
07243    char *name = NULL, *number = NULL;
07244    int distMatches;
07245    int curRingData[3];
07246    int receivedRingT;
07247    int counter1;
07248    int counter;
07249    int samples = 0;
07250    struct ast_smdi_md_message *smdi_msg = NULL;
07251    int flags = 0;
07252    int i;
07253    int timeout;
07254    int getforward = 0;
07255    char *s1, *s2;
07256    int len = 0;
07257    int res;
07258    int index;
07259 
07260    ast_mutex_lock(&ss_thread_lock);
07261    ss_thread_count++;
07262    ast_mutex_unlock(&ss_thread_lock);
07263    /* in the bizarre case where the channel has become a zombie before we
07264       even get started here, abort safely
07265    */
07266    if (!p) {
07267       ast_log(LOG_WARNING, "Channel became a zombie before simple switch could be started (%s)\n", chan->name);
07268       ast_hangup(chan);
07269       goto quit;
07270    }
07271    if (option_verbose > 2) 
07272       ast_verbose( VERBOSE_PREFIX_3 "Starting simple switch on '%s'\n", chan->name);
07273    index = dahdi_get_index(chan, p, 0);
07274    if (index < 0) {
07275       ast_hangup(chan);
07276       goto quit;
07277    }
07278    if (p->dsp)
07279       ast_dsp_digitreset(p->dsp);
07280    switch (p->sig) {
07281 #ifdef HAVE_PRI
07282    case SIG_PRI:
07283       /* Now loop looking for an extension */
07284       ast_copy_string(exten, p->exten, sizeof(exten));
07285       len = strlen(exten);
07286       res = 0;
07287       while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) {
07288          if (len && !ast_ignore_pattern(chan->context, exten))
07289             tone_zone_play_tone(p->subs[index].dfd, -1);
07290          else
07291             tone_zone_play_tone(p->subs[index].dfd, DAHDI_TONE_DIALTONE);
07292          if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num))
07293             timeout = matchdigittimeout;
07294          else
07295             timeout = gendigittimeout;
07296          res = ast_waitfordigit(chan, timeout);
07297          if (res < 0) {
07298             ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n");
07299             ast_hangup(chan);
07300             goto quit;
07301          } else if (res) {
07302             exten[len++] = res;
07303             exten[len] = '\0';
07304          } else
07305             break;
07306       }
07307       /* if no extension was received ('unspecified') on overlap call, use the 's' extension */
07308       if (ast_strlen_zero(exten)) {
07309          if (option_verbose > 2)
07310             ast_verbose(VERBOSE_PREFIX_3 "Going to extension s|1 because of empty extension received on overlap call\n");
07311          exten[0] = 's';
07312          exten[1] = '\0';
07313       }
07314       tone_zone_play_tone(p->subs[index].dfd, -1);
07315       if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num)) {
07316          /* Start the real PBX */
07317          ast_copy_string(chan->exten, exten, sizeof(chan->exten));
07318          if (p->dsp) {
07319             ast_dsp_digitreset(p->dsp);
07320          }
07321 #if defined(ISSUE_16789)
07322          /*
07323           * Conditionaled out this code to effectively revert the Mantis
07324           * issue 16789 change.  It breaks overlap dialing through
07325           * Asterisk.  There is not enough information available at this
07326           * point to know if dialing is complete.  The
07327           * ast_exists_extension(), ast_matchmore_extension(), and
07328           * ast_canmatch_extension() calls are not adequate to detect a
07329           * dial through extension pattern of "_9!".
07330           *
07331           * Workaround is to use the dialplan Proceeding() application
07332           * early on non-dial through extensions.
07333           */
07334          if ((p->pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)
07335             && !ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) {
07336             ast_mutex_lock(&p->lock);
07337             if (p->pri->pri) {
07338                if (!pri_grab(p, p->pri)) {
07339                   if (p->call_level < DAHDI_CALL_LEVEL_PROCEEDING) {
07340                      p->call_level = DAHDI_CALL_LEVEL_PROCEEDING;
07341                   }
07342                   pri_proceeding(p->pri->pri, p->call, PVT_TO_CHANNEL(p), 0);
07343                   pri_rel(p->pri);
07344                } else {
07345                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
07346                }
07347             }
07348             ast_mutex_unlock(&p->lock);
07349          }
07350 #endif   /* defined(ISSUE_16789) */
07351 
07352          dahdi_enable_ec(p);
07353          ast_setstate(chan, AST_STATE_RING);
07354          res = ast_pbx_run(chan);
07355          if (res) {
07356             ast_log(LOG_WARNING, "PBX exited non-zero!\n");
07357          }
07358       } else {
07359          ast_log(LOG_DEBUG, "No such possible extension '%s' in context '%s'\n", exten, chan->context);
07360          chan->hangupcause = AST_CAUSE_UNALLOCATED;
07361          ast_hangup(chan);
07362          p->exten[0] = '\0';
07363          /* Since we send release complete here, we won't get one */
07364          p->call = NULL;
07365       }
07366       goto quit;
07367       break;
07368 #endif
07369    case SIG_FEATD:
07370    case SIG_FEATDMF:
07371    case SIG_FEATDMF_TA:
07372    case SIG_E911:
07373    case SIG_FGC_CAMAMF:
07374    case SIG_FEATB:
07375    case SIG_EMWINK:
07376    case SIG_SF_FEATD:
07377    case SIG_SF_FEATDMF:
07378    case SIG_SF_FEATB:
07379    case SIG_SFWINK:
07380       if (dahdi_wink(p, index))  
07381          goto quit;
07382       /* Fall through */
07383    case SIG_EM:
07384    case SIG_EM_E1:
07385    case SIG_SF:
07386    case SIG_FGC_CAMA:
07387       res = tone_zone_play_tone(p->subs[index].dfd, -1);
07388       if (p->dsp)
07389          ast_dsp_digitreset(p->dsp);
07390       /* set digit mode appropriately */
07391       if (p->dsp) {
07392          if (NEED_MFDETECT(p))
07393             ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MF | p->dtmfrelax); 
07394          else 
07395             ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax);
07396       }
07397       memset(dtmfbuf, 0, sizeof(dtmfbuf));
07398       /* Wait for the first digit only if immediate=no */
07399       if (!p->immediate)
07400          /* Wait for the first digit (up to 5 seconds). */
07401          res = ast_waitfordigit(chan, 5000);
07402       else
07403          res = 0;
07404       if (res > 0) {
07405          /* save first char */
07406          dtmfbuf[0] = res;
07407          switch (p->sig) {
07408          case SIG_FEATD:
07409          case SIG_SF_FEATD:
07410             res = my_getsigstr(chan, dtmfbuf + 1, "*", 3000);
07411             if (res > 0)
07412                res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000);
07413             if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
07414             break;
07415          case SIG_FEATDMF_TA:
07416             res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
07417             if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
07418             if (dahdi_wink(p, index)) goto quit;
07419             dtmfbuf[0] = 0;
07420             /* Wait for the first digit (up to 5 seconds). */
07421             res = ast_waitfordigit(chan, 5000);
07422             if (res <= 0) break;
07423             dtmfbuf[0] = res;
07424             /* fall through intentionally */
07425          case SIG_FEATDMF:
07426          case SIG_E911:
07427          case SIG_FGC_CAMAMF:
07428          case SIG_SF_FEATDMF:
07429             res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
07430             /* if international caca, do it again to get real ANO */
07431             if ((p->sig == SIG_FEATDMF) && (dtmfbuf[1] != '0') && (strlen(dtmfbuf) != 14))
07432             {
07433                if (dahdi_wink(p, index)) goto quit;
07434                dtmfbuf[0] = 0;
07435                /* Wait for the first digit (up to 5 seconds). */
07436                res = ast_waitfordigit(chan, 5000);
07437                if (res <= 0) break;
07438                dtmfbuf[0] = res;
07439                res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
07440             }
07441             if (res > 0) {
07442                /* if E911, take off hook */
07443                if (p->sig == SIG_E911)
07444                   dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_OFFHOOK);
07445                res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "#", 3000);
07446             }
07447             if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
07448             break;
07449          case SIG_FEATB:
07450          case SIG_SF_FEATB:
07451             res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
07452             if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
07453             break;
07454          case SIG_EMWINK:
07455             /* if we received a '*', we are actually receiving Feature Group D
07456                dial syntax, so use that mode; otherwise, fall through to normal
07457                mode
07458             */
07459             if (res == '*') {
07460                res = my_getsigstr(chan, dtmfbuf + 1, "*", 3000);
07461                if (res > 0)
07462                   res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000);
07463                if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
07464                break;
07465             }
07466          default:
07467             /* If we got the first digit, get the rest */
07468             len = 1;
07469             dtmfbuf[len] = '\0';
07470             while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, dtmfbuf, 1, p->cid_num)) {
07471                if (ast_exists_extension(chan, chan->context, dtmfbuf, 1, p->cid_num)) {
07472                   timeout = matchdigittimeout;
07473                } else {
07474                   timeout = gendigittimeout;
07475                }
07476                res = ast_waitfordigit(chan, timeout);
07477                if (res < 0) {
07478                   ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n");
07479                   ast_hangup(chan);
07480                   goto quit;
07481                } else if (res) {
07482                   dtmfbuf[len++] = res;
07483                   dtmfbuf[len] = '\0';
07484                } else {
07485                   break;
07486                }
07487             }
07488             break;
07489          }
07490       }
07491       if (res == -1) {
07492          ast_log(LOG_WARNING, "getdtmf on channel %d: %s\n", p->channel, strerror(errno));
07493          ast_hangup(chan);
07494          goto quit;
07495       } else if (res < 0) {
07496          ast_log(LOG_DEBUG, "Got hung up before digits finished\n");
07497          ast_hangup(chan);
07498          goto quit;
07499       }
07500 
07501       if (p->sig == SIG_FGC_CAMA) {
07502          char anibuf[100];
07503 
07504          if (ast_safe_sleep(chan,1000) == -1) {
07505                            ast_hangup(chan);
07506                            goto quit;
07507          }
07508                         dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_OFFHOOK);
07509                         ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MF | p->dtmfrelax);
07510                         res = my_getsigstr(chan, anibuf, "#", 10000);
07511                         if ((res > 0) && (strlen(anibuf) > 2)) {
07512             if (anibuf[strlen(anibuf) - 1] == '#')
07513                anibuf[strlen(anibuf) - 1] = 0;
07514             ast_set_callerid(chan, anibuf + 2, NULL, anibuf + 2);
07515          }
07516                         ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax);
07517       }
07518 
07519       ast_copy_string(exten, dtmfbuf, sizeof(exten));
07520       if (ast_strlen_zero(exten))
07521          ast_copy_string(exten, "s", sizeof(exten));
07522       if (p->sig == SIG_FEATD || p->sig == SIG_EMWINK) {
07523          /* Look for Feature Group D on all E&M Wink and Feature Group D trunks */
07524          if (exten[0] == '*') {
07525             char *stringp=NULL;
07526             ast_copy_string(exten2, exten, sizeof(exten2));
07527             /* Parse out extension and callerid */
07528             stringp=exten2 +1;
07529             s1 = strsep(&stringp, "*");
07530             s2 = strsep(&stringp, "*");
07531             if (s2) {
07532                if (!ast_strlen_zero(p->cid_num))
07533                   ast_set_callerid(chan, p->cid_num, NULL, p->cid_num);
07534                else
07535                   ast_set_callerid(chan, s1, NULL, s1);
07536                ast_copy_string(exten, s2, sizeof(exten));
07537             } else
07538                ast_copy_string(exten, s1, sizeof(exten));
07539          } else if (p->sig == SIG_FEATD)
07540             ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d.  Assuming E&M Wink instead\n", p->channel);
07541       }
07542       if ((p->sig == SIG_FEATDMF) || (p->sig == SIG_FEATDMF_TA)) {
07543          if (exten[0] == '*') {
07544             char *stringp=NULL;
07545             ast_copy_string(exten2, exten, sizeof(exten2));
07546             /* Parse out extension and callerid */
07547             stringp=exten2 +1;
07548             s1 = strsep(&stringp, "#");
07549             s2 = strsep(&stringp, "#");
07550             if (s2) {
07551                if (!ast_strlen_zero(p->cid_num))
07552                   ast_set_callerid(chan, p->cid_num, NULL, p->cid_num);
07553                else
07554                   if (*(s1 + 2))
07555                      ast_set_callerid(chan, s1 + 2, NULL, s1 + 2);
07556                ast_copy_string(exten, s2 + 1, sizeof(exten));
07557             } else
07558                ast_copy_string(exten, s1 + 2, sizeof(exten));
07559          } else
07560             ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d.  Assuming E&M Wink instead\n", p->channel);
07561       }
07562       if ((p->sig == SIG_E911) || (p->sig == SIG_FGC_CAMAMF)) {
07563          if (exten[0] == '*') {
07564             char *stringp=NULL;
07565             ast_copy_string(exten2, exten, sizeof(exten2));
07566             /* Parse out extension and callerid */
07567             stringp=exten2 +1;
07568             s1 = strsep(&stringp, "#");
07569             s2 = strsep(&stringp, "#");
07570             if (s2 && (*(s2 + 1) == '0')) {
07571                if (*(s2 + 2))
07572                   ast_set_callerid(chan, s2 + 2, NULL, s2 + 2);
07573             }
07574             if (s1)  ast_copy_string(exten, s1, sizeof(exten));
07575             else ast_copy_string(exten, "911", sizeof(exten));
07576          } else
07577             ast_log(LOG_WARNING, "Got a non-E911/FGC CAMA input on channel %d.  Assuming E&M Wink instead\n", p->channel);
07578       }
07579       if (p->sig == SIG_FEATB) {
07580          if (exten[0] == '*') {
07581             char *stringp=NULL;
07582             ast_copy_string(exten2, exten, sizeof(exten2));
07583             /* Parse out extension and callerid */
07584             stringp=exten2 +1;
07585             s1 = strsep(&stringp, "#");
07586             ast_copy_string(exten, exten2 + 1, sizeof(exten));
07587          } else
07588             ast_log(LOG_WARNING, "Got a non-Feature Group B input on channel %d.  Assuming E&M Wink instead\n", p->channel);
07589       }
07590       if ((p->sig == SIG_FEATDMF) || (p->sig == SIG_FEATDMF_TA)) {
07591          dahdi_wink(p, index);
07592                         /* some switches require a minimum guard time between
07593                            the last FGD wink and something that answers
07594                            immediately. This ensures it */
07595          if (ast_safe_sleep(chan, 100)) {
07596             ast_hangup(chan);
07597             goto quit;
07598          }
07599       }
07600       dahdi_enable_ec(p);
07601       if (NEED_MFDETECT(p)) {
07602          if (p->dsp) {
07603             if (!p->hardwaredtmf)
07604                ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax); 
07605             else {
07606                ast_dsp_free(p->dsp);
07607                p->dsp = NULL;
07608             }
07609          }
07610       }
07611 
07612       if (ast_exists_extension(chan, chan->context, exten, 1, chan->cid.cid_num)) {
07613          ast_copy_string(chan->exten, exten, sizeof(chan->exten));
07614          if (p->dsp) ast_dsp_digitreset(p->dsp);
07615          res = ast_pbx_run(chan);
07616          if (res) {
07617             ast_log(LOG_WARNING, "PBX exited non-zero\n");
07618             res = tone_zone_play_tone(p->subs[index].dfd, DAHDI_TONE_CONGESTION);
07619          }
07620          goto quit;
07621       } else {
07622          if (option_verbose > 2)
07623             ast_verbose(VERBOSE_PREFIX_2 "Unknown extension '%s' in context '%s' requested\n", exten, chan->context);
07624          sleep(2);
07625          res = tone_zone_play_tone(p->subs[index].dfd, DAHDI_TONE_INFO);
07626          if (res < 0)
07627             ast_log(LOG_WARNING, "Unable to start special tone on %d\n", p->channel);
07628          else
07629             sleep(1);
07630          res = ast_streamfile(chan, "ss-noservice", chan->language);
07631          if (res >= 0)
07632             ast_waitstream(chan, "");
07633          res = tone_zone_play_tone(p->subs[index].dfd, DAHDI_TONE_CONGESTION);
07634          ast_hangup(chan);
07635          goto quit;
07636       }
07637       break;
07638    case SIG_FXOLS:
07639    case SIG_FXOGS:
07640    case SIG_FXOKS:
07641       /* Read the first digit */
07642       timeout = firstdigittimeout;
07643       /* If starting a threeway call, never timeout on the first digit so someone
07644          can use flash-hook as a "hold" feature */
07645       if (p->subs[SUB_THREEWAY].owner) 
07646          timeout = 999999;
07647       while (len < AST_MAX_EXTENSION-1) {
07648          /* Read digit unless it's supposed to be immediate, in which case the
07649             only answer is 's' */
07650          if (p->immediate) 
07651             res = 's';
07652          else
07653             res = ast_waitfordigit(chan, timeout);
07654          timeout = 0;
07655          if (res < 0) {
07656             ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n");
07657             res = tone_zone_play_tone(p->subs[index].dfd, -1);
07658             ast_hangup(chan);
07659             goto quit;
07660          } else if (res)  {
07661             exten[len++]=res;
07662             exten[len] = '\0';
07663          }
07664          if (!ast_ignore_pattern(chan->context, exten))
07665             tone_zone_play_tone(p->subs[index].dfd, -1);
07666          else
07667             tone_zone_play_tone(p->subs[index].dfd, DAHDI_TONE_DIALTONE);
07668          if (!strcmp(exten,ast_pickup_ext())) {
07669             /* Scan all channels and see if there are any
07670              * ringing channels that have call groups
07671              * that equal this channels pickup group
07672              */
07673             if (index == SUB_REAL) {
07674                /* Switch us from Third call to Call Wait */
07675                if (p->subs[SUB_THREEWAY].owner) {
07676                   /* If you make a threeway call and the *8# a call, it should actually
07677                      look like a callwait */
07678                   alloc_sub(p, SUB_CALLWAIT);
07679                   swap_subs(p, SUB_CALLWAIT, SUB_THREEWAY);
07680                   unalloc_sub(p, SUB_THREEWAY);
07681                }
07682                dahdi_enable_ec(p);
07683                if (ast_pickup_call(chan)) {
07684                   ast_log(LOG_DEBUG, "No call pickup possible...\n");
07685                   res = tone_zone_play_tone(p->subs[index].dfd, DAHDI_TONE_CONGESTION);
07686                   dahdi_wait_event(p->subs[index].dfd);
07687                }
07688                ast_hangup(chan);
07689                goto quit;
07690             } else {
07691                ast_log(LOG_WARNING, "Huh?  Got *8# on call not on real\n");
07692                ast_hangup(chan);
07693                goto quit;
07694             }
07695 
07696          } else if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num) && strcmp(exten, ast_parking_ext())) {
07697             if (!res || !ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) {
07698                if (getforward) {
07699                   /* Record this as the forwarding extension */
07700                   ast_copy_string(p->call_forward, exten, sizeof(p->call_forward)); 
07701                   if (option_verbose > 2)
07702                      ast_verbose(VERBOSE_PREFIX_3 "Setting call forward to '%s' on channel %d\n", p->call_forward, p->channel);
07703                   res = tone_zone_play_tone(p->subs[index].dfd, DAHDI_TONE_DIALRECALL);
07704                   if (res)
07705                      break;
07706                   usleep(500000);
07707                   res = tone_zone_play_tone(p->subs[index].dfd, -1);
07708                   sleep(1);
07709                   memset(exten, 0, sizeof(exten));
07710                   res = tone_zone_play_tone(p->subs[index].dfd, DAHDI_TONE_DIALTONE);
07711                   len = 0;
07712                   getforward = 0;
07713                } else  {
07714                   res = tone_zone_play_tone(p->subs[index].dfd, -1);
07715                   ast_copy_string(chan->exten, exten, sizeof(chan->exten));
07716                   if (!ast_strlen_zero(p->cid_num)) {
07717                      if (!p->hidecallerid)
07718                         ast_set_callerid(chan, p->cid_num, NULL, p->cid_num); 
07719                      else
07720                         ast_set_callerid(chan, NULL, NULL, p->cid_num); 
07721                   }
07722                   if (!ast_strlen_zero(p->cid_name)) {
07723                      if (!p->hidecallerid)
07724                         ast_set_callerid(chan, NULL, p->cid_name, NULL);
07725                   }
07726                   ast_setstate(chan, AST_STATE_RING);
07727                   dahdi_enable_ec(p);
07728                   res = ast_pbx_run(chan);
07729                   if (res) {
07730                      ast_log(LOG_WARNING, "PBX exited non-zero\n");
07731                      res = tone_zone_play_tone(p->subs[index].dfd, DAHDI_TONE_CONGESTION);
07732                   }
07733                   goto quit;
07734                }
07735             } else {
07736                /* It's a match, but they just typed a digit, and there is an ambiguous match,
07737                   so just set the timeout to matchdigittimeout and wait some more */
07738                timeout = matchdigittimeout;
07739             }
07740          } else if (res == 0) {
07741             ast_log(LOG_DEBUG, "not enough digits (and no ambiguous match)...\n");
07742             res = tone_zone_play_tone(p->subs[index].dfd, DAHDI_TONE_CONGESTION);
07743             dahdi_wait_event(p->subs[index].dfd);
07744             ast_hangup(chan);
07745             goto quit;
07746          } else if (p->callwaiting && !strcmp(exten, "*70")) {
07747             if (option_verbose > 2) 
07748                ast_verbose(VERBOSE_PREFIX_3 "Disabling call waiting on %s\n", chan->name);
07749             /* Disable call waiting if enabled */
07750             p->callwaiting = 0;
07751             res = tone_zone_play_tone(p->subs[index].dfd, DAHDI_TONE_DIALRECALL);
07752             if (res) {
07753                ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 
07754                   chan->name, strerror(errno));
07755             }
07756             len = 0;
07757             ioctl(p->subs[index].dfd,DAHDI_CONFDIAG,&len);
07758             memset(exten, 0, sizeof(exten));
07759             timeout = firstdigittimeout;
07760                
07761          } else if (!p->hidecallerid && !strcmp(exten, "*67")) {
07762             if (option_verbose > 2) 
07763                ast_verbose(VERBOSE_PREFIX_3 "Disabling Caller*ID on %s\n", chan->name);
07764             /* Disable Caller*ID if enabled */
07765             p->hidecallerid = 1;
07766             if (chan->cid.cid_num)
07767                free(chan->cid.cid_num);
07768             chan->cid.cid_num = NULL;
07769             if (chan->cid.cid_name)
07770                free(chan->cid.cid_name);
07771             chan->cid.cid_name = NULL;
07772             res = tone_zone_play_tone(p->subs[index].dfd, DAHDI_TONE_DIALRECALL);
07773             if (res) {
07774                ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 
07775                   chan->name, strerror(errno));
07776             }
07777             len = 0;
07778             memset(exten, 0, sizeof(exten));
07779             timeout = firstdigittimeout;
07780          } else if (p->callreturn && !strcmp(exten, "*69")) {
07781             res = 0;
07782             if (!ast_strlen_zero(p->lastcid_num)) {
07783                res = ast_say_digit_str(chan, p->lastcid_num, "", chan->language);
07784             }
07785             if (!res)
07786                res = tone_zone_play_tone(p->subs[index].dfd, DAHDI_TONE_DIALRECALL);
07787             break;
07788          } else if (!strcmp(exten, "*78")) {
07789             /* Do not disturb */
07790             if (option_verbose > 2)
07791                ast_verbose(VERBOSE_PREFIX_3 "Enabled DND on channel %d\n", p->channel);
07792             manager_event(EVENT_FLAG_SYSTEM, "DNDState",
07793                      "Channel: %s/%d\r\n"
07794                      "Status: enabled\r\n", dahdi_chan_name, p->channel);
07795             res = tone_zone_play_tone(p->subs[index].dfd, DAHDI_TONE_DIALRECALL);
07796             p->dnd = 1;
07797             getforward = 0;
07798             memset(exten, 0, sizeof(exten));
07799             len = 0;
07800          } else if (!strcmp(exten, "*79")) {
07801             /* Do not disturb */
07802             if (option_verbose > 2)
07803                ast_verbose(VERBOSE_PREFIX_3 "Disabled DND on channel %d\n", p->channel);
07804             manager_event(EVENT_FLAG_SYSTEM, "DNDState",
07805                      "Channel: %s/%d\r\n"
07806                      "Status: disabled\r\n", dahdi_chan_name, p->channel);
07807             res = tone_zone_play_tone(p->subs[index].dfd, DAHDI_TONE_DIALRECALL);
07808             p->dnd = 0;
07809             getforward = 0;
07810             memset(exten, 0, sizeof(exten));
07811             len = 0;
07812          } else if (p->cancallforward && !strcmp(exten, "*72")) {
07813             res = tone_zone_play_tone(p->subs[index].dfd, DAHDI_TONE_DIALRECALL);
07814             getforward = 1;
07815             memset(exten, 0, sizeof(exten));
07816             len = 0;
07817          } else if (p->cancallforward && !strcmp(exten, "*73")) {
07818             if (option_verbose > 2)
07819                ast_verbose(VERBOSE_PREFIX_3 "Cancelling call forwarding on channel %d\n", p->channel);
07820             res = tone_zone_play_tone(p->subs[index].dfd, DAHDI_TONE_DIALRECALL);
07821             memset(p->call_forward, 0, sizeof(p->call_forward));
07822             getforward = 0;
07823             memset(exten, 0, sizeof(exten));
07824             len = 0;
07825          } else if ((p->transfer || p->canpark) && !strcmp(exten, ast_parking_ext()) && 
07826                   p->subs[SUB_THREEWAY].owner &&
07827                   ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
07828             /* This is a three way call, the main call being a real channel, 
07829                and we're parking the first call. */
07830             ast_masq_park_call(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), chan, 0, NULL);
07831             if (option_verbose > 2)
07832                ast_verbose(VERBOSE_PREFIX_3 "Parking call to '%s'\n", chan->name);
07833             break;
07834          } else if (!ast_strlen_zero(p->lastcid_num) && !strcmp(exten, "*60")) {
07835             if (option_verbose > 2)
07836                ast_verbose(VERBOSE_PREFIX_3 "Blacklisting number %s\n", p->lastcid_num);
07837             res = ast_db_put("blacklist", p->lastcid_num, "1");
07838             if (!res) {
07839                res = tone_zone_play_tone(p->subs[index].dfd, DAHDI_TONE_DIALRECALL);
07840                memset(exten, 0, sizeof(exten));
07841                len = 0;
07842             }
07843          } else if (p->hidecallerid && !strcmp(exten, "*82")) {
07844             if (option_verbose > 2) 
07845                ast_verbose(VERBOSE_PREFIX_3 "Enabling Caller*ID on %s\n", chan->name);
07846             /* Enable Caller*ID if enabled */
07847             p->hidecallerid = 0;
07848             if (chan->cid.cid_num)
07849                free(chan->cid.cid_num);
07850             chan->cid.cid_num = NULL;
07851             if (chan->cid.cid_name)
07852                free(chan->cid.cid_name);
07853             chan->cid.cid_name = NULL;
07854             ast_set_callerid(chan, p->cid_num, p->cid_name, NULL);
07855             res = tone_zone_play_tone(p->subs[index].dfd, DAHDI_TONE_DIALRECALL);
07856             if (res) {
07857                ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 
07858                   chan->name, strerror(errno));
07859             }
07860             len = 0;
07861             memset(exten, 0, sizeof(exten));
07862             timeout = firstdigittimeout;
07863          } else if (!strcmp(exten, "*0")) {
07864             struct ast_channel *nbridge = 
07865                p->subs[SUB_THREEWAY].owner;
07866             struct dahdi_pvt *pbridge = NULL;
07867               /* set up the private struct of the bridged one, if any */
07868             if (nbridge && ast_bridged_channel(nbridge)) 
07869                pbridge = ast_bridged_channel(nbridge)->tech_pvt;
07870             if (nbridge && pbridge && 
07871                 (nbridge->tech == chan_tech) && 
07872                 (ast_bridged_channel(nbridge)->tech == chan_tech) &&
07873                 ISTRUNK(pbridge)) {
07874                int func = DAHDI_FLASH;
07875                /* Clear out the dial buffer */
07876                p->dop.dialstr[0] = '\0';
07877                /* flash hookswitch */
07878                if ((ioctl(pbridge->subs[SUB_REAL].dfd,DAHDI_HOOK,&func) == -1) && (errno != EINPROGRESS)) {
07879                   ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n", 
07880                      nbridge->name, strerror(errno));
07881                }
07882                swap_subs(p, SUB_REAL, SUB_THREEWAY);
07883                unalloc_sub(p, SUB_THREEWAY);
07884                p->owner = p->subs[SUB_REAL].owner;
07885                if (ast_bridged_channel(p->subs[SUB_REAL].owner))
07886                   ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
07887                ast_hangup(chan);
07888                goto quit;
07889             } else {
07890                tone_zone_play_tone(p->subs[index].dfd, DAHDI_TONE_CONGESTION);
07891                dahdi_wait_event(p->subs[index].dfd);
07892                tone_zone_play_tone(p->subs[index].dfd, -1);
07893                swap_subs(p, SUB_REAL, SUB_THREEWAY);
07894                unalloc_sub(p, SUB_THREEWAY);
07895                p->owner = p->subs[SUB_REAL].owner;
07896                ast_hangup(chan);
07897                goto quit;
07898             }              
07899          } else if (!ast_canmatch_extension(chan, chan->context, exten, 1, chan->cid.cid_num) &&
07900                      ((exten[0] != '*') || (strlen(exten) > 2))) {
07901             if (option_debug)
07902                ast_log(LOG_DEBUG, "Can't match %s from '%s' in context %s\n", exten, chan->cid.cid_num ? chan->cid.cid_num : "<Unknown Caller>", chan->context);
07903             break;
07904          }
07905          if (!timeout)
07906             timeout = gendigittimeout;
07907          if (len && !ast_ignore_pattern(chan->context, exten))
07908             tone_zone_play_tone(p->subs[index].dfd, -1);
07909       }
07910       break;
07911    case SIG_FXSLS:
07912    case SIG_FXSGS:
07913    case SIG_FXSKS:
07914 #ifdef HAVE_PRI
07915       if (p->pri) {
07916          /* This is a GR-303 trunk actually.  Wait for the first ring... */
07917          struct ast_frame *f;
07918          int res;
07919          time_t start;
07920 
07921          time(&start);
07922          ast_setstate(chan, AST_STATE_RING);
07923          while (time(NULL) < start + 3) {
07924             res = ast_waitfor(chan, 1000);
07925             if (res) {
07926                f = ast_read(chan);
07927                if (!f) {
07928                   ast_log(LOG_WARNING, "Whoa, hangup while waiting for first ring!\n");
07929                   ast_hangup(chan);
07930                   goto quit;
07931                } else if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_RING)) {
07932                   res = 1;
07933                } else
07934                   res = 0;
07935                ast_frfree(f);
07936                if (res) {
07937                   ast_log(LOG_DEBUG, "Got ring!\n");
07938                   res = 0;
07939                   break;
07940                }
07941             }
07942          }
07943       }
07944 #endif
07945       /* check for SMDI messages */
07946       if (p->use_smdi && p->smdi_iface) {
07947          smdi_msg = ast_smdi_md_message_wait(p->smdi_iface, SMDI_MD_WAIT_TIMEOUT);
07948 
07949          if (smdi_msg != NULL) {
07950             ast_copy_string(chan->exten, smdi_msg->fwd_st, sizeof(chan->exten));
07951 
07952             if (smdi_msg->type == 'B')
07953                pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "b");
07954             else if (smdi_msg->type == 'N')
07955                pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "u");
07956 
07957             ast_log(LOG_DEBUG, "Received SMDI message on %s\n", chan->name);
07958          } else {
07959             ast_log(LOG_WARNING, "SMDI enabled but no SMDI message present\n");
07960          }
07961       }
07962 
07963       if (p->use_callerid && (p->cid_signalling == CID_SIG_SMDI && smdi_msg)) {
07964             number = smdi_msg->calling_st;
07965 
07966       /* If we want caller id, we're in a prering state due to a polarity reversal
07967        * and we're set to use a polarity reversal to trigger the start of caller id,
07968        * grab the caller id and wait for ringing to start... */
07969       } else if (p->use_callerid && (chan->_state == AST_STATE_PRERING &&
07970                    (p->cid_start == CID_START_POLARITY || p->cid_start == CID_START_DTMF_NOALERT))) {
07971          /* If set to use DTMF CID signalling, listen for DTMF */
07972          if (p->cid_signalling == CID_SIG_DTMF) {
07973             int i = 0;
07974             cs = NULL;
07975             ast_log(LOG_DEBUG, "Receiving DTMF cid on channel %s\n", chan->name);
07976             dahdi_setlinear(p->subs[index].dfd, 0);
07977             /*
07978              * We are the only party interested in the Rx stream since
07979              * we have not answered yet.  We don't need or even want DTMF
07980              * emulation.  The DTMF digits can come so fast that emulation
07981              * can drop some of them.
07982              */
07983             ast_set_flag(chan, AST_FLAG_END_DTMF_ONLY);
07984             res = 4000;/* This is a typical OFF time between rings. */
07985             for (;;) {
07986                struct ast_frame *f;
07987                res = ast_waitfor(chan, res);
07988                if (res <= 0) {
07989                   /*
07990                    * We do not need to restore the dahdi_setlinear()
07991                    * or AST_FLAG_END_DTMF_ONLY flag settings since we
07992                    * are hanging up the channel.
07993                    */
07994                   ast_log(LOG_WARNING, "DTMFCID timed out waiting for ring. "
07995                      "Exiting simple switch\n");
07996                   ast_hangup(chan);
07997                   goto quit;
07998                } 
07999                f = ast_read(chan);
08000                if (!f)
08001                   break;
08002                if (f->frametype == AST_FRAME_DTMF) {
08003                   if (i < ARRAY_LEN(dtmfbuf) - 1) {
08004                      dtmfbuf[i++] = f->subclass;
08005                   }
08006                   ast_log(LOG_DEBUG, "CID got digit '%c'\n", f->subclass);
08007                   res = 4000;/* This is a typical OFF time between rings. */
08008                }
08009                ast_frfree(f);
08010                if (chan->_state == AST_STATE_RING ||
08011                    chan->_state == AST_STATE_RINGING) 
08012                   break; /* Got ring */
08013             }
08014             ast_clear_flag(chan, AST_FLAG_END_DTMF_ONLY);
08015             dtmfbuf[i] = '\0';
08016             dahdi_setlinear(p->subs[index].dfd, p->subs[index].linear);
08017             /* Got cid and ring. */
08018             ast_log(LOG_DEBUG, "CID got string '%s'\n", dtmfbuf);
08019             callerid_get_dtmf(dtmfbuf, dtmfcid, &flags);
08020             ast_log(LOG_DEBUG, "CID is '%s', flags %d\n", dtmfcid, flags);
08021             /* If first byte is NULL, we have no cid */
08022             if (!ast_strlen_zero(dtmfcid)) 
08023                number = dtmfcid;
08024             else
08025                number = NULL;
08026          /* If set to use V23 Signalling, launch our FSK gubbins and listen for it */
08027          } else if ((p->cid_signalling == CID_SIG_V23) || (p->cid_signalling == CID_SIG_V23_JP)) {
08028             cs = callerid_new(p->cid_signalling);
08029             if (cs) {
08030                samples = 0;
08031 #if 1
08032                bump_gains(p);
08033 #endif            
08034                /* Take out of linear mode for Caller*ID processing */
08035                dahdi_setlinear(p->subs[index].dfd, 0);
08036                
08037                /* First we wait and listen for the Caller*ID */
08038                for (;;) {  
08039                   i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT;
08040                   if ((res = ioctl(p->subs[index].dfd, DAHDI_IOMUX, &i)))  {
08041                      ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
08042                      callerid_free(cs);
08043                      ast_hangup(chan);
08044                      goto quit;
08045                   }
08046                   if (i & DAHDI_IOMUX_SIGEVENT) {
08047                      res = dahdi_get_event(p->subs[index].dfd);
08048                      ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
08049                      if (res == DAHDI_EVENT_NOALARM) {
08050                         p->inalarm = 0;
08051                      }
08052 
08053                      if (p->cid_signalling == CID_SIG_V23_JP) {
08054 #ifdef DAHDI_EVENT_RINGBEGIN
08055                         if (res == DAHDI_EVENT_RINGBEGIN) {
08056                            res = dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_OFFHOOK);
08057                            usleep(1);
08058                         }
08059 #endif
08060                      } else {
08061                         res = 0;
08062                         break;
08063                      }
08064                   } else if (i & DAHDI_IOMUX_READ) {
08065                      res = read(p->subs[index].dfd, buf, sizeof(buf));
08066                      if (res < 0) {
08067                         if (errno != ELAST) {
08068                            ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
08069                            callerid_free(cs);
08070                            ast_hangup(chan);
08071                            goto quit;
08072                         }
08073                         break;
08074                      }
08075                      samples += res;
08076 
08077                      if  (p->cid_signalling == CID_SIG_V23_JP) {
08078                         res = callerid_feed_jp(cs, buf, res, AST_LAW(p));
08079                      } else {
08080                         res = callerid_feed(cs, buf, res, AST_LAW(p));
08081                      }
08082                      if (res < 0) {
08083                         /*
08084                          * The previous diagnostic message output likely
08085                          * explains why it failed.
08086                          */
08087                         ast_log(LOG_WARNING,
08088                            "Failed to decode CallerID on channel '%s'\n",
08089                            chan->name);
08090                         break;
08091                      } else if (res)
08092                         break;
08093                      else if (samples > (8000 * 10))
08094                         break;
08095                   }
08096                }
08097                if (res == 1) {
08098                   callerid_get(cs, &name, &number, &flags);
08099                   ast_log(LOG_NOTICE, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags);
08100                }
08101 
08102                if (p->cid_signalling == CID_SIG_V23_JP) {
08103                   res = dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_ONHOOK);
08104                   usleep(1);
08105                }
08106 
08107                /* Finished with Caller*ID, now wait for a ring to make sure there really is a call coming */
08108                res = 4000;/* This is a typical OFF time between rings. */
08109                for (;;) {
08110                   struct ast_frame *f;
08111                   res = ast_waitfor(chan, res);
08112                   if (res <= 0) {
08113                      ast_log(LOG_WARNING, "CID timed out waiting for ring. "
08114                         "Exiting simple switch\n");
08115                      ast_hangup(chan);
08116                      goto quit;
08117                   } 
08118                   if (!(f = ast_read(chan))) {
08119                      ast_log(LOG_WARNING, "Hangup received waiting for ring. Exiting simple switch\n");
08120                      ast_hangup(chan);
08121                      goto quit;
08122                   }
08123                   ast_frfree(f);
08124                   if (chan->_state == AST_STATE_RING ||
08125                       chan->_state == AST_STATE_RINGING) 
08126                      break; /* Got ring */
08127                }
08128    
08129                /* We must have a ring by now, so, if configured, lets try to listen for
08130                 * distinctive ringing */ 
08131                if (p->usedistinctiveringdetection) {
08132                   len = 0;
08133                   distMatches = 0;
08134                   /* Clear the current ring data array so we dont have old data in it. */
08135                   for (receivedRingT = 0; receivedRingT < (sizeof(curRingData) / sizeof(curRingData[0])); receivedRingT++)
08136                      curRingData[receivedRingT] = 0;
08137                   receivedRingT = 0;
08138                   counter = 0;
08139                   counter1 = 0;
08140                   /* Check to see if context is what it should be, if not set to be. */
08141                   if (strcmp(p->context,p->defcontext) != 0) {
08142                      ast_copy_string(p->context, p->defcontext, sizeof(p->context));
08143                      ast_copy_string(chan->context,p->defcontext,sizeof(chan->context));
08144                   }
08145       
08146                   for (;;) {  
08147                      i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT;
08148                      if ((res = ioctl(p->subs[index].dfd, DAHDI_IOMUX, &i)))  {
08149                         ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
08150                         callerid_free(cs);
08151                         ast_hangup(chan);
08152                         goto quit;
08153                      }
08154                      if (i & DAHDI_IOMUX_SIGEVENT) {
08155                         res = dahdi_get_event(p->subs[index].dfd);
08156                         ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
08157                         if (res == DAHDI_EVENT_NOALARM) {
08158                            p->inalarm = 0;
08159                         }
08160                         res = 0;
08161                         /* Let us detect distinctive ring */
08162       
08163                         curRingData[receivedRingT] = p->ringt;
08164       
08165                         if (p->ringt < p->ringt_base/2)
08166                            break;
08167                         /* Increment the ringT counter so we can match it against
08168                            values in chan_dahdi.conf for distinctive ring */
08169                         if (++receivedRingT == (sizeof(curRingData) / sizeof(curRingData[0])))
08170                            break;
08171                      } else if (i & DAHDI_IOMUX_READ) {
08172                         res = read(p->subs[index].dfd, buf, sizeof(buf));
08173                         if (res < 0) {
08174                            if (errno != ELAST) {
08175                               ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
08176                               callerid_free(cs);
08177                               ast_hangup(chan);
08178                               goto quit;
08179                            }
08180                            break;
08181                         }
08182                         if (p->ringt) 
08183                            p->ringt--;
08184                         if (p->ringt == 1) {
08185                            res = -1;
08186                            break;
08187                         }
08188                      }
08189                   }
08190                   if (option_verbose > 2)
08191                      /* this only shows up if you have n of the dring patterns filled in */
08192                      ast_verbose( VERBOSE_PREFIX_3 "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]);
08193    
08194                   for (counter = 0; counter < 3; counter++) {
08195                      /* Check to see if the rings we received match any of the ones in chan_dahdi.conf for this
08196                      channel */
08197                      distMatches = 0;
08198                      for (counter1 = 0; counter1 < 3; counter1++) {
08199                         if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1]+10) && curRingData[counter1] >=
08200                         (p->drings.ringnum[counter].ring[counter1]-10)) {
08201                            distMatches++;
08202                         }
08203                      }
08204                      if (distMatches == 3) {
08205                         /* The ring matches, set the context to whatever is for distinctive ring.. */
08206                         ast_copy_string(p->context, p->drings.ringContext[counter].contextData, sizeof(p->context));
08207                         ast_copy_string(chan->context, p->drings.ringContext[counter].contextData, sizeof(chan->context));
08208                         if (option_verbose > 2)
08209                            ast_verbose( VERBOSE_PREFIX_3 "Distinctive Ring matched context %s\n",p->context);
08210                         break;
08211                      }
08212                   }
08213                }
08214                /* Restore linear mode (if appropriate) for Caller*ID processing */
08215                dahdi_setlinear(p->subs[index].dfd, p->subs[index].linear);
08216 #if 1
08217                restore_gains(p);
08218 #endif            
08219             } else
08220                ast_log(LOG_WARNING, "Unable to get caller ID space\n");       
08221          } else {
08222             ast_log(LOG_WARNING, "Channel %s in prering "
08223                "state, but I have nothing to do. "
08224                "Terminating simple switch, should be "
08225                "restarted by the actual ring.\n", 
08226                chan->name);
08227             ast_hangup(chan);
08228             goto quit;
08229          }
08230       } else if (p->use_callerid && p->cid_start == CID_START_RING) {
08231          /* FSK Bell202 callerID */
08232          cs = callerid_new(p->cid_signalling);
08233          if (cs) {
08234 #if 1
08235             bump_gains(p);
08236 #endif            
08237             samples = 0;
08238             len = 0;
08239             distMatches = 0;
08240             /* Clear the current ring data array so we dont have old data in it. */
08241             for (receivedRingT = 0; receivedRingT < (sizeof(curRingData) / sizeof(curRingData[0])); receivedRingT++)
08242                curRingData[receivedRingT] = 0;
08243             receivedRingT = 0;
08244             counter = 0;
08245             counter1 = 0;
08246             /* Check to see if context is what it should be, if not set to be. */
08247             if (strcmp(p->context,p->defcontext) != 0) {
08248                ast_copy_string(p->context, p->defcontext, sizeof(p->context));
08249                ast_copy_string(chan->context,p->defcontext,sizeof(chan->context));
08250             }
08251 
08252             /* Take out of linear mode for Caller*ID processing */
08253             dahdi_setlinear(p->subs[index].dfd, 0);
08254             for (;;) {  
08255                i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT;
08256                if ((res = ioctl(p->subs[index].dfd, DAHDI_IOMUX, &i)))  {
08257                   ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
08258                   callerid_free(cs);
08259                   ast_hangup(chan);
08260                   goto quit;
08261                }
08262                if (i & DAHDI_IOMUX_SIGEVENT) {
08263                   res = dahdi_get_event(p->subs[index].dfd);
08264                   ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
08265                   if (res == DAHDI_EVENT_NOALARM) {
08266                      p->inalarm = 0;
08267                   }
08268                   /* If we get a PR event, they hung up while processing calerid */
08269                   if ( res == DAHDI_EVENT_POLARITY && p->hanguponpolarityswitch && p->polarity == POLARITY_REV) {
08270                      ast_log(LOG_DEBUG, "Hanging up due to polarity reversal on channel %d while detecting callerid\n", p->channel);
08271                      p->polarity = POLARITY_IDLE;
08272                      callerid_free(cs);
08273                      ast_hangup(chan);
08274                      goto quit;
08275                   }
08276                   res = 0;
08277                   /* Let us detect callerid when the telco uses distinctive ring */
08278 
08279                   curRingData[receivedRingT] = p->ringt;
08280 
08281                   if (p->ringt < p->ringt_base/2)
08282                      break;
08283                   /* Increment the ringT counter so we can match it against
08284                      values in chan_dahdi.conf for distinctive ring */
08285                   if (++receivedRingT == (sizeof(curRingData) / sizeof(curRingData[0])))
08286                      break;
08287                } else if (i & DAHDI_IOMUX_READ) {
08288                   res = read(p->subs[index].dfd, buf, sizeof(buf));
08289                   if (res < 0) {
08290                      if (errno != ELAST) {
08291                         ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
08292                         callerid_free(cs);
08293                         ast_hangup(chan);
08294                         goto quit;
08295                      }
08296                      break;
08297                   }
08298                   if (p->ringt) 
08299                      p->ringt--;
08300                   if (p->ringt == 1) {
08301                      res = -1;
08302                      break;
08303                   }
08304                   samples += res;
08305                   res = callerid_feed(cs, buf, res, AST_LAW(p));
08306                   if (res < 0) {
08307                      /*
08308                       * The previous diagnostic message output likely
08309                       * explains why it failed.
08310                       */
08311                      ast_log(LOG_WARNING,
08312                         "Failed to decode CallerID on channel '%s'\n",
08313                         chan->name);
08314                      break;
08315                   } else if (res)
08316                      break;
08317                   else if (samples > (8000 * 10))
08318                      break;
08319                }
08320             }
08321             if (res == 1) {
08322                callerid_get(cs, &name, &number, &flags);
08323                if (option_debug)
08324                   ast_log(LOG_DEBUG, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags);
08325             }
08326             if (distinctiveringaftercid == 1) {
08327                /* Clear the current ring data array so we dont have old data in it. */
08328                for (receivedRingT = 0; receivedRingT < 3; receivedRingT++) {
08329                   curRingData[receivedRingT] = 0;
08330                }
08331                receivedRingT = 0;
08332                if (option_verbose > 2)
08333                   ast_verbose( VERBOSE_PREFIX_3 "Detecting post-CID distinctive ring\n");
08334                for (;;) {
08335                   i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT;
08336                   if ((res = ioctl(p->subs[index].dfd, DAHDI_IOMUX, &i)))    {
08337                      ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
08338                      callerid_free(cs);
08339                      ast_hangup(chan);
08340                      goto quit;
08341                   }
08342                   if (i & DAHDI_IOMUX_SIGEVENT) {
08343                      res = dahdi_get_event(p->subs[index].dfd);
08344                      ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
08345                      if (res == DAHDI_EVENT_NOALARM) {
08346                         p->inalarm = 0;
08347                      }
08348                      res = 0;
08349                      /* Let us detect callerid when the telco uses distinctive ring */
08350 
08351                      curRingData[receivedRingT] = p->ringt;
08352 
08353                      if (p->ringt < p->ringt_base/2)
08354                         break;
08355                      /* Increment the ringT counter so we can match it against
08356                         values in chan_dahdi.conf for distinctive ring */
08357                      if (++receivedRingT == (sizeof(curRingData) / sizeof(curRingData[0])))
08358                         break;
08359                   } else if (i & DAHDI_IOMUX_READ) {
08360                      res = read(p->subs[index].dfd, buf, sizeof(buf));
08361                      if (res < 0) {
08362                         if (errno != ELAST) {
08363                            ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
08364                            callerid_free(cs);
08365                            ast_hangup(chan);
08366                            goto quit;
08367                         }
08368                         break;
08369                      }
08370                   if (p->ringt)
08371                      p->ringt--;
08372                      if (p->ringt == 1) {
08373                         res = -1;
08374                         break;
08375                      }
08376                   }
08377                }
08378             }
08379             if (p->usedistinctiveringdetection) {
08380                if (option_verbose > 2)
08381                   /* this only shows up if you have n of the dring patterns filled in */
08382                   ast_verbose( VERBOSE_PREFIX_3 "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]);
08383 
08384                for (counter = 0; counter < 3; counter++) {
08385                   /* Check to see if the rings we received match any of the ones in chan_dahdi.conf for this
08386                   channel */
08387                   if (option_verbose > 2)
08388                      /* this only shows up if you have n of the dring patterns filled in */
08389                      ast_verbose( VERBOSE_PREFIX_3 "Checking %d,%d,%d\n",
08390                         p->drings.ringnum[counter].ring[0],
08391                         p->drings.ringnum[counter].ring[1],
08392                         p->drings.ringnum[counter].ring[2]);
08393                   distMatches = 0;
08394                   for (counter1 = 0; counter1 < 3; counter1++) {
08395                      if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1]+10) && curRingData[counter1] >=
08396                      (p->drings.ringnum[counter].ring[counter1]-10)) {
08397                         distMatches++;
08398                      }
08399                   }
08400                   if (distMatches == 3) {
08401                      /* The ring matches, set the context to whatever is for distinctive ring.. */
08402                      ast_copy_string(p->context, p->drings.ringContext[counter].contextData, sizeof(p->context));
08403                      ast_copy_string(chan->context, p->drings.ringContext[counter].contextData, sizeof(chan->context));
08404                      if (option_verbose > 2)
08405                         ast_verbose( VERBOSE_PREFIX_3 "Distinctive Ring matched context %s\n",p->context);
08406                      break;
08407                   }
08408                }
08409             }
08410             /* Restore linear mode (if appropriate) for Caller*ID processing */
08411             dahdi_setlinear(p->subs[index].dfd, p->subs[index].linear);
08412 #if 1
08413             restore_gains(p);
08414 #endif            
08415             if (res < 0) {
08416                ast_log(LOG_WARNING, "CallerID returned with error on channel '%s'\n", chan->name);
08417             }
08418          } else
08419             ast_log(LOG_WARNING, "Unable to get caller ID space\n");
08420       }
08421       else
08422          cs = NULL;
08423 
08424       if (number)
08425          ast_shrink_phone_number(number);
08426       ast_set_callerid(chan, number, name, number);
08427 
08428       if (smdi_msg)
08429          ASTOBJ_UNREF(smdi_msg, ast_smdi_md_message_destroy);
08430 
08431       if (cs)
08432          callerid_free(cs);
08433 
08434       ast_setstate(chan, AST_STATE_RING);
08435       chan->rings = 1;
08436       p->ringt = p->ringt_base;
08437       res = ast_pbx_run(chan);
08438       if (res) {
08439          ast_hangup(chan);
08440          ast_log(LOG_WARNING, "PBX exited non-zero\n");
08441       }
08442       goto quit;
08443    default:
08444       ast_log(LOG_WARNING, "Don't know how to handle simple switch with signalling %s on channel %d\n", sig2str(p->sig), p->channel);
08445       res = tone_zone_play_tone(p->subs[index].dfd, DAHDI_TONE_CONGESTION);
08446       if (res < 0)
08447             ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel);
08448    }
08449    res = tone_zone_play_tone(p->subs[index].dfd, DAHDI_TONE_CONGESTION);
08450    if (res < 0)
08451          ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel);
08452    ast_hangup(chan);
08453 quit:
08454    ast_mutex_lock(&ss_thread_lock);
08455    ss_thread_count--;
08456    ast_cond_signal(&ss_thread_complete);
08457    ast_mutex_unlock(&ss_thread_lock);
08458    return NULL;
08459 }
08460 
08461 static int calc_energy(const unsigned char *buf, int len, int law)
08462 {
08463    int x;
08464    int sum = 0;
08465    int ssum = 0, mean = 0;
08466 
08467    if (!len)
08468       return 0;
08469 
08470    /* First calc mean signal (DC offset) */
08471    for (x = 0; x < len; x++)
08472          ssum += (law == AST_FORMAT_ULAW ? AST_MULAW(buf[x]) : AST_ALAW(buf[x]));
08473 
08474    mean = ssum / len;   
08475 
08476    for (x = 0; x < len; x++) {
08477          sum += abs((law == AST_FORMAT_ULAW ? AST_MULAW(buf[x]) : AST_ALAW(buf[x])) - mean);
08478       if (option_verbose > 7)
08479             ast_log(LOG_WARNING, "x %i, bufx: %i sum %i, ssum %i\n", x, buf[x], sum, ssum);
08480    }
08481 
08482    if (option_verbose > 5)
08483          ast_log(LOG_WARNING, "mean %i, energy %i\n", mean, sum/len);
08484 
08485    return sum / len;
08486 }
08487 
08488 /* destroy a DAHDI channel, identified by its number */
08489 static int dahdi_destroy_channel_bynum(int channel)
08490 {
08491    struct dahdi_pvt *tmp = NULL;
08492    struct dahdi_pvt *prev = NULL;
08493 
08494    ast_mutex_lock(&iflock);
08495    tmp = iflist;
08496    while (tmp) {
08497       if (tmp->channel == channel) {
08498          int x = DAHDI_FLASH;
08499          ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_HOOK, &x); /* important to create an event for dahdi_wait_event to register so that all ss_threads terminate */
08500          destroy_channel(prev, tmp, 1);
08501          ast_mutex_unlock(&iflock);
08502          ast_module_unref(ast_module_info->self);
08503          return RESULT_SUCCESS;
08504       }
08505       prev = tmp;
08506       tmp = tmp->next;
08507    }
08508    ast_mutex_unlock(&iflock);
08509    return RESULT_FAILURE;
08510 }
08511 
08512 static struct dahdi_pvt *handle_init_event(struct dahdi_pvt *i, int event)
08513 {
08514    int res;
08515    pthread_t threadid;
08516    pthread_attr_t attr;
08517    struct ast_channel *chan;
08518    pthread_attr_init(&attr);
08519    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
08520    /* Handle an event on a given channel for the monitor thread. */
08521    switch (event) {
08522    case DAHDI_EVENT_NONE:
08523    case DAHDI_EVENT_BITSCHANGED:
08524       break;
08525    case DAHDI_EVENT_WINKFLASH:
08526    case DAHDI_EVENT_RINGOFFHOOK:
08527       if (i->inalarm) break;
08528       if (i->radio) break;
08529       /* Got a ring/answer.  What kind of channel are we? */
08530       switch (i->sig) {
08531       case SIG_FXOLS:
08532       case SIG_FXOGS:
08533       case SIG_FXOKS:
08534          res = dahdi_set_hook(i->subs[SUB_REAL].dfd, DAHDI_OFFHOOK);
08535          if (res && (errno == EBUSY))
08536             break;
08537 
08538          /* Cancel VMWI spill */
08539          free(i->cidspill);
08540          i->cidspill = NULL;
08541          restore_conference(i);
08542 
08543          if (i->immediate) {
08544             dahdi_enable_ec(i);
08545             /* The channel is immediately up.  Start right away */
08546             res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_RINGTONE);
08547             chan = dahdi_new(i, AST_STATE_RING, 1, SUB_REAL, 0, 0);
08548             if (!chan) {
08549                ast_log(LOG_WARNING, "Unable to start PBX on channel %d\n", i->channel);
08550                res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION);
08551                if (res < 0)
08552                   ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
08553             }
08554          } else {
08555             /* Check for callerid, digits, etc */
08556             chan = dahdi_new(i, AST_STATE_RESERVED, 0, SUB_REAL, 0, 0);
08557             if (chan) {
08558                if (has_voicemail(i))
08559                   res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_STUTTER);
08560                else
08561                   res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_DIALTONE);
08562                if (res < 0) 
08563                   ast_log(LOG_WARNING, "Unable to play dialtone on channel %d, do you have defaultzone and loadzone defined?\n", i->channel);
08564                if (ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
08565                   ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
08566                   res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION);
08567                   if (res < 0)
08568                      ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
08569                   ast_hangup(chan);
08570                }
08571             } else
08572                ast_log(LOG_WARNING, "Unable to create channel\n");
08573          }
08574          break;
08575       case SIG_FXSLS:
08576       case SIG_FXSGS:
08577       case SIG_FXSKS:
08578             i->ringt = i->ringt_base;
08579             /* Fall through */
08580       case SIG_EMWINK:
08581       case SIG_FEATD:
08582       case SIG_FEATDMF:
08583       case SIG_FEATDMF_TA:
08584       case SIG_E911:
08585       case SIG_FGC_CAMA:
08586       case SIG_FGC_CAMAMF:
08587       case SIG_FEATB:
08588       case SIG_EM:
08589       case SIG_EM_E1:
08590       case SIG_SFWINK:
08591       case SIG_SF_FEATD:
08592       case SIG_SF_FEATDMF:
08593       case SIG_SF_FEATB:
08594       case SIG_SF:
08595             /* Check for callerid, digits, etc */
08596             chan = dahdi_new(i, AST_STATE_RING, 0, SUB_REAL, 0, 0);
08597             if (chan && ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
08598                ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
08599                res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION);
08600                if (res < 0)
08601                   ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
08602                ast_hangup(chan);
08603             } else if (!chan) {
08604                ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel);
08605             }
08606             break;
08607       default:
08608          ast_log(LOG_WARNING, "Don't know how to handle ring/answer with signalling %s on channel %d\n", sig2str(i->sig), i->channel);
08609          res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION);
08610          if (res < 0)
08611                ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
08612          pthread_attr_destroy(&attr);
08613          return NULL;
08614       }
08615       break;
08616    case DAHDI_EVENT_NOALARM:
08617       i->inalarm = 0;
08618 #if defined(HAVE_PRI)
08619       i->resetting = 0;
08620 #endif   /* defined(HAVE_PRI) */
08621       if (!i->unknown_alarm) {
08622          ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", i->channel);
08623          manager_event(EVENT_FLAG_SYSTEM, "AlarmClear",
08624                   "Channel: %d\r\n", i->channel);
08625       } else {
08626          i->unknown_alarm = 0;
08627       }
08628       break;
08629    case DAHDI_EVENT_ALARM:
08630       i->inalarm = 1;
08631 #if defined(HAVE_PRI)
08632       i->resetting = 0;
08633 #endif   /* defined(HAVE_PRI) */
08634       res = get_alarms(i);
08635       handle_alarms(i, res);
08636       /* fall thru intentionally */
08637    case DAHDI_EVENT_ONHOOK:
08638       if (i->radio)
08639          break;
08640       /* Back on hook.  Hang up. */
08641       switch (i->sig) {
08642       case SIG_FXOLS:
08643       case SIG_FXOGS:
08644       case SIG_FEATD:
08645       case SIG_FEATDMF:
08646       case SIG_FEATDMF_TA:
08647       case SIG_E911:
08648       case SIG_FGC_CAMA:
08649       case SIG_FGC_CAMAMF:
08650       case SIG_FEATB:
08651       case SIG_EM:
08652       case SIG_EM_E1:
08653       case SIG_EMWINK:
08654       case SIG_SF_FEATD:
08655       case SIG_SF_FEATDMF:
08656       case SIG_SF_FEATB:
08657       case SIG_SF:
08658       case SIG_SFWINK:
08659       case SIG_FXSLS:
08660       case SIG_FXSGS:
08661       case SIG_FXSKS:
08662       case SIG_GR303FXSKS:
08663          dahdi_disable_ec(i);
08664          res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, -1);
08665          dahdi_set_hook(i->subs[SUB_REAL].dfd, DAHDI_ONHOOK);
08666          break;
08667       case SIG_GR303FXOKS:
08668       case SIG_FXOKS:
08669          dahdi_disable_ec(i);
08670          /* Diddle the battery for the zhone */
08671 #ifdef ZHONE_HACK
08672          dahdi_set_hook(i->subs[SUB_REAL].dfd, DAHDI_OFFHOOK);
08673          usleep(1);
08674 #endif         
08675          res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, -1);
08676          dahdi_set_hook(i->subs[SUB_REAL].dfd, DAHDI_ONHOOK);
08677          break;
08678       case SIG_PRI:
08679          dahdi_disable_ec(i);
08680          res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, -1);
08681          break;
08682       default:
08683          ast_log(LOG_WARNING, "Don't know how to handle on hook with signalling %s on channel %d\n", sig2str(i->sig), i->channel);
08684          res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, -1);
08685          pthread_attr_destroy(&attr);
08686          return NULL;
08687       }
08688       break;
08689    case DAHDI_EVENT_POLARITY:
08690       switch (i->sig) {
08691       case SIG_FXSLS:
08692       case SIG_FXSKS:
08693       case SIG_FXSGS:
08694          /* We have already got a PR before the channel was 
08695             created, but it wasn't handled. We need polarity 
08696             to be REV for remote hangup detection to work. 
08697             At least in Spain */
08698          if (i->hanguponpolarityswitch)
08699             i->polarity = POLARITY_REV;
08700 
08701          if (i->cid_start == CID_START_POLARITY) {
08702             i->polarity = POLARITY_REV;
08703             ast_verbose(VERBOSE_PREFIX_2 "Starting post polarity "
08704                    "CID detection on channel %d\n",
08705                    i->channel);
08706             chan = dahdi_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, 0);
08707             if (chan && ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
08708                ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
08709             }
08710          }
08711          break;
08712       default:
08713          ast_log(LOG_WARNING, "handle_init_event detected "
08714             "polarity reversal on non-FXO (SIG_FXS) "
08715             "interface %d\n", i->channel);
08716       }
08717       break;
08718    case DAHDI_EVENT_REMOVED: /* destroy channel, will actually do so in do_monitor */
08719       ast_log(LOG_NOTICE, 
08720             "Got DAHDI_EVENT_REMOVED. Destroying channel %d\n", 
08721             i->channel);
08722       pthread_attr_destroy(&attr);
08723       return i;
08724    }
08725    pthread_attr_destroy(&attr);
08726    return NULL;
08727 }
08728 
08729 static void *do_monitor(void *data)
08730 {
08731    int count, res, res2, spoint, pollres=0;
08732    struct dahdi_pvt *i;
08733    struct dahdi_pvt *last = NULL;
08734    struct dahdi_pvt *doomed;
08735    time_t thispass = 0, lastpass = 0;
08736    int found;
08737    char buf[1024];
08738    struct pollfd *pfds=NULL;
08739    int lastalloc = -1;
08740    /* This thread monitors all the frame relay interfaces which are not yet in use
08741       (and thus do not have a separate thread) indefinitely */
08742    /* From here on out, we die whenever asked */
08743 #if 0
08744    if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL)) {
08745       ast_log(LOG_WARNING, "Unable to set cancel type to asynchronous\n");
08746       return NULL;
08747    }
08748    ast_log(LOG_DEBUG, "Monitor starting...\n");
08749 #endif
08750    pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
08751 
08752    for (;;) {
08753       /* Lock the interface list */
08754       ast_mutex_lock(&iflock);
08755       if (!pfds || (lastalloc != ifcount)) {
08756          if (pfds) {
08757             free(pfds);
08758             pfds = NULL;
08759          }
08760          if (ifcount) {
08761             if (!(pfds = ast_calloc(1, ifcount * sizeof(*pfds)))) {
08762                ast_mutex_unlock(&iflock);
08763                return NULL;
08764             }
08765          }
08766          lastalloc = ifcount;
08767       }
08768       /* Build the stuff we're going to poll on, that is the socket of every
08769          dahdi_pvt that does not have an associated owner channel */
08770       count = 0;
08771       i = iflist;
08772       while (i) {
08773          if ((i->subs[SUB_REAL].dfd > -1) && i->sig && (!i->radio) && !(i->sig & SIG_MFCR2)) {
08774             if (!i->owner && !i->subs[SUB_REAL].owner) {
08775                /* This needs to be watched, as it lacks an owner */
08776                pfds[count].fd = i->subs[SUB_REAL].dfd;
08777                pfds[count].events = POLLPRI;
08778                pfds[count].revents = 0;
08779                /* Message waiting or r2 channels also get watched for reading */
08780                if (i->cidspill ||
08781                    (i->cid_start == CID_START_DTMF_NOALERT && (i->sig == SIG_FXSLS || i->sig == SIG_FXSGS || i->sig == SIG_FXSKS))) {
08782                   pfds[count].events |= POLLIN;
08783                }
08784                count++;
08785             }
08786          }
08787          i = i->next;
08788       }
08789       /* Okay, now that we know what to do, release the interface lock */
08790       ast_mutex_unlock(&iflock);
08791       
08792       pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
08793       pthread_testcancel();
08794       /* Wait at least a second for something to happen */
08795       res = poll(pfds, count, 1000);
08796       pthread_testcancel();
08797       pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
08798 
08799       /* Okay, poll has finished.  Let's see what happened.  */
08800       if (res < 0) {
08801          if ((errno != EAGAIN) && (errno != EINTR))
08802             ast_log(LOG_WARNING, "poll return %d: %s\n", res, strerror(errno));
08803          continue;
08804       }
08805       /* Alright, lock the interface list again, and let's look and see what has
08806          happened */
08807       ast_mutex_lock(&iflock);
08808       found = 0;
08809       spoint = 0;
08810       lastpass = thispass;
08811       thispass = time(NULL);
08812       doomed = NULL;
08813       for (i = iflist;; i = i->next) {
08814          if (doomed) {
08815             int res;
08816             res = dahdi_destroy_channel_bynum(doomed->channel);
08817             if (!res) {
08818                ast_log(LOG_WARNING, "Couldn't find channel to destroy, hopefully another destroy operation just happened.\n");
08819             }
08820             doomed = NULL;
08821          }
08822          if (!i) {
08823             break;
08824          }
08825          if (thispass != lastpass) {
08826             if (!found && ((i == last) || ((i == iflist) && !last))) {
08827                last = i;
08828                if (last) {
08829                   if (!last->cidspill
08830                      && !last->owner
08831                      && !ast_strlen_zero(last->mailbox)
08832                      && (thispass - last->onhooktime > 3)
08833                      && (last->sig & __DAHDI_SIG_FXO)) {
08834                      res = ast_app_has_voicemail(last->mailbox, NULL);
08835                      if (last->msgstate != res) {
08836                         int x;
08837                         ast_log(LOG_DEBUG, "Message status for %s changed from %d to %d on %d\n", last->mailbox, last->msgstate, res, last->channel);
08838                         x = DAHDI_FLUSH_BOTH;
08839                         res2 = ioctl(last->subs[SUB_REAL].dfd, DAHDI_FLUSH, &x);
08840                         if (res2)
08841                            ast_log(LOG_WARNING, "Unable to flush input on channel %d: %s\n", last->channel, strerror(errno));
08842                         if ((last->cidspill = ast_calloc(1, MAX_CALLERID_SIZE))) {
08843                            /* Turn on on hook transfer for 4 seconds */
08844                            x = 4000;
08845                            ioctl(last->subs[SUB_REAL].dfd, DAHDI_ONHOOKTRANSFER, &x);
08846                            last->cidlen = ast_callerid_vmwi_generate(last->cidspill, res, 1, AST_LAW(last));
08847                            last->cidpos = 0;
08848                            last->msgstate = res;
08849                            last->onhooktime = thispass;
08850                         }
08851                         found ++;
08852                      }
08853                   }
08854                   last = last->next;
08855                }
08856             }
08857          }
08858          if ((i->subs[SUB_REAL].dfd > -1) && i->sig) {
08859             if (i->radio && !i->owner)
08860             {
08861                res = dahdi_get_event(i->subs[SUB_REAL].dfd);
08862                if (res)
08863                {
08864                   if (option_debug)
08865                      ast_log(LOG_DEBUG, "Monitor doohicky got event %s on radio channel %d\n", event2str(res), i->channel);
08866                   /* Don't hold iflock while handling init events */
08867                   ast_mutex_unlock(&iflock);
08868                   doomed = handle_init_event(i, res);
08869                   ast_mutex_lock(&iflock);   
08870                }
08871                continue;
08872             }              
08873             pollres = ast_fdisset(pfds, i->subs[SUB_REAL].dfd, count, &spoint);
08874             if (pollres & POLLIN) {
08875                if (i->owner || i->subs[SUB_REAL].owner) {
08876 #ifdef HAVE_PRI
08877                   if (!i->pri)
08878 #endif                  
08879                      ast_log(LOG_WARNING, "Whoa....  I'm owned but found (%d) in read...\n", i->subs[SUB_REAL].dfd);
08880                   continue;
08881                }
08882                res = read(i->subs[SUB_REAL].dfd, buf, sizeof(buf));
08883                if (res > 0) {
08884                   /* We read some number of bytes.  Write an equal amount of data */
08885                   /* If configured to check for a DTMF CID spill that comes without alert (e.g no polarity reversal) */
08886                   if (i->cid_start == CID_START_DTMF_NOALERT) {
08887                      int energy;
08888                      struct timeval now;
08889                      /* State machine dtmfcid_holdoff_state allows for the line to settle
08890                       * before checking agin for dtmf energy.  Presently waits for 500 mS before checking again
08891                      */
08892                      if (1 == i->dtmfcid_holdoff_state) {
08893                         gettimeofday(&i->dtmfcid_delay, NULL);
08894                         i->dtmfcid_holdoff_state = 2;
08895                      } else if (2 == i->dtmfcid_holdoff_state) {
08896                         gettimeofday(&now, NULL);
08897                         if ((int)(now.tv_sec - i->dtmfcid_delay.tv_sec) * 1000000 + (int)now.tv_usec - (int)i->dtmfcid_delay.tv_usec > 500000) {
08898                            i->dtmfcid_holdoff_state = 0;
08899                         }
08900                      } else {
08901                         energy = calc_energy((unsigned char *) buf, res, AST_LAW(i));
08902                         if (energy > dtmfcid_level) {
08903                            pthread_t threadid;
08904                            struct ast_channel *chan;
08905                            ast_mutex_unlock(&iflock);
08906                            chan = dahdi_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, 0);
08907                            if (!chan) {
08908                               ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel);
08909                            } else {
08910                               pthread_attr_t attr;
08911                               pthread_attr_init(&attr);
08912                               pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
08913                               res = ast_pthread_create(&threadid, &attr, ss_thread, chan);
08914                               if (res) {
08915                                  ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
08916                               } else {
08917                                  i->dtmfcid_holdoff_state = 1;
08918                               }
08919                            }
08920                            ast_mutex_lock(&iflock);
08921                         }
08922                      }
08923                   }
08924                } else {
08925                   ast_log(LOG_WARNING, "Read failed with %d: %s\n", res, strerror(errno));
08926                }
08927             }
08928             if (pollres & POLLPRI) {
08929                if (i->owner || i->subs[SUB_REAL].owner) {
08930 #ifdef HAVE_PRI
08931                   if (!i->pri)
08932 #endif                  
08933                      ast_log(LOG_WARNING, "Whoa....  I'm owned but found (%d)...\n", i->subs[SUB_REAL].dfd);
08934                   continue;
08935                }
08936                res = dahdi_get_event(i->subs[SUB_REAL].dfd);
08937                if (option_debug)
08938                   ast_log(LOG_DEBUG, "Monitor doohicky got event %s on channel %d\n", event2str(res), i->channel);
08939                /* Don't hold iflock while handling init events */
08940                ast_mutex_unlock(&iflock);
08941                doomed = handle_init_event(i, res);
08942                ast_mutex_lock(&iflock);   
08943             }
08944          }
08945       }
08946       ast_mutex_unlock(&iflock);
08947    }
08948    /* Never reached */
08949    return NULL;
08950    
08951 }
08952 
08953 static int restart_monitor(void)
08954 {
08955    pthread_attr_t attr;
08956    pthread_attr_init(&attr);
08957    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
08958    /* If we're supposed to be stopped -- stay stopped */
08959    if (monitor_thread == AST_PTHREADT_STOP)
08960       return 0;
08961    ast_mutex_lock(&monlock);
08962    if (monitor_thread == pthread_self()) {
08963       ast_mutex_unlock(&monlock);
08964       ast_log(LOG_WARNING, "Cannot kill myself\n");
08965       return -1;
08966    }
08967    if (monitor_thread != AST_PTHREADT_NULL) {
08968       /* Wake up the thread */
08969       pthread_kill(monitor_thread, SIGURG);
08970    } else {
08971       /* Start a new monitor */
08972       if (ast_pthread_create_background(&monitor_thread, &attr, do_monitor, NULL) < 0) {
08973          ast_mutex_unlock(&monlock);
08974          ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
08975          pthread_attr_destroy(&attr);
08976          return -1;
08977       }
08978    }
08979    ast_mutex_unlock(&monlock);
08980    pthread_attr_destroy(&attr);
08981    return 0;
08982 }
08983 
08984 #ifdef HAVE_OPENR2
08985 static struct dahdi_mfcr2 *mfcr2_get_context(int id)
08986 {
08987    if ((id < 0) || (id >= (sizeof(r2links)/sizeof(r2links[0])))) {
08988       ast_log(LOG_ERROR, "No more R2 links available!.\n");
08989       return NULL;
08990    }
08991    return &r2links[id];
08992 }
08993 #endif
08994 
08995 #ifdef HAVE_PRI
08996 static int pri_resolve_span(int *span, int channel, int offset, struct dahdi_spaninfo *si)
08997 {
08998    int x;
08999    int trunkgroup;
09000    /* Get appropriate trunk group if there is one */
09001    trunkgroup = pris[*span].mastertrunkgroup;
09002    if (trunkgroup) {
09003       /* Select a specific trunk group */
09004       for (x = 0; x < NUM_SPANS; x++) {
09005          if (pris[x].trunkgroup == trunkgroup) {
09006             *span = x;
09007             return 0;
09008          }
09009       }
09010       ast_log(LOG_WARNING, "Channel %d on span %d configured to use nonexistent trunk group %d\n", channel, *span, trunkgroup);
09011       *span = -1;
09012    } else {
09013       if (pris[*span].trunkgroup) {
09014          ast_log(LOG_WARNING, "Unable to use span %d implicitly since it is trunk group %d (please use spanmap)\n", *span, pris[*span].trunkgroup);
09015          *span = -1;
09016       } else if (pris[*span].mastertrunkgroup) {
09017          ast_log(LOG_WARNING, "Unable to use span %d implicitly since it is already part of trunk group %d\n", *span, pris[*span].mastertrunkgroup);
09018          *span = -1;
09019       } else {
09020          if (si->totalchans == 31) {
09021             /* E1 */
09022             pris[*span].dchannels[0] = 16 + offset;
09023          } else if (si->totalchans == 24) {
09024             /* T1 or J1 */
09025             pris[*span].dchannels[0] = 24 + offset;
09026          } else if (si->totalchans == 3) {
09027             /* BRI */
09028             pris[*span].dchannels[0] = 3 + offset;
09029          } else {
09030             ast_log(LOG_WARNING, "Unable to use span %d, since the D-channel cannot be located (unexpected span size of %d channels)\n", *span, si->totalchans);
09031             *span = -1;
09032             return 0;
09033          }
09034          pris[*span].dchanavail[0] |= DCHAN_PROVISIONED;
09035          pris[*span].offset = offset;
09036          pris[*span].span = *span + 1;
09037       }
09038    }
09039    return 0;
09040 }
09041 
09042 static int pri_create_trunkgroup(int trunkgroup, int *channels)
09043 {
09044    struct dahdi_spaninfo si;
09045    struct dahdi_params p;
09046    int fd;
09047    int span;
09048    int ospan=0;
09049    int x,y;
09050    for (x = 0; x < NUM_SPANS; x++) {
09051       if (pris[x].trunkgroup == trunkgroup) {
09052          ast_log(LOG_WARNING, "Trunk group %d already exists on span %d, Primary d-channel %d\n", trunkgroup, x + 1, pris[x].dchannels[0]);
09053          return -1;
09054       }
09055    }
09056    for (y = 0; y < NUM_DCHANS; y++) {
09057       if (!channels[y]) 
09058          break;
09059       memset(&si, 0, sizeof(si));
09060       memset(&p, 0, sizeof(p));
09061       fd = open(DAHDI_FILE_CHANNEL, O_RDWR);
09062       if (fd < 0) {
09063          ast_log(LOG_WARNING, "Failed to open channel: %s\n", strerror(errno));
09064          return -1;
09065       }
09066       x = channels[y];
09067       if (ioctl(fd, DAHDI_SPECIFY, &x)) {
09068          ast_log(LOG_WARNING, "Failed to specify channel %d: %s\n", channels[y], strerror(errno));
09069          close(fd);
09070          return -1;
09071       }
09072       if (ioctl(fd, DAHDI_GET_PARAMS, &p)) {
09073          ast_log(LOG_WARNING, "Failed to get channel parameters for channel %d: %s\n", channels[y], strerror(errno));
09074          return -1;
09075       }
09076       if (ioctl(fd, DAHDI_SPANSTAT, &si)) {
09077          ast_log(LOG_WARNING, "Failed go get span information on channel %d (span %d): %s\n", channels[y], p.spanno, strerror(errno));
09078          close(fd);
09079          return -1;
09080       }
09081       span = p.spanno - 1;
09082       if (pris[span].trunkgroup) {
09083          ast_log(LOG_WARNING, "Span %d is already provisioned for trunk group %d\n", span + 1, pris[span].trunkgroup);
09084          close(fd);
09085          return -1;
09086       }
09087       if (pris[span].pvts[0]) {
09088          ast_log(LOG_WARNING, "Span %d is already provisioned with channels (implicit PRI maybe?)\n", span + 1);
09089          close(fd);
09090          return -1;
09091       }
09092       if (!y) {
09093          pris[span].trunkgroup = trunkgroup;
09094          pris[span].offset = channels[y] - p.chanpos;
09095          ospan = span;
09096       }
09097       pris[ospan].dchannels[y] = channels[y];
09098       pris[ospan].dchanavail[y] |= DCHAN_PROVISIONED;
09099       pris[span].span = span + 1;
09100       close(fd);
09101    }
09102    return 0;   
09103 }
09104 
09105 static int pri_create_spanmap(int span, int trunkgroup, int logicalspan)
09106 {
09107    if (pris[span].mastertrunkgroup) {
09108       ast_log(LOG_WARNING, "Span %d is already part of trunk group %d, cannot add to trunk group %d\n", span + 1, pris[span].mastertrunkgroup, trunkgroup);
09109       return -1;
09110    }
09111    pris[span].mastertrunkgroup = trunkgroup;
09112    pris[span].prilogicalspan = logicalspan;
09113    return 0;
09114 }
09115 
09116 #endif
09117 
09118 static struct dahdi_pvt *mkintf(int channel, const struct dahdi_chan_conf *conf, struct dahdi_pri *pri, int reloading)
09119 {
09120    /* Make a dahdi_pvt structure for this interface (or CRV if "pri" is specified) */
09121    struct dahdi_pvt *tmp = NULL, *tmp2,  *prev = NULL;
09122    char fn[80];
09123 #if 1
09124    struct dahdi_bufferinfo bi;
09125 #endif
09126    int res;
09127    int span=0;
09128    int here = 0;
09129    int x;
09130    struct dahdi_pvt **wlist;
09131    struct dahdi_pvt **wend;
09132    struct dahdi_params p;
09133 
09134    wlist = &iflist;
09135    wend = &ifend;
09136 
09137 #ifdef HAVE_PRI
09138    if (pri) {
09139       wlist = &pri->crvs;
09140       wend = &pri->crvend;
09141    }
09142 #endif
09143 
09144    tmp2 = *wlist;
09145    prev = NULL;
09146 
09147    while (tmp2) {
09148       if (!tmp2->destroy) {
09149          if (tmp2->channel == channel) {
09150             tmp = tmp2;
09151             here = 1;
09152             break;
09153          }
09154          if (tmp2->channel > channel) {
09155             break;
09156          }
09157       }
09158       prev = tmp2;
09159       tmp2 = tmp2->next;
09160    }
09161 
09162    if (!here && reloading != 1) {
09163       if (!(tmp = ast_calloc(1, sizeof(*tmp)))) {
09164          if (tmp)
09165             free(tmp);
09166          return NULL;
09167       }
09168       ast_mutex_init(&tmp->lock);
09169       ifcount++;
09170       for (x = 0; x < 3; x++)
09171          tmp->subs[x].dfd = -1;
09172       tmp->channel = channel;
09173       tmp->priindication_oob = conf->chan.priindication_oob;
09174    }
09175 
09176    if (tmp) {
09177       int chan_sig = conf->chan.sig;
09178       if (!here) {
09179          if ((channel != CHAN_PSEUDO) && !pri) {
09180             int count = 0;
09181             snprintf(fn, sizeof(fn), "%d", channel);
09182             /* Open non-blocking */
09183             tmp->subs[SUB_REAL].dfd = dahdi_open(fn);
09184             while (tmp->subs[SUB_REAL].dfd < 0 && reloading == 2 && count < 1000) { /* the kernel may not call dahdi_release fast enough for the open flagbit to be cleared in time */
09185                usleep(1);
09186                tmp->subs[SUB_REAL].dfd = dahdi_open(fn);
09187                count++;
09188             }
09189             /* Allocate a DAHDI structure */
09190             if (tmp->subs[SUB_REAL].dfd < 0) {
09191                ast_log(LOG_ERROR, "Unable to open channel %d: %s\nhere = %d, tmp->channel = %d, channel = %d\n", channel, strerror(errno), here, tmp->channel, channel);
09192                destroy_dahdi_pvt(&tmp);
09193                return NULL;
09194             }
09195             memset(&p, 0, sizeof(p));
09196             res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &p);
09197             if (res < 0) {
09198                ast_log(LOG_ERROR, "Unable to get parameters: %s\n", strerror(errno));
09199                destroy_dahdi_pvt(&tmp);
09200                return NULL;
09201             }
09202             if (p.sigtype != (conf->chan.sig & 0x3ffff)) {
09203                ast_log(LOG_ERROR, "Signalling requested on channel %d is %s but line is in %s signalling\n", channel, sig2str(conf->chan.sig), sig2str(p.sigtype));
09204                destroy_dahdi_pvt(&tmp);
09205                return NULL;
09206             }
09207             tmp->law = p.curlaw;
09208             tmp->span = p.spanno;
09209             span = p.spanno - 1;
09210          } else {
09211             if (channel == CHAN_PSEUDO)
09212                chan_sig = 0;
09213             else if ((chan_sig != SIG_FXOKS) && (chan_sig != SIG_FXSKS)) {
09214                ast_log(LOG_ERROR, "CRV's must use FXO/FXS Kewl Start (fxo_ks/fxs_ks) signalling only.\n");
09215                return NULL;
09216             }
09217          }
09218          tmp->outsigmod = conf->chan.outsigmod;
09219 
09220 #ifdef HAVE_PRI
09221          if ((chan_sig == SIG_PRI) || (chan_sig == SIG_GR303FXOKS) || (chan_sig == SIG_GR303FXSKS)) {
09222             int offset;
09223             int myswitchtype;
09224             int matchesdchan;
09225             int x,y;
09226             offset = 0;
09227             if ((chan_sig == SIG_PRI) && ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &offset)) {
09228                ast_log(LOG_ERROR, "Unable to set clear mode on clear channel %d of span %d: %s\n", channel, p.spanno, strerror(errno));
09229                destroy_dahdi_pvt(&tmp);
09230                return NULL;
09231             }
09232             if (span >= NUM_SPANS) {
09233                ast_log(LOG_ERROR, "Channel %d does not lie on a span I know of (%d)\n", channel, span);
09234                destroy_dahdi_pvt(&tmp);
09235                return NULL;
09236             } else {
09237                struct dahdi_spaninfo si;
09238                si.spanno = 0;
09239                if (ioctl(tmp->subs[SUB_REAL].dfd,DAHDI_SPANSTAT,&si) == -1) {
09240                   ast_log(LOG_ERROR, "Unable to get span status: %s\n", strerror(errno));
09241                   destroy_dahdi_pvt(&tmp);
09242                   return NULL;
09243                }
09244                /* Store the logical span first based upon the real span */
09245                tmp->logicalspan = pris[span].prilogicalspan;
09246                pri_resolve_span(&span, channel, (channel - p.chanpos), &si);
09247                if (span < 0) {
09248                   ast_log(LOG_WARNING, "Channel %d: Unable to find locate channel/trunk group!\n", channel);
09249                   destroy_dahdi_pvt(&tmp);
09250                   return NULL;
09251                }
09252                if (chan_sig == SIG_PRI)
09253                   myswitchtype = conf->pri.switchtype;
09254                else
09255                   myswitchtype = PRI_SWITCH_GR303_TMC;
09256                /* Make sure this isn't a d-channel */
09257                matchesdchan=0;
09258                for (x = 0; x < NUM_SPANS; x++) {
09259                   for (y = 0; y < NUM_DCHANS; y++) {
09260                      if (pris[x].dchannels[y] == tmp->channel) {
09261                         matchesdchan = 1;
09262                         break;
09263                      }
09264                   }
09265                }
09266                offset = p.chanpos;
09267                if (!matchesdchan) {
09268                   if (pris[span].nodetype && (pris[span].nodetype != conf->pri.nodetype)) {
09269                      ast_log(LOG_ERROR, "Span %d is already a %s node\n", span + 1, pri_node2str(pris[span].nodetype));
09270                      destroy_dahdi_pvt(&tmp);
09271                      return NULL;
09272                   }
09273                   if (pris[span].switchtype && (pris[span].switchtype != myswitchtype)) {
09274                      ast_log(LOG_ERROR, "Span %d is already a %s switch\n", span + 1, pri_switch2str(pris[span].switchtype));
09275                      destroy_dahdi_pvt(&tmp);
09276                      return NULL;
09277                   }
09278                   if ((pris[span].dialplan) && (pris[span].dialplan != conf->pri.dialplan)) {
09279                      ast_log(LOG_ERROR, "Span %d is already a %s dialing plan\n", span + 1, dialplan2str(pris[span].dialplan));
09280                      destroy_dahdi_pvt(&tmp);
09281                      return NULL;
09282                   }
09283                   if (!ast_strlen_zero(pris[span].idledial) && strcmp(pris[span].idledial, conf->pri.idledial)) {
09284                      ast_log(LOG_ERROR, "Span %d already has idledial '%s'.\n", span + 1, conf->pri.idledial);
09285                      destroy_dahdi_pvt(&tmp);
09286                      return NULL;
09287                   }
09288                   if (!ast_strlen_zero(pris[span].idleext) && strcmp(pris[span].idleext, conf->pri.idleext)) {
09289                      ast_log(LOG_ERROR, "Span %d already has idleext '%s'.\n", span + 1, conf->pri.idleext);
09290                      destroy_dahdi_pvt(&tmp);
09291                      return NULL;
09292                   }
09293                   if (pris[span].minunused && (pris[span].minunused != conf->pri.minunused)) {
09294                      ast_log(LOG_ERROR, "Span %d already has minunused of %d.\n", span + 1, conf->pri.minunused);
09295                      destroy_dahdi_pvt(&tmp);
09296                      return NULL;
09297                   }
09298                   if (pris[span].minidle && (pris[span].minidle != conf->pri.minidle)) {
09299                      ast_log(LOG_ERROR, "Span %d already has minidle of %d.\n", span + 1, conf->pri.minidle);
09300                      destroy_dahdi_pvt(&tmp);
09301                      return NULL;
09302                   }
09303                   if (pris[span].numchans >= MAX_CHANNELS) {
09304                      ast_log(LOG_ERROR, "Unable to add channel %d: Too many channels in trunk group %d!\n", channel,
09305                         pris[span].trunkgroup);
09306                      destroy_dahdi_pvt(&tmp);
09307                      return NULL;
09308                   }
09309                   pris[span].nodetype = conf->pri.nodetype;
09310                   pris[span].switchtype = myswitchtype;
09311                   pris[span].nsf = conf->pri.nsf;
09312                   pris[span].dialplan = conf->pri.dialplan;
09313                   pris[span].localdialplan = conf->pri.localdialplan;
09314                   pris[span].pvts[pris[span].numchans++] = tmp;
09315                   pris[span].minunused = conf->pri.minunused;
09316                   pris[span].minidle = conf->pri.minidle;
09317                   pris[span].overlapdial = conf->pri.overlapdial;
09318 #ifdef HAVE_PRI_INBANDDISCONNECT
09319                   pris[span].inbanddisconnect = conf->pri.inbanddisconnect;
09320 #endif
09321                   pris[span].facilityenable = conf->pri.facilityenable;
09322                   ast_copy_string(pris[span].idledial, conf->pri.idledial, sizeof(pris[span].idledial));
09323                   ast_copy_string(pris[span].idleext, conf->pri.idleext, sizeof(pris[span].idleext));
09324                   ast_copy_string(pris[span].internationalprefix, conf->pri.internationalprefix, sizeof(pris[span].internationalprefix));
09325                   ast_copy_string(pris[span].nationalprefix, conf->pri.nationalprefix, sizeof(pris[span].nationalprefix));
09326                   ast_copy_string(pris[span].localprefix, conf->pri.localprefix, sizeof(pris[span].localprefix));
09327                   ast_copy_string(pris[span].privateprefix, conf->pri.privateprefix, sizeof(pris[span].privateprefix));
09328                   ast_copy_string(pris[span].unknownprefix, conf->pri.unknownprefix, sizeof(pris[span].unknownprefix));
09329                   pris[span].resetinterval = conf->pri.resetinterval;
09330                   
09331                   tmp->pri = &pris[span];
09332                   tmp->prioffset = offset;
09333                   tmp->call = NULL;
09334 
09335                   tmp->priexclusive = conf->chan.priexclusive;
09336                } else {
09337                   ast_log(LOG_ERROR, "Channel %d is reserved for D-channel.\n", offset);
09338                   destroy_dahdi_pvt(&tmp);
09339                   return NULL;
09340                }
09341             }
09342          } else {
09343             tmp->prioffset = 0;
09344          }
09345 #endif
09346 
09347 #ifdef HAVE_OPENR2
09348          if (chan_sig == SIG_MFCR2 && reloading != 1) {
09349             char logdir[OR2_MAX_PATH];
09350             struct dahdi_mfcr2 *dahdi_r2;
09351             int threshold = 0;
09352             int snres = 0;
09353             dahdi_r2 = mfcr2_get_context(mfcr2_cur_context_index);
09354             if (!dahdi_r2) {
09355                ast_log(LOG_WARNING, "Cannot get another R2 DAHDI context!\n");
09356             } else if (!dahdi_r2->protocol_context){
09357                char tmplogdir[] = "/tmp";
09358                dahdi_r2->protocol_context = openr2_context_new(NULL, &dahdi_r2_event_iface, 
09359                      &dahdi_r2_transcode_iface, mfcr2_cur_variant, mfcr2_cur_max_ani, mfcr2_cur_max_dnis);
09360                if (!dahdi_r2->protocol_context) {
09361                   ast_log(LOG_ERROR, "Cannot create OpenR2 protocol context.\n");
09362                   destroy_dahdi_pvt(&tmp);
09363                   return NULL;
09364                } 
09365                openr2_context_set_log_level(dahdi_r2->protocol_context, mfcr2_cur_loglevel);
09366                openr2_context_set_ani_first(dahdi_r2->protocol_context, mfcr2_cur_get_ani_first);
09367                openr2_context_set_skip_category_request(dahdi_r2->protocol_context, mfcr2_cur_skip_category);
09368                openr2_context_set_mf_threshold(dahdi_r2->protocol_context, threshold);
09369                openr2_context_set_mf_back_timeout(dahdi_r2->protocol_context, mfcr2_cur_mfback_timeout);
09370                openr2_context_set_metering_pulse_timeout(dahdi_r2->protocol_context, mfcr2_cur_metering_pulse_timeout);
09371                openr2_context_set_double_answer(dahdi_r2->protocol_context, mfcr2_cur_double_answer);
09372                openr2_context_set_immediate_accept(dahdi_r2->protocol_context, mfcr2_cur_immediate_accept);
09373 #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 2
09374                openr2_context_set_dtmf_dialing(dahdi_r2->protocol_context, mfcr2_cur_dtmf_dialing, mfcr2_cur_dtmf_time_on, mfcr2_cur_dtmf_time_off);
09375                openr2_context_set_dtmf_detection(dahdi_r2->protocol_context, mfcr2_cur_dtmf_detection);
09376 #endif
09377                if (ast_strlen_zero(mfcr2_cur_logdir)) {
09378                   if (openr2_context_set_log_directory(dahdi_r2->protocol_context, tmplogdir)) {
09379                      ast_log(LOG_ERROR, "Failed setting default MFC/R2 log directory %s\n", tmplogdir);
09380                   }
09381                } else {
09382                   snres = snprintf(logdir, sizeof(logdir), "%s/%s/%s", ast_config_AST_LOG_DIR, "mfcr2", mfcr2_cur_logdir);
09383                   if (snres >= sizeof(logdir)) {
09384                      ast_log(LOG_ERROR, "MFC/R2 logging directory truncated, using %s\n", tmplogdir);
09385                      if (openr2_context_set_log_directory(dahdi_r2->protocol_context, logdir)) {
09386                         ast_log(LOG_ERROR, "Failed setting default MFC/R2 log directory %s\n", tmplogdir);
09387                      }
09388                   } else {
09389                      if (openr2_context_set_log_directory(dahdi_r2->protocol_context, logdir)) {
09390                         ast_log(LOG_ERROR, "Failed setting MFC/R2 log directory %s\n", logdir);
09391                      }
09392                   }  
09393                }
09394                if (!ast_strlen_zero(mfcr2_cur_r2proto_file)) {
09395                   if (openr2_context_configure_from_advanced_file(dahdi_r2->protocol_context, mfcr2_cur_r2proto_file)) {
09396                      ast_log(LOG_ERROR, "Failed to configure r2context from advanced configuration file %s\n", mfcr2_cur_r2proto_file);
09397                   }
09398                }
09399             } 
09400             if (dahdi_r2) {
09401                /* TODO: should we check numchans overflow, or is it already done by DAHDI? */
09402                dahdi_r2->pvts[dahdi_r2->numchans++] = tmp;
09403                tmp->r2chan = openr2_chan_new_from_fd(dahdi_r2->protocol_context,
09404                      tmp->subs[SUB_REAL].dfd, NULL, NULL);
09405                if (!tmp->r2chan) {
09406                   openr2_liberr_t err = openr2_context_get_last_error(dahdi_r2->protocol_context);
09407                   ast_log(LOG_ERROR, "Cannot create OpenR2 channel: %s\n", openr2_context_error_string(err));
09408                   destroy_dahdi_pvt(&tmp);
09409                   return NULL;
09410                }
09411                openr2_chan_set_client_data(tmp->r2chan, tmp);
09412                /* cast seems to be needed to get rid of the annoying warning regarding format attribute */
09413                openr2_chan_set_logging_func(tmp->r2chan, (openr2_logging_func_t)dahdi_r2_on_chan_log);
09414                openr2_chan_set_log_level(tmp->r2chan, mfcr2_cur_loglevel);
09415                if (mfcr2_cur_call_files) {
09416                   openr2_chan_enable_call_files(tmp->r2chan);
09417                }
09418                tmp->mfcr2_category = mfcr2_cur_category;
09419                tmp->mfcr2 = dahdi_r2;
09420                tmp->mfcr2call = 0;
09421                tmp->mfcr2block = DAHDI_R2_REMOTE_BLOCK | DAHDI_R2_LOCAL_BLOCK;
09422                tmp->mfcr2_accept_on_offer = mfcr2_cur_accept_on_offer;
09423                tmp->mfcr2_charge_calls = mfcr2_cur_charge_calls;
09424                tmp->mfcr2_ani_index = 0;
09425                tmp->mfcr2_dnis_index = 0;
09426                tmp->mfcr2_allow_collect_calls = mfcr2_cur_allow_collect_calls;
09427                tmp->mfcr2_forced_release = mfcr2_cur_forced_release;
09428             }
09429          }
09430 #endif
09431 
09432       } else {
09433          chan_sig = tmp->sig;
09434          if (tmp->subs[SUB_REAL].dfd > -1) {
09435             memset(&p, 0, sizeof(p));
09436             res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &p);
09437          }
09438       }
09439       /* Adjust starttime on loopstart and kewlstart trunks to reasonable values */
09440       switch (chan_sig) {
09441       case SIG_FXSKS:
09442       case SIG_FXSLS:
09443       case SIG_EM:
09444       case SIG_EM_E1:
09445       case SIG_EMWINK:
09446       case SIG_FEATD:
09447       case SIG_FEATDMF:
09448       case SIG_FEATDMF_TA:
09449       case SIG_FEATB:
09450       case SIG_E911:
09451       case SIG_SF:
09452       case SIG_SFWINK:
09453       case SIG_FGC_CAMA:
09454       case SIG_FGC_CAMAMF:
09455       case SIG_SF_FEATD:
09456       case SIG_SF_FEATDMF:
09457       case SIG_SF_FEATB:
09458          p.starttime = 250;
09459          break;
09460       }
09461 
09462       if (tmp->radio) {
09463          /* XXX Waiting to hear back from Jim if these should be adjustable XXX */
09464          p.channo = channel;
09465          p.rxwinktime = 1;
09466          p.rxflashtime = 1;
09467          p.starttime = 1;
09468          p.debouncetime = 5;
09469       }
09470       if (!tmp->radio) {
09471          p.channo = channel;
09472          /* Override timing settings based on config file */
09473          if (conf->timing.prewinktime >= 0)
09474             p.prewinktime = conf->timing.prewinktime;
09475          if (conf->timing.preflashtime >= 0)
09476             p.preflashtime = conf->timing.preflashtime;
09477          if (conf->timing.winktime >= 0)
09478             p.winktime = conf->timing.winktime;
09479          if (conf->timing.flashtime >= 0)
09480             p.flashtime = conf->timing.flashtime;
09481          if (conf->timing.starttime >= 0)
09482             p.starttime = conf->timing.starttime;
09483          if (conf->timing.rxwinktime >= 0)
09484             p.rxwinktime = conf->timing.rxwinktime;
09485          if (conf->timing.rxflashtime >= 0)
09486             p.rxflashtime = conf->timing.rxflashtime;
09487          if (conf->timing.debouncetime >= 0)
09488             p.debouncetime = conf->timing.debouncetime;
09489       }
09490       
09491       /* dont set parms on a pseudo-channel (or CRV) */
09492       if (tmp->subs[SUB_REAL].dfd >= 0)
09493       {
09494          res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_SET_PARAMS, &p);
09495          if (res < 0) {
09496             ast_log(LOG_ERROR, "Unable to set parameters: %s\n", strerror(errno));
09497             destroy_dahdi_pvt(&tmp);
09498             return NULL;
09499          }
09500       }
09501 #if 1
09502       if (!here && (tmp->subs[SUB_REAL].dfd > -1)) {
09503          memset(&bi, 0, sizeof(bi));
09504          res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GET_BUFINFO, &bi);
09505          if (!res) {
09506             bi.txbufpolicy = conf->chan.buf_policy;
09507             bi.rxbufpolicy = conf->chan.buf_policy;
09508             bi.numbufs = conf->chan.buf_no;
09509             res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_SET_BUFINFO, &bi);
09510             if (res < 0) {
09511                ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d: %s\n", channel, strerror(errno));
09512             }
09513          } else {
09514             ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d: %s\n", channel, strerror(errno));
09515          }
09516          tmp->buf_policy = conf->chan.buf_policy;
09517          tmp->buf_no = conf->chan.buf_no;
09518          /* This is not as gnarly as it may first appear.  If the ioctl above failed, we'd be setting
09519           * tmp->bufsize to zero which would cause subsequent faxbuffer-related ioctl calls to fail.
09520           * The reason the ioctl call above failed should to be determined before worrying about the
09521           * faxbuffer-related ioctl calls */
09522          tmp->bufsize = bi.bufsize;
09523       }
09524 #endif
09525       tmp->immediate = conf->chan.immediate;
09526       tmp->transfertobusy = conf->chan.transfertobusy;
09527       tmp->sig = chan_sig;
09528       tmp->ringt_base = ringt_base;
09529       tmp->firstradio = 0;
09530       if ((chan_sig == SIG_FXOKS) || (chan_sig == SIG_FXOLS) || (chan_sig == SIG_FXOGS))
09531          tmp->permcallwaiting = conf->chan.callwaiting;
09532       else
09533          tmp->permcallwaiting = 0;
09534       /* Flag to destroy the channel must be cleared on new mkif.  Part of changes for reload to work */
09535       tmp->destroy = 0;
09536       tmp->drings = drings;
09537       tmp->usedistinctiveringdetection = conf->chan.usedistinctiveringdetection;
09538       tmp->callwaitingcallerid = conf->chan.callwaitingcallerid;
09539       tmp->threewaycalling = conf->chan.threewaycalling;
09540       tmp->adsi = conf->chan.adsi;
09541       tmp->use_smdi = conf->chan.use_smdi;
09542       tmp->permhidecallerid = conf->chan.hidecallerid;
09543       tmp->hidecalleridname = conf->chan.hidecalleridname;
09544       tmp->callreturn = conf->chan.callreturn;
09545       tmp->echocancel = conf->chan.echocancel;
09546       tmp->echotraining = conf->chan.echotraining;
09547       tmp->pulse = conf->chan.pulse;
09548       if (tmp->echocancel)
09549          tmp->echocanbridged = conf->chan.echocanbridged;
09550       else {
09551          if (conf->chan.echocanbridged)
09552             ast_log(LOG_NOTICE, "echocancelwhenbridged requires echocancel to be enabled; ignoring\n");
09553          tmp->echocanbridged = 0;
09554       }
09555       tmp->busydetect = conf->chan.busydetect;
09556       tmp->busycount = conf->chan.busycount;
09557       tmp->busycompare = conf->chan.busycompare;
09558       tmp->busytonelength = conf->chan.busytonelength;
09559       tmp->busyquietlength = conf->chan.busyquietlength;
09560       tmp->busyfuzziness = conf->chan.busyfuzziness;
09561       tmp->silencethreshold = conf->chan.silencethreshold;
09562       tmp->callprogress = conf->chan.callprogress;
09563       tmp->cancallforward = conf->chan.cancallforward;
09564       tmp->dtmfrelax = conf->chan.dtmfrelax;
09565       tmp->callwaiting = tmp->permcallwaiting;
09566       tmp->hidecallerid = tmp->permhidecallerid;
09567       tmp->channel = channel;
09568       tmp->stripmsd = conf->chan.stripmsd;
09569       tmp->use_callerid = conf->chan.use_callerid;
09570       tmp->cid_signalling = conf->chan.cid_signalling;
09571       tmp->cid_start = conf->chan.cid_start;
09572       tmp->dahditrcallerid = conf->chan.dahditrcallerid;
09573       tmp->restrictcid = conf->chan.restrictcid;
09574       tmp->use_callingpres = conf->chan.use_callingpres;
09575       if (tmp->usedistinctiveringdetection) {
09576          if (!tmp->use_callerid) {
09577             ast_log(LOG_NOTICE, "Distinctive Ring detect requires 'usecallerid' be on\n");
09578             tmp->use_callerid = 1;
09579          }
09580       }
09581 
09582       if (tmp->cid_signalling == CID_SIG_SMDI) {
09583          if (!tmp->use_smdi) {
09584             ast_log(LOG_WARNING, "SMDI callerid requires SMDI to be enabled, enabling...\n");
09585             tmp->use_smdi = 1;
09586          }
09587       }
09588       if (tmp->use_smdi) {
09589          tmp->smdi_iface = ast_smdi_interface_find(conf->smdi_port);
09590          if (!(tmp->smdi_iface)) {
09591             ast_log(LOG_ERROR, "Invalid SMDI port specfied, disabling SMDI support\n");
09592             tmp->use_smdi = 0;
09593          }
09594       }
09595 
09596       ast_copy_string(tmp->accountcode, conf->chan.accountcode, sizeof(tmp->accountcode));
09597       tmp->amaflags = conf->chan.amaflags;
09598       if (!here) {
09599          tmp->confno = -1;
09600          tmp->propconfno = -1;
09601       }
09602       tmp->canpark = conf->chan.canpark;
09603       tmp->transfer = conf->chan.transfer;
09604       ast_copy_string(tmp->defcontext,conf->chan.context,sizeof(tmp->defcontext));
09605       ast_copy_string(tmp->language, conf->chan.language, sizeof(tmp->language));
09606       ast_copy_string(tmp->mohinterpret, conf->chan.mohinterpret, sizeof(tmp->mohinterpret));
09607       ast_copy_string(tmp->mohsuggest, conf->chan.mohsuggest, sizeof(tmp->mohsuggest));
09608       ast_copy_string(tmp->context, conf->chan.context, sizeof(tmp->context));
09609       tmp->cid_ton = 0;
09610       if (chan_sig != SIG_PRI) {
09611          ast_copy_string(tmp->cid_num, conf->chan.cid_num, sizeof(tmp->cid_num));
09612          ast_copy_string(tmp->cid_name, conf->chan.cid_name, sizeof(tmp->cid_name));
09613       } else {
09614          tmp->cid_num[0] = '\0';
09615          tmp->cid_name[0] = '\0';
09616       }
09617       ast_copy_string(tmp->mailbox, conf->chan.mailbox, sizeof(tmp->mailbox));
09618       tmp->msgstate = -1;
09619       tmp->group = conf->chan.group;
09620       tmp->callgroup = conf->chan.callgroup;
09621       tmp->pickupgroup= conf->chan.pickupgroup;
09622       tmp->rxgain = conf->chan.rxgain;
09623       tmp->txgain = conf->chan.txgain;
09624       tmp->tonezone = conf->chan.tonezone;
09625       tmp->onhooktime = time(NULL);
09626       if (tmp->subs[SUB_REAL].dfd > -1) {
09627          set_actual_gain(tmp->subs[SUB_REAL].dfd, 0, tmp->rxgain, tmp->txgain, tmp->law);
09628          if (tmp->dsp)
09629             ast_dsp_digitmode(tmp->dsp, DSP_DIGITMODE_DTMF | tmp->dtmfrelax);
09630          update_conf(tmp);
09631          if (!here) {
09632             if ((chan_sig != SIG_PRI) && (chan_sig != SIG_MFCR2))
09633                /* Hang it up to be sure it's good */
09634                dahdi_set_hook(tmp->subs[SUB_REAL].dfd, DAHDI_ONHOOK);
09635          }
09636          ioctl(tmp->subs[SUB_REAL].dfd,DAHDI_SETTONEZONE,&tmp->tonezone);
09637 #ifdef HAVE_PRI
09638          /* the dchannel is down so put the channel in alarm */
09639          if (tmp->pri && !pri_is_up(tmp->pri)) {
09640             tmp->inalarm = 1;
09641             tmp->resetting = 0;
09642          }
09643 #endif            
09644          if ((res = get_alarms(tmp)) != DAHDI_ALARM_NONE) {
09645             tmp->inalarm = 1;
09646 #if defined(HAVE_PRI)
09647             tmp->resetting = 0;
09648 #endif   /* defined(HAVE_PRI) */
09649             handle_alarms(tmp, res);
09650          } else {
09651             /* yes, this looks strange... the unknown_alarm flag is only used to
09652                control whether an 'alarm cleared' message gets generated when we
09653                get an indication that the channel is no longer in alarm status.
09654                however, the channel *could* be in an alarm status that we aren't
09655                aware of (since get_alarms() only reports span alarms, not channel
09656                alarms). setting this flag will cause any potential 'alarm cleared'
09657                message to be suppressed, but if a real alarm occurs before that
09658                happens, this flag will get cleared by it and the situation will
09659                be normal.
09660             */
09661             tmp->unknown_alarm = 1;
09662          }
09663       }
09664 
09665       tmp->polarityonanswerdelay = conf->chan.polarityonanswerdelay;
09666       tmp->answeronpolarityswitch = conf->chan.answeronpolarityswitch;
09667       tmp->hanguponpolarityswitch = conf->chan.hanguponpolarityswitch;
09668       tmp->sendcalleridafter = conf->chan.sendcalleridafter;
09669 
09670    }
09671    if (tmp && !here) {
09672       /* nothing on the iflist */
09673       if (!*wlist) {
09674          *wlist = tmp;
09675          tmp->prev = NULL;
09676          tmp->next = NULL;
09677          *wend = tmp;
09678       } else {
09679          /* at least one member on the iflist */
09680          struct dahdi_pvt *working = *wlist;
09681 
09682          /* check if we maybe have to put it on the begining */
09683          if (working->channel > tmp->channel) {
09684             tmp->next = *wlist;
09685             tmp->prev = NULL;
09686             (*wlist)->prev = tmp;
09687             *wlist = tmp;
09688          } else {
09689          /* go through all the members and put the member in the right place */
09690             while (working) {
09691                /* in the middle */
09692                if (working->next) {
09693                   if (working->channel < tmp->channel && working->next->channel > tmp->channel) {
09694                      tmp->next = working->next;
09695                      tmp->prev = working;
09696                      working->next->prev = tmp;
09697                      working->next = tmp;
09698                      break;
09699                   }
09700                } else {
09701                /* the last */
09702                   if (working->channel < tmp->channel) {
09703                      working->next = tmp;
09704                      tmp->next = NULL;
09705                      tmp->prev = working;
09706                      *wend = tmp;
09707                      break;
09708                   }
09709                }
09710                working = working->next;
09711             }
09712          }
09713       }
09714    }
09715    return tmp;
09716 }
09717 
09718 #if defined(HAVE_PRI)
09719 /*!
09720  * \internal
09721  * \brief Determine if a private channel structure is in use.
09722  * \since 1.8
09723  *
09724  * \param pvt Channel to determine if in use.
09725  *
09726  * \return TRUE if the channel is in use.
09727  */
09728 static int sig_pri_is_chan_in_use(struct dahdi_pvt *pvt)
09729 {
09730    return pvt->owner || pvt->call || pvt->allocated || pvt->resetting || pvt->inalarm;
09731 }
09732 #endif   /* defined(HAVE_PRI) */
09733 
09734 #if defined(HAVE_PRI)
09735 /*!
09736  * \internal
09737  * \brief Determine if a private channel structure is available.
09738  * \since 1.8
09739  *
09740  * \param pvt Channel to determine if available.
09741  *
09742  * \return TRUE if the channel is available.
09743  */
09744 static int sig_pri_is_chan_available(struct dahdi_pvt *pvt)
09745 {
09746    return !sig_pri_is_chan_in_use(pvt);
09747 }
09748 #endif   /* defined(HAVE_PRI) */
09749 
09750 #if defined(HAVE_PRI)
09751 /*!
09752  * \internal
09753  * \brief Simple check if the channel is available to use.
09754  * \since 1.8
09755  *
09756  * \param pvt Private channel control structure.
09757  *
09758  * \retval 0 Interface not available.
09759  * \retval 1 Interface is available.
09760  */
09761 static int sig_pri_available_check(struct dahdi_pvt *pvt)
09762 {
09763    /*
09764     * If interface is available for use
09765     * then the channel is available.
09766     */
09767    if (sig_pri_is_chan_available(pvt)) {
09768       return 1;
09769    }
09770    return 0;
09771 }
09772 #endif   /* defined(HAVE_PRI) */
09773 
09774 #if defined(HAVE_PRI)
09775 static int sig_pri_available(struct dahdi_pvt *pvt)
09776 {
09777    struct dahdi_pvt *p = pvt;
09778    struct dahdi_pri *pri;
09779 
09780    if (!p->pri) {
09781       /* Something is wrong here.  A PRI channel without the pri pointer? */
09782       return 0;
09783    }
09784    pri = p->pri;
09785 
09786    ast_mutex_lock(&pri->lock);
09787    if (sig_pri_available_check(p)) {
09788       p->allocated = 1;
09789       ast_mutex_unlock(&pri->lock);
09790       return 1;
09791    }
09792 
09793    ast_mutex_unlock(&pri->lock);
09794    return 0;
09795 }
09796 #endif   /* defined(HAVE_PRI) */
09797 
09798 static inline int available(struct dahdi_pvt *p, int channelmatch, ast_group_t groupmatch, int *busy, int *channelmatched, int *groupmatched)
09799 {
09800    int res;
09801    struct dahdi_params par;
09802 
09803    /* First, check group matching */
09804    if (groupmatch) {
09805       if ((p->group & groupmatch) != groupmatch)
09806          return 0;
09807       *groupmatched = 1;
09808    }
09809    /* Check to see if we have a channel match */
09810    if (channelmatch != -1) {
09811       if (p->channel != channelmatch)
09812          return 0;
09813       *channelmatched = 1;
09814    }
09815 
09816 #if defined(HAVE_PRI)
09817    switch (p->sig) {
09818    case SIG_PRI_LIB_HANDLE_CASES:
09819       return sig_pri_available(p);
09820    default:
09821       break;
09822    }
09823 #endif   /* defined(HAVE_PRI) */
09824 
09825    /* We're at least busy at this point */
09826    if (busy) {
09827       if ((p->sig == SIG_FXOKS) || (p->sig == SIG_FXOLS) || (p->sig == SIG_FXOGS))
09828          *busy = 1;
09829    }
09830    /* If do not disturb, definitely not */
09831    if (p->dnd)
09832       return 0;
09833    /* If guard time, definitely not */
09834    if (p->guardtime && (time(NULL) < p->guardtime)) 
09835       return 0;
09836       
09837    /* If no owner definitely available */
09838    if (!p->owner) {
09839 #ifdef HAVE_PRI
09840       /* Trust PRI */
09841       if (p->pri) {
09842          /* Likely only GR-303 gets here. */
09843          return sig_pri_available(p);
09844       }
09845 #endif
09846 
09847 #ifdef HAVE_OPENR2
09848       /* Trust MFC/R2 */
09849       if (p->mfcr2) {
09850          if (p->mfcr2call || p->mfcr2block)
09851             return 0;
09852          else
09853             return 1;
09854       }
09855 #endif
09856 
09857       if (!(p->radio || (p->oprmode < 0)))
09858       {
09859          if (!p->sig || (p->sig == SIG_FXSLS))
09860             return 1;
09861          /* Check hook state */
09862          if (p->subs[SUB_REAL].dfd > -1) {
09863             memset(&par, 0, sizeof(par));
09864             res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &par);
09865          } else {
09866             /* Assume not off hook on CVRS */
09867             res = 0;
09868             par.rxisoffhook = 0;
09869          }
09870          if (res) {
09871             ast_log(LOG_WARNING, "Unable to check hook state on channel %d: %s\n", p->channel, strerror(errno));
09872          } else if ((p->sig == SIG_FXSKS) || (p->sig == SIG_FXSGS)) {
09873             /* When "onhook" that means no battery on the line, and thus
09874               it is out of service..., if it's on a TDM card... If it's a channel
09875               bank, there is no telling... */
09876             if (par.rxbits > -1)
09877                return 1;
09878             if (par.rxisoffhook)
09879                return 1;
09880             else
09881 #ifdef DAHDI_CHECK_HOOKSTATE
09882                return 0;
09883 #else
09884                return 1;
09885 #endif
09886          } else if (par.rxisoffhook) {
09887             ast_log(LOG_DEBUG, "Channel %d off hook, can't use\n", p->channel);
09888             /* Not available when the other end is off hook */
09889             return 0;
09890          }
09891       }
09892       return 1;
09893    }
09894 
09895    /* If it's not an FXO, forget about call wait */
09896    if ((p->sig != SIG_FXOKS) && (p->sig != SIG_FXOLS) && (p->sig != SIG_FXOGS)) 
09897       return 0;
09898 
09899    if (!p->callwaiting) {
09900       /* If they don't have call waiting enabled, then for sure they're unavailable at this point */
09901       return 0;
09902    }
09903 
09904    if (p->subs[SUB_CALLWAIT].dfd > -1) {
09905       /* If there is already a call waiting call, then we can't take a second one */
09906       return 0;
09907    }
09908    
09909    if ((p->owner->_state != AST_STATE_UP) &&
09910        ((p->owner->_state != AST_STATE_RINGING) || p->outgoing)) {
09911       /* If the current call is not up, then don't allow the call */
09912       return 0;
09913    }
09914    if ((p->subs[SUB_THREEWAY].owner) && (!p->subs[SUB_THREEWAY].inthreeway)) {
09915       /* Can't take a call wait when the three way calling hasn't been merged yet. */
09916       return 0;
09917    }
09918    /* We're cool */
09919    return 1;
09920 }
09921 
09922 static struct dahdi_pvt *chandup(struct dahdi_pvt *src)
09923 {
09924    struct dahdi_pvt *p;
09925    struct dahdi_bufferinfo bi;
09926    int res;
09927    
09928    if ((p = ast_malloc(sizeof(*p)))) {
09929       memcpy(p, src, sizeof(struct dahdi_pvt));
09930       ast_mutex_init(&p->lock);
09931       p->subs[SUB_REAL].dfd = dahdi_open(DAHDI_FILE_PSEUDO);
09932       /* Allocate a DAHDI structure */
09933       if (p->subs[SUB_REAL].dfd < 0) {
09934          ast_log(LOG_ERROR, "Unable to dup channel: %s\n",  strerror(errno));
09935          destroy_dahdi_pvt(&p);
09936          return NULL;
09937       }
09938       res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_BUFINFO, &bi);
09939       if (!res) {
09940          bi.txbufpolicy = p->buf_policy;
09941          bi.rxbufpolicy = p->buf_policy;
09942          bi.numbufs = p->buf_no;
09943          res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SET_BUFINFO, &bi);
09944          if (res < 0) {
09945             ast_log(LOG_WARNING, "Unable to set buffer policy on dup channel: %s\n", strerror(errno));
09946          }
09947       } else
09948          ast_log(LOG_WARNING, "Unable to check buffer policy on dup channel: %s\n", strerror(errno));
09949    }
09950    p->destroy = 1;
09951    p->next = iflist;
09952    p->prev = NULL;
09953    iflist = p;
09954    if (iflist->next)
09955       iflist->next->prev = p;
09956    return p;
09957 }
09958    
09959 
09960 #ifdef HAVE_PRI
09961 /*!
09962  * \internal
09963  * \brief Find an empty B-channel interface to use.
09964  *
09965  * \param pri PRI span control structure.
09966  * \param backwards TRUE if the search starts from higher channels.
09967  *
09968  * \note Assumes the pri->lock is already obtained.
09969  *
09970  * \retval array-index into private pointer array on success.
09971  * \retval -1 on error.
09972  */
09973 static int pri_find_empty_chan(struct dahdi_pri *pri, int backwards)
09974 {
09975    int x;
09976    if (backwards)
09977       x = pri->numchans;
09978    else
09979       x = 0;
09980    for (;;) {
09981       if (backwards && (x < 0))
09982          break;
09983       if (!backwards && (x >= pri->numchans))
09984          break;
09985       if (pri->pvts[x]
09986          && sig_pri_is_chan_available(pri->pvts[x])) {
09987          ast_log(LOG_DEBUG, "Found empty available channel %d/%d\n", 
09988             pri->pvts[x]->logicalspan, pri->pvts[x]->prioffset);
09989          return x;
09990       }
09991       if (backwards)
09992          x--;
09993       else
09994          x++;
09995    }
09996    return -1;
09997 }
09998 #endif
09999 
10000 static struct ast_channel *dahdi_request(const char *type, int format, void *data, int *cause)
10001 {
10002    ast_group_t groupmatch = 0;
10003    int channelmatch = -1;
10004    int roundrobin = 0;
10005    int callwait = 0;
10006    int busy = 0;
10007    struct dahdi_pvt *p;
10008    struct ast_channel *tmp = NULL;
10009    char *dest=NULL;
10010    int x;
10011    char *s;
10012    char opt=0;
10013    int res=0, y=0;
10014    int backwards = 0;
10015 #ifdef HAVE_PRI
10016    int crv;
10017    int bearer = -1;
10018    int trunkgroup;
10019    struct dahdi_pri *pri=NULL;
10020 #endif   
10021    struct dahdi_pvt *exit, *start, *end;
10022    ast_mutex_t *lock;
10023    int channelmatched = 0;
10024    int groupmatched = 0;
10025    
10026    /*
10027     * data is ---v
10028     * Dial(DAHDI/pseudo[/extension])
10029     * Dial(DAHDI/<channel#>[c|r<cadance#>|d][/extension])
10030     * Dial(DAHDI/<trunk_group#>:<crv#>[c|r<cadance#>|d][/extension])
10031     * Dial(DAHDI/(g|G|r|R)<group#(0-63)>[c|r<cadance#>|d][/extension])
10032     *
10033     * g - channel group allocation search forward
10034     * G - channel group allocation search backward
10035     * r - channel group allocation round robin search forward
10036     * R - channel group allocation round robin search backward
10037     *
10038     * c - Wait for DTMF digit to confirm answer
10039     * r<cadance#> - Set distintive ring cadance number
10040     * d - Force bearer capability for ISDN call to digital.
10041     */
10042 
10043    /* Assume we're locking the iflock */
10044    lock = &iflock;
10045    start = iflist;
10046    end = ifend;
10047    if (data) {
10048       dest = ast_strdupa((char *)data);
10049    } else {
10050       ast_log(LOG_WARNING, "Channel requested with no data\n");
10051       return NULL;
10052    }
10053    if (toupper(dest[0]) == 'G' || toupper(dest[0])=='R') {
10054       /* Retrieve the group number */
10055       char *stringp;
10056 
10057       stringp = dest + 1;
10058       s = strsep(&stringp, "/");
10059       if ((res = sscanf(s, "%30d%1c%30d", &x, &opt, &y)) < 1) {
10060          ast_log(LOG_WARNING, "Unable to determine group for data %s\n", (char *)data);
10061          return NULL;
10062       }
10063       groupmatch = ((ast_group_t) 1 << x);
10064       if (toupper(dest[0]) == 'G') {
10065          if (dest[0] == 'G') {
10066             backwards = 1;
10067             p = ifend;
10068          } else
10069             p = iflist;
10070       } else {
10071          if (dest[0] == 'R') {
10072             backwards = 1;
10073             p = round_robin[x]?round_robin[x]->prev:ifend;
10074             if (!p)
10075                p = ifend;
10076          } else {
10077             p = round_robin[x]?round_robin[x]->next:iflist;
10078             if (!p)
10079                p = iflist;
10080          }
10081          roundrobin = 1;
10082       }
10083    } else {
10084       char *stringp;
10085 
10086       stringp = dest;
10087       s = strsep(&stringp, "/");
10088       p = iflist;
10089       if (!strcasecmp(s, "pseudo")) {
10090          /* Special case for pseudo */
10091          x = CHAN_PSEUDO;
10092          channelmatch = x;
10093       } 
10094 #ifdef HAVE_PRI
10095       else if ((res = sscanf(s, "%30d:%30d%c%30d", &trunkgroup, &crv, &opt, &y)) > 1) {
10096          if ((trunkgroup < 1) || (crv < 1)) {
10097             ast_log(LOG_WARNING, "Unable to determine trunk group and CRV for data %s\n", (char *)data);
10098             return NULL;
10099          }
10100          res--;
10101          for (x = 0; x < NUM_SPANS; x++) {
10102             if (pris[x].trunkgroup == trunkgroup) {
10103                pri = pris + x;
10104                lock = &pri->lock;
10105                start = pri->crvs;
10106                end = pri->crvend;
10107                break;
10108             }
10109          }
10110          if (!pri) {
10111             ast_log(LOG_WARNING, "Unable to find trunk group %d\n", trunkgroup);
10112             return NULL;
10113          }
10114          channelmatch = crv;
10115          p = pris[x].crvs;
10116       }
10117 #endif   
10118       else if ((res = sscanf(s, "%30d%1c%30d", &x, &opt, &y)) < 1) {
10119          ast_log(LOG_WARNING, "Unable to determine channel for data %s\n", (char *)data);
10120          return NULL;
10121       } else {
10122          channelmatch = x;
10123       }
10124    }
10125    /* Search for an unowned channel */
10126    ast_mutex_lock(lock);
10127    exit = p;
10128    while (p && !tmp) {
10129       if (roundrobin)
10130          round_robin[x] = p;
10131 #if 0
10132       ast_verbose("name = %s, %d, %d, %llu\n",p->owner ? p->owner->name : "<none>", p->channel, channelmatch, groupmatch);
10133 #endif
10134 
10135       if (p && available(p, channelmatch, groupmatch, &busy, &channelmatched, &groupmatched)) {
10136          if (option_debug)
10137             ast_log(LOG_DEBUG, "Using channel %d\n", p->channel);
10138             if (p->inalarm) 
10139                goto next;
10140 
10141          callwait = (p->owner != NULL);
10142 #ifdef HAVE_PRI
10143          if (pri && (p->subs[SUB_REAL].dfd < 0)) {
10144             if (p->sig != SIG_FXSKS) {
10145                /* Gotta find an actual channel to use for this
10146                   CRV if this isn't a callwait */
10147                bearer = pri_find_empty_chan(pri, 0);
10148                if (bearer < 0) {
10149                   ast_log(LOG_NOTICE, "Out of bearer channels on span %d for call to CRV %d:%d\n", pri->span, trunkgroup, crv);
10150                   p = NULL;
10151                   break;
10152                }
10153                pri_assign_bearer(p, pri, pri->pvts[bearer]);
10154             } else {
10155                if (alloc_sub(p, 0)) {
10156                   ast_log(LOG_NOTICE, "Failed to allocate place holder pseudo channel!\n");
10157                   p = NULL;
10158                   break;
10159                } else
10160                   ast_log(LOG_DEBUG, "Allocated placeholder pseudo channel\n");
10161                p->pri = pri;
10162             }
10163          }
10164 #endif
10165 
10166 #ifdef HAVE_OPENR2
10167          if (p->mfcr2) {
10168             ast_mutex_lock(&p->lock);
10169             if (p->mfcr2call) {
10170                ast_mutex_unlock(&p->lock);
10171                ast_log(LOG_NOTICE, "Yay!, someone just beat us in the race for channel %d.\n", p->channel);
10172                goto next;
10173             }
10174             if (p->mfcr2block) {
10175                ast_mutex_unlock(&p->lock);
10176                ast_log(LOG_NOTICE, "Yay!, channel %d just got blocked (%d).\n", p->channel, p->mfcr2block);
10177                goto next;
10178             }
10179             p->mfcr2call = 1;
10180             ast_mutex_unlock(&p->lock);
10181          }
10182 #endif
10183 
10184          if (p->channel == CHAN_PSEUDO) {
10185             p = chandup(p);
10186             if (!p) {
10187                break;
10188             }
10189          }
10190          if (p->owner) {
10191             if (alloc_sub(p, SUB_CALLWAIT)) {
10192                p = NULL;
10193                break;
10194             }
10195          }
10196 #if defined(HAVE_PRI)
10197          switch (p->sig) {
10198          case SIG_GR303FXOKS:
10199          case SIG_GR303FXSKS:
10200          case SIG_PRI_LIB_HANDLE_CASES:
10201             /*
10202              * We already have the B channel reserved for this call.  We
10203              * just need to make sure that dahdi_hangup() has completed
10204              * cleaning up before continuing.
10205              */
10206             ast_mutex_lock(&p->lock);
10207             ast_mutex_unlock(&p->lock);
10208             break;
10209          default:
10210             break;
10211          }
10212 #endif   /* defined(HAVE_PRI) */
10213          p->outgoing = 1;
10214          tmp = dahdi_new(p, AST_STATE_RESERVED, 0, p->owner ? SUB_CALLWAIT : SUB_REAL, 0, 0);
10215          if (!tmp) {
10216             p->outgoing = 0;
10217 #if defined(HAVE_PRI)
10218             /*
10219              * This should be the last thing to clear when we are done with
10220              * the channel.
10221              */
10222             p->allocated = 0;
10223 #endif   /* defined(HAVE_PRI) */
10224          }
10225 #ifdef HAVE_PRI
10226          if (p->bearer) {
10227             /* Log owner to bearer channel, too */
10228             p->bearer->owner = tmp;
10229          }
10230 #endif         
10231          /* Make special notes */
10232          if (res > 1) {
10233             if (opt == 'c') {
10234                /* Confirm answer */
10235                p->confirmanswer = 1;
10236             } else if (opt == 'r') {
10237                /* Distinctive ring */
10238                if (res < 3)
10239                   ast_log(LOG_WARNING, "Distinctive ring missing identifier in '%s'\n", (char *)data);
10240                else
10241                   p->distinctivering = y;
10242             } else if (opt == 'd') {
10243                /* If this is an ISDN call, make it digital */
10244                p->digital = 1;
10245                if (tmp)
10246                   tmp->transfercapability = AST_TRANS_CAP_DIGITAL;
10247             } else {
10248                ast_log(LOG_WARNING, "Unknown option '%c' in '%s'\n", opt, (char *)data);
10249             }
10250          }
10251          /* Note if the call is a call waiting call */
10252          if (tmp && callwait)
10253             tmp->cdrflags |= AST_CDR_CALLWAIT;
10254          break;
10255       }
10256 next:
10257       if (backwards) {
10258          p = p->prev;
10259          if (!p)
10260             p = end;
10261       } else {
10262          p = p->next;
10263          if (!p)
10264             p = start;
10265       }
10266       /* stop when you roll to the one that we started from */
10267       if (p == exit)
10268          break;
10269    }
10270    ast_mutex_unlock(lock);
10271    restart_monitor();
10272    if (callwait)
10273       *cause = AST_CAUSE_BUSY;
10274    else if (!tmp) {
10275       if (channelmatched) {
10276          if (busy)
10277             *cause = AST_CAUSE_BUSY;
10278       } else if (groupmatched) {
10279          *cause = AST_CAUSE_CONGESTION;
10280       }
10281    }
10282       
10283    return tmp;
10284 }
10285 
10286 #ifdef HAVE_OPENR2
10287 static void *mfcr2_monitor(void *data)
10288 {
10289    struct dahdi_pvt *p;
10290    struct dahdi_mfcr2 *mfcr2 = data;
10291    /* we should be using pthread_key_create
10292       and allocate pollers dynamically.
10293       I think do_monitor() could be leaking, since it
10294       could be cancelled at any time and is not
10295       using thread keys, why?, */
10296    struct pollfd pollers[mfcr2->numchans];
10297    int maxsleep = 20;
10298    int res = 0;
10299    int i = 0;
10300    int pollsize = 0;
10301    int oldstate = 0;
10302    int was_idle = 0;
10303    int quit_loop = 0;
10304    /* now that we're ready to get calls, unblock our side and
10305       get current line state */
10306    for (i = 0; i < mfcr2->numchans; i++) {
10307       p = mfcr2->pvts[i];
10308       pollers[i].fd = mfcr2->pvts[i]->subs[SUB_REAL].dfd;
10309       if (openr2_chan_set_idle(p->r2chan)) {
10310          ast_log(LOG_ERROR, "Failed to set channel %d in IDLE\n", p->channel);
10311       } else {
10312          ast_mutex_lock(&p->lock);
10313          mfcr2->pvts[i]->mfcr2block &= ~DAHDI_R2_LOCAL_BLOCK;
10314          mfcr2->pvts[i]->mfcr2call = 0;
10315          ast_mutex_unlock(&p->lock);
10316       }
10317       openr2_chan_handle_cas(mfcr2->pvts[i]->r2chan);
10318    }
10319    while(1) {
10320       /* we trust here that the mfcr2 channel list will not ever change once
10321          the module is loaded */
10322       pollsize = 0;
10323       for (i = 0; i < mfcr2->numchans; i++) {
10324          pollers[i].events = 0;
10325          pollers[i].revents = 0;
10326          if (mfcr2->pvts[i]->owner) {
10327             continue;
10328          }
10329          if (!mfcr2->pvts[i]->r2chan) {
10330             ast_log(LOG_DEBUG, "Wow, no r2chan on channel %d\n", mfcr2->pvts[i]->channel);
10331             quit_loop = 1;
10332             break;
10333          }
10334          openr2_chan_enable_read(mfcr2->pvts[i]->r2chan);
10335          pollers[i].events = POLLIN | POLLPRI;
10336          pollsize++;
10337       }
10338       if (quit_loop) {
10339          break;
10340       }
10341 
10342       if (pollsize == 0) {
10343          if (!was_idle) {
10344             ast_log(LOG_NOTICE, "Monitor thread going idle since everybody has an owner\n");
10345             was_idle = 1;
10346          }
10347          poll(NULL, 0, maxsleep);
10348          continue;
10349       }
10350       was_idle = 0;
10351 
10352       /* probably poll() is a valid cancel point, lets just be on the safe side
10353          by calling pthread_testcancel */
10354       pthread_testcancel();
10355       res = poll(pollers, mfcr2->numchans, maxsleep);
10356       pthread_testcancel();
10357       if ((res < 0) && (errno != EINTR)) {
10358          ast_log(LOG_ERROR, "going out, poll failed: %s\n", strerror(errno));
10359          break;
10360       } 
10361       /* do we want to allow to cancel while processing events? */
10362       pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate);
10363       for (i = 0; i < mfcr2->numchans; i++) {
10364          if ((pollers[i].revents & POLLPRI) || (pollers[i].revents & POLLIN)) {
10365             openr2_chan_process_event(mfcr2->pvts[i]->r2chan);
10366          }
10367       }
10368       pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
10369    }
10370    ast_log(LOG_NOTICE, "Quitting MFC/R2 monitor thread\n");
10371    return 0;
10372 }
10373 #endif
10374 
10375 #if defined(HAVE_PRI)
10376 static struct dahdi_pvt *pri_find_crv(struct dahdi_pri *pri, int crv)
10377 {
10378    struct dahdi_pvt *p;
10379    p = pri->crvs;
10380    while (p) {
10381       if (p->channel == crv)
10382          return p;
10383       p = p->next;
10384    }
10385    return NULL;
10386 }
10387 #endif   /* defined(HAVE_PRI) */
10388 
10389 #if defined(HAVE_PRI)
10390 /*!
10391  * \internal
10392  * \brief Obtain the DAHDI owner channel lock if the owner exists.
10393  * \since 1.8
10394  *
10395  * \param pri PRI span control structure.
10396  * \param chanpos Channel position in the span.
10397  *
10398  * \note Assumes the pri->lock is already obtained.
10399  * \note Assumes the pri->pvts[chanpos]->lock is already obtained.
10400  *
10401  * \return Nothing
10402  */
10403 static void sig_pri_lock_owner(struct dahdi_pri *pri, int chanpos)
10404 {
10405    for (;;) {
10406       if (!pri->pvts[chanpos]->owner) {
10407          /* There is no owner lock to get. */
10408          break;
10409       }
10410       if (!ast_channel_trylock(pri->pvts[chanpos]->owner)) {
10411          /* We got the lock */
10412          break;
10413       }
10414       /* We must unlock the PRI to avoid the possibility of a deadlock */
10415       ast_mutex_unlock(&pri->lock);
10416       DEADLOCK_AVOIDANCE(&pri->pvts[chanpos]->lock);
10417       ast_mutex_lock(&pri->lock);
10418    }
10419 }
10420 #endif   /* defined(HAVE_PRI) */
10421 
10422 #if defined(HAVE_PRI)
10423 /*!
10424  * \internal
10425  * \brief Queue the given frame onto the owner channel.
10426  * \since 1.8
10427  *
10428  * \param pri PRI span control structure.
10429  * \param chanpos Channel position in the span.
10430  * \param frame Frame to queue onto the owner channel.
10431  *
10432  * \note Assumes the pri->lock is already obtained.
10433  * \note Assumes the sig_pri_lock_private(pri->pvts[chanpos]) is already obtained.
10434  *
10435  * \return Nothing
10436  */
10437 static void pri_queue_frame(struct dahdi_pri *pri, int chanpos, struct ast_frame *frame)
10438 {
10439    sig_pri_lock_owner(pri, chanpos);
10440    if (pri->pvts[chanpos]->owner) {
10441       ast_queue_frame(pri->pvts[chanpos]->owner, frame);
10442       ast_channel_unlock(pri->pvts[chanpos]->owner);
10443    }
10444 }
10445 #endif   /* defined(HAVE_PRI) */
10446 
10447 #if defined(HAVE_PRI)
10448 /*!
10449  * \internal
10450  * \brief Queue a control frame of the specified subclass onto the owner channel.
10451  * \since 1.8
10452  *
10453  * \param pri PRI span control structure.
10454  * \param chanpos Channel position in the span.
10455  * \param subclass Control frame subclass to queue onto the owner channel.
10456  *
10457  * \note Assumes the pri->lock is already obtained.
10458  * \note Assumes the sig_pri_lock_private(pri->pvts[chanpos]) is already obtained.
10459  *
10460  * \return Nothing
10461  */
10462 static void pri_queue_control(struct dahdi_pri *pri, int chanpos, int subclass)
10463 {
10464    struct ast_frame f = {AST_FRAME_CONTROL, };
10465 
10466    f.subclass = subclass;
10467    pri_queue_frame(pri, chanpos, &f);
10468 }
10469 #endif   /* defined(HAVE_PRI) */
10470 
10471 #if defined(HAVE_PRI)
10472 /*!
10473  * \internal
10474  * \brief Find the channel associated with the libpri call.
10475  * \since 1.10
10476  *
10477  * \param pri PRI span control structure.
10478  * \param call LibPRI opaque call pointer to find.
10479  *
10480  * \note Assumes the pri->lock is already obtained.
10481  *
10482  * \retval array-index into private pointer array on success.
10483  * \retval -1 on error.
10484  */
10485 static int pri_find_principle_by_call(struct dahdi_pri *pri, q931_call *call)
10486 {
10487    int idx;
10488 
10489    if (!call) {
10490       /* Cannot find a call without a call. */
10491       return -1;
10492    }
10493    for (idx = 0; idx < pri->numchans; ++idx) {
10494       if (pri->pvts[idx] && pri->pvts[idx]->call == call) {
10495          /* Found the principle */
10496          return idx;
10497       }
10498    }
10499    return -1;
10500 }
10501 #endif   /* defined(HAVE_PRI) */
10502 
10503 #if defined(HAVE_PRI)
10504 /*!
10505  * \internal
10506  * \brief Kill the call.
10507  * \since 1.10
10508  *
10509  * \param pri PRI span control structure.
10510  * \param call LibPRI opaque call pointer to find.
10511  * \param cause Reason call was killed.
10512  *
10513  * \note Assumes the pvt->pri->lock is already obtained.
10514  *
10515  * \return Nothing
10516  */
10517 static void sig_pri_kill_call(struct dahdi_pri *pri, q931_call *call, int cause)
10518 {
10519    int chanpos;
10520 
10521    chanpos = pri_find_principle_by_call(pri, call);
10522    if (chanpos < 0) {
10523       pri_hangup(pri->pri, call, cause);
10524       return;
10525    }
10526    ast_mutex_lock(&pri->pvts[chanpos]->lock);
10527    if (!pri->pvts[chanpos]->owner) {
10528       pri_hangup(pri->pri, call, cause);
10529       pri->pvts[chanpos]->call = NULL;
10530       ast_mutex_unlock(&pri->pvts[chanpos]->lock);
10531       return;
10532    }
10533    pri->pvts[chanpos]->owner->hangupcause = cause;
10534    pri_queue_control(pri, chanpos, AST_CONTROL_HANGUP);
10535    ast_mutex_unlock(&pri->pvts[chanpos]->lock);
10536 }
10537 #endif   /* defined(HAVE_PRI) */
10538 
10539 #if defined(HAVE_PRI)
10540 /*!
10541  * \internal
10542  * \brief Find the private structure for the libpri call.
10543  *
10544  * \param pri PRI span control structure.
10545  * \param channel LibPRI encoded channel ID.
10546  *
10547  * \note Assumes the pri->lock is already obtained.
10548  *
10549  * \retval array-index into private pointer array on success.
10550  * \retval -1 on error.
10551  */
10552 static int pri_find_principle(struct dahdi_pri *pri, int channel)
10553 {
10554    int x;
10555    int span = PRI_SPAN(channel);
10556    int spanfd;
10557    struct dahdi_params param;
10558    int principle = -1;
10559    int explicit = PRI_EXPLICIT(channel);
10560    channel = PRI_CHANNEL(channel);
10561 
10562    if (!explicit) {
10563       spanfd = pri_active_dchan_fd(pri);
10564       memset(&param, 0, sizeof(param));
10565       if (ioctl(spanfd, DAHDI_GET_PARAMS, &param))
10566          return -1;
10567       span = pris[param.spanno - 1].prilogicalspan;
10568    }
10569 
10570    for (x = 0; x < pri->numchans; x++) {
10571       if (pri->pvts[x] && (pri->pvts[x]->prioffset == channel) && (pri->pvts[x]->logicalspan == span)) {
10572          principle = x;
10573          break;
10574       }
10575    }
10576    
10577    return principle;
10578 }
10579 #endif   /* defined(HAVE_PRI) */
10580 
10581 #if defined(HAVE_PRI)
10582 /*!
10583  * \internal
10584  * \brief Fixup the private structure associated with the libpri call.
10585  *
10586  * \param pri PRI span control structure.
10587  * \param principle Array-index into private array to move call to if not already there.
10588  * \param c LibPRI opaque call pointer to find if need to move call.
10589  *
10590  * \note Assumes the pri->lock is already obtained.
10591  *
10592  * \retval principle on success.
10593  * \retval -1 on error.
10594  */
10595 static int pri_fixup_principle(struct dahdi_pri *pri, int principle, q931_call *c)
10596 {
10597    int x;
10598    struct dahdi_pvt *crv;
10599    if (!c) {
10600       if (principle < 0)
10601          return -1;
10602       return principle;
10603    }
10604    if ((principle > -1) && 
10605       (principle < pri->numchans) && 
10606       (pri->pvts[principle]) && 
10607       (pri->pvts[principle]->call == c))
10608       return principle;
10609    /* First, check for other bearers */
10610    for (x = 0; x < pri->numchans; x++) {
10611       if (!pri->pvts[x])
10612          continue;
10613       if (pri->pvts[x]->call == c) {
10614          /* Found our call */
10615          if (principle != x) {
10616             struct dahdi_pvt *new = pri->pvts[principle], *old = pri->pvts[x];
10617 
10618             /* Get locks to safely move to the new private structure. */
10619             ast_mutex_lock(&old->lock);
10620             sig_pri_lock_owner(pri, x);
10621             ast_mutex_lock(&new->lock);
10622 
10623             if (option_verbose > 2) {
10624                ast_verbose(VERBOSE_PREFIX_3
10625                   "Moving call (%s) from channel %d to %d.\n",
10626                   old->owner ? old->owner->name : "",
10627                   old->channel, new->channel);
10628             }
10629             if (!sig_pri_is_chan_available(new)) {
10630                ast_log(LOG_WARNING,
10631                   "Can't move call (%s) from channel %d to %d.  It is already in use.\n",
10632                   old->owner ? old->owner->name : "",
10633                   old->channel, new->channel);
10634                ast_mutex_unlock(&new->lock);
10635                if (old->owner) {
10636                   ast_mutex_unlock(&old->owner->lock);
10637                }
10638                ast_mutex_unlock(&old->lock);
10639                return -1;
10640             }
10641 
10642             /* Fix it all up now */
10643             new->owner = old->owner;
10644             old->owner = NULL;
10645             if (new->owner) {
10646                ast_string_field_build(new->owner, name, "%s/%d:%d-%d", dahdi_chan_name, pri->trunkgroup, new->channel, 1);
10647                new->owner->tech_pvt = new;
10648                new->owner->fds[0] = new->subs[SUB_REAL].dfd;
10649                new->subs[SUB_REAL].owner = old->subs[SUB_REAL].owner;
10650                old->subs[SUB_REAL].owner = NULL;
10651             } else
10652                ast_log(LOG_WARNING, "Whoa, there's no owner, and we're having to fix up channel %d to channel %d\n", old->channel, new->channel);
10653             new->call = old->call;
10654             old->call = NULL;
10655 
10656             /* Copy any DSP that may be present */
10657             new->dsp = old->dsp;
10658             new->dsp_features = old->dsp_features;
10659             old->dsp = NULL;
10660             old->dsp_features = 0;
10661 
10662             /* Transfer flags from the old channel. */
10663             new->alreadyhungup = old->alreadyhungup;
10664             new->isidlecall = old->isidlecall;
10665             new->progress = old->progress;
10666             new->allocated = old->allocated;
10667             new->outgoing = old->outgoing;
10668             new->digital = old->digital;
10669             old->alreadyhungup = 0;
10670             old->isidlecall = 0;
10671             old->progress = 0;
10672             old->allocated = 0;
10673             old->outgoing = 0;
10674             old->digital = 0;
10675 
10676             /* More stuff to transfer to the new channel. */
10677             new->call_level = old->call_level;
10678             old->call_level = DAHDI_CALL_LEVEL_IDLE;
10679  
10680             ast_mutex_unlock(&old->lock);
10681             if (new->owner) {
10682                ast_mutex_unlock(&new->owner->lock);
10683             }
10684             ast_mutex_unlock(&new->lock);
10685          }
10686          return principle;
10687       }
10688    }
10689    /* Now check for a CRV with no bearer */
10690    crv = pri->crvs;
10691    while (crv) {
10692       if (crv->call == c) {
10693          /* This is our match...  Perform some basic checks */
10694          if (crv->bearer)
10695             ast_log(LOG_WARNING, "Trying to fix up call which already has a bearer which isn't the one we think it is\n");
10696          else if (pri->pvts[principle]->owner) 
10697             ast_log(LOG_WARNING, "Tring to fix up a call to a bearer which already has an owner!\n");
10698          else {
10699             /* Looks good.  Drop the pseudo channel now, clear up the assignment, and
10700                wakeup the potential sleeper */
10701             dahdi_close_sub(crv, SUB_REAL);
10702             pri->pvts[principle]->call = crv->call;
10703             pri_assign_bearer(crv, pri, pri->pvts[principle]);
10704             ast_log(LOG_DEBUG, "Assigning bearer %d/%d to CRV %d:%d\n",
10705                            pri->pvts[principle]->logicalspan, pri->pvts[principle]->prioffset,
10706                            pri->trunkgroup, crv->channel);
10707             wakeup_sub(crv, SUB_REAL, pri);
10708          }
10709          return principle;
10710       }
10711       crv = crv->next;
10712    }
10713    ast_log(LOG_WARNING, "Call specified, but not found?\n");
10714    return -1;
10715 }
10716 #endif   /* defined(HAVE_PRI) */
10717 
10718 #if defined(HAVE_PRI)
10719 /*!
10720  * \internal
10721  * \brief Find and fixup the private structure associated with the libpri call.
10722  *
10723  * \param pri PRI span control structure.
10724  * \param channel LibPRI encoded channel ID.
10725  * \param call LibPRI opaque call pointer.
10726  *
10727  * \details
10728  * This is a combination of pri_find_principle() and pri_fixup_principle()
10729  * to reduce code redundancy and to make handling several PRI_EVENT_xxx's
10730  * consistent for the current architecture.
10731  *
10732  * \note Assumes the pri->lock is already obtained.
10733  *
10734  * \retval array-index into private pointer array on success.
10735  * \retval -1 on error.
10736  */
10737 static int pri_find_fixup_principle(struct dahdi_pri *pri, int channel, q931_call *call)
10738 {
10739    int chanpos;
10740 
10741    chanpos = pri_find_principle(pri, channel);
10742    if (chanpos < 0) {
10743       ast_log(LOG_WARNING, "Span %d: PRI requested channel %d/%d is unconfigured.\n",
10744          pri->span, PRI_SPAN(channel), PRI_CHANNEL(channel));
10745       sig_pri_kill_call(pri, call, PRI_CAUSE_IDENTIFIED_CHANNEL_NOTEXIST);
10746       return -1;
10747    }
10748    chanpos = pri_fixup_principle(pri, chanpos, call);
10749    if (chanpos < 0) {
10750       ast_log(LOG_WARNING, "Span %d: PRI requested channel %d/%d is not available.\n",
10751          pri->span, PRI_SPAN(channel), PRI_CHANNEL(channel));
10752       /*
10753        * Using Q.931 section 5.2.3.1 b) as the reason for picking
10754        * PRI_CAUSE_CHANNEL_UNACCEPTABLE.  Receiving a
10755        * PRI_CAUSE_REQUESTED_CHAN_UNAVAIL would cause us to restart
10756        * that channel (which is not specified by Q.931) and kill some
10757        * other call which would be bad.
10758        */
10759       sig_pri_kill_call(pri, call, PRI_CAUSE_CHANNEL_UNACCEPTABLE);
10760       return -1;
10761    }
10762    return chanpos;
10763 }
10764 #endif   /* defined(HAVE_PRI) */
10765 
10766 #if defined(HAVE_PRI)
10767 static void *do_idle_thread(void *vchan)
10768 {
10769    struct ast_channel *chan = vchan;
10770    struct dahdi_pvt *pvt = chan->tech_pvt;
10771    struct ast_frame *f;
10772    char ex[80];
10773    /* Wait up to 30 seconds for an answer */
10774    int newms, ms = 30000;
10775    if (option_verbose > 2) 
10776       ast_verbose(VERBOSE_PREFIX_3 "Initiating idle call on channel %s\n", chan->name);
10777    snprintf(ex, sizeof(ex), "%d/%s", pvt->channel, pvt->pri->idledial);
10778    if (ast_call(chan, ex, 0)) {
10779       ast_log(LOG_WARNING, "Idle dial failed on '%s' to '%s'\n", chan->name, ex);
10780       ast_hangup(chan);
10781       return NULL;
10782    }
10783    while ((newms = ast_waitfor(chan, ms)) > 0) {
10784       f = ast_read(chan);
10785       if (!f) {
10786          /* Got hangup */
10787          break;
10788       }
10789       if (f->frametype == AST_FRAME_CONTROL) {
10790          switch (f->subclass) {
10791          case AST_CONTROL_ANSWER:
10792             /* Launch the PBX */
10793             ast_copy_string(chan->exten, pvt->pri->idleext, sizeof(chan->exten));
10794             ast_copy_string(chan->context, pvt->pri->idlecontext, sizeof(chan->context));
10795             chan->priority = 1;
10796             if (option_verbose > 3) 
10797                ast_verbose(VERBOSE_PREFIX_3 "Idle channel '%s' answered, sending to %s@%s\n", chan->name, chan->exten, chan->context);
10798             ast_pbx_run(chan);
10799             /* It's already hungup, return immediately */
10800             return NULL;
10801          case AST_CONTROL_BUSY:
10802             if (option_verbose > 3) 
10803                ast_verbose(VERBOSE_PREFIX_3 "Idle channel '%s' busy, waiting...\n", chan->name);
10804             break;
10805          case AST_CONTROL_CONGESTION:
10806             if (option_verbose > 3) 
10807                ast_verbose(VERBOSE_PREFIX_3 "Idle channel '%s' congested, waiting...\n", chan->name);
10808             break;
10809          };
10810       }
10811       ast_frfree(f);
10812       ms = newms;
10813    }
10814    /* Hangup the channel since nothing happend */
10815    ast_hangup(chan);
10816    return NULL;
10817 }
10818 
10819 #ifndef PRI_RESTART
10820 #error "Upgrade your libpri"
10821 #endif
10822 static void dahdi_pri_message(struct pri *pri, char *s)
10823 {
10824    int x, y;
10825    int dchan = -1, span = -1;
10826    int dchancount = 0;
10827 
10828    if (pri) {
10829       for (x = 0; x < NUM_SPANS; x++) {
10830          for (y = 0; y < NUM_DCHANS; y++) {
10831             if (pris[x].dchans[y])
10832                dchancount++;
10833 
10834             if (pris[x].dchans[y] == pri)
10835                dchan = y;
10836          }
10837          if (dchan >= 0) {
10838             span = x;
10839             break;
10840          }
10841          dchancount = 0;
10842       }
10843       if ((dchan >= 0) && (span >= 0)) {
10844          if (dchancount > 1)
10845             ast_verbose("[Span %d D-Channel %d]%s", span, dchan, s);
10846          else
10847             ast_verbose("%s", s);
10848       } else
10849          ast_log(LOG_ERROR, "PRI debug error: could not find pri associated it with debug message output\n");
10850    } else
10851       ast_verbose("%s", s);
10852 
10853    ast_mutex_lock(&pridebugfdlock);
10854 
10855    if (pridebugfd >= 0) {
10856       if (write(pridebugfd, s, strlen(s)) < 0) {
10857          ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
10858       }
10859    }
10860 
10861    ast_mutex_unlock(&pridebugfdlock);
10862 }
10863 
10864 static void dahdi_pri_error(struct pri *pri, char *s)
10865 {
10866    int x, y;
10867    int dchan = -1, span = -1;
10868    int dchancount = 0;
10869 
10870    if (pri) {
10871       for (x = 0; x < NUM_SPANS; x++) {
10872          for (y = 0; y < NUM_DCHANS; y++) {
10873             if (pris[x].dchans[y])
10874                dchancount++;
10875 
10876             if (pris[x].dchans[y] == pri)
10877                dchan = y;
10878          }
10879          if (dchan >= 0) {
10880             span = x;
10881             break;
10882          }
10883          dchancount = 0;
10884       }
10885       if ((dchan >= 0) && (span >= 0)) {
10886          if (dchancount > 1)
10887             ast_log(LOG_ERROR, "[Span %d D-Channel %d] PRI: %s", span, dchan, s);
10888          else
10889             ast_log(LOG_ERROR, "%s", s);
10890       } else
10891          ast_log(LOG_ERROR, "PRI debug error: could not find pri associated it with debug message output\n");
10892    } else
10893       ast_log(LOG_ERROR, "%s", s);
10894 
10895    ast_mutex_lock(&pridebugfdlock);
10896 
10897    if (pridebugfd >= 0) {
10898       if (write(pridebugfd, s, strlen(s)) < 0) {
10899          ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
10900       }
10901    }
10902 
10903    ast_mutex_unlock(&pridebugfdlock);
10904 }
10905 
10906 /*!
10907  * \internal
10908  * \brief Restart the next channel we think is idle on the span.
10909  *
10910  * \param pri PRI span control structure.
10911  *
10912  * \note Assumes the pri->lock is already obtained.
10913  *
10914  * \return Nothing
10915  */
10916 static void pri_check_restart(struct dahdi_pri *pri)
10917 {
10918    for (++pri->resetpos; pri->resetpos < pri->numchans; ++pri->resetpos) {
10919       if (!pri->pvts[pri->resetpos]
10920          || sig_pri_is_chan_in_use(pri->pvts[pri->resetpos])) {
10921          continue;
10922       }
10923       break;
10924    }
10925    if (pri->resetpos < pri->numchans) {
10926       /* Mark the channel as resetting and restart it */
10927       pri->pvts[pri->resetpos]->resetting = 1;
10928       pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[pri->resetpos]));
10929    } else {
10930       pri->resetting = 0;
10931       time(&pri->lastreset);
10932    }
10933 }
10934 
10935 static int pri_hangup_all(struct dahdi_pvt *p, struct dahdi_pri *pri)
10936 {
10937    int x;
10938    int redo;
10939    ast_mutex_unlock(&pri->lock);
10940    ast_mutex_lock(&p->lock);
10941    do {
10942       redo = 0;
10943       for (x = 0; x < 3; x++) {
10944          while (p->subs[x].owner && ast_mutex_trylock(&p->subs[x].owner->lock)) {
10945             redo++;
10946             DEADLOCK_AVOIDANCE(&p->lock);
10947          }
10948          if (p->subs[x].owner) {
10949             ast_queue_hangup(p->subs[x].owner);
10950             ast_mutex_unlock(&p->subs[x].owner->lock);
10951          }
10952       }
10953    } while (redo);
10954    ast_mutex_unlock(&p->lock);
10955    ast_mutex_lock(&pri->lock);
10956    return 0;
10957 }
10958 
10959 static char * redirectingreason2str(int redirectingreason)
10960 {
10961    switch (redirectingreason) {
10962    case 0:
10963       return "UNKNOWN";
10964    case 1:
10965       return "BUSY";
10966    case 2:
10967       return "NO_REPLY";
10968    case 0xF:
10969       return "UNCONDITIONAL";
10970    default:
10971       return "NOREDIRECT";
10972    }
10973 }
10974 
10975 static void apply_plan_to_number(char *buf, size_t size, const struct dahdi_pri *pri, const char *number, const int plan)
10976 {
10977    if (ast_strlen_zero(number)) { /* make sure a number exists so prefix isn't placed on an empty string */
10978       if (size) {
10979          *buf = '\0';
10980       }
10981       return;
10982    }
10983 
10984    switch (plan) {
10985    case PRI_INTERNATIONAL_ISDN:     /* Q.931 dialplan == 0x11 international dialplan => prepend international prefix digits */
10986       snprintf(buf, size, "%s%s", pri->internationalprefix, number);
10987       break;
10988    case PRI_NATIONAL_ISDN:       /* Q.931 dialplan == 0x21 national dialplan => prepend national prefix digits */
10989       snprintf(buf, size, "%s%s", pri->nationalprefix, number);
10990       break;
10991    case PRI_LOCAL_ISDN:       /* Q.931 dialplan == 0x41 local dialplan => prepend local prefix digits */
10992       snprintf(buf, size, "%s%s", pri->localprefix, number);
10993       break;
10994    case PRI_PRIVATE:       /* Q.931 dialplan == 0x49 private dialplan => prepend private prefix digits */
10995       snprintf(buf, size, "%s%s", pri->privateprefix, number);
10996       break;
10997    case PRI_UNKNOWN:       /* Q.931 dialplan == 0x00 unknown dialplan => prepend unknown prefix digits */
10998       snprintf(buf, size, "%s%s", pri->unknownprefix, number);
10999       break;
11000    default:          /* other Q.931 dialplan => don't twiddle with callingnum */
11001       snprintf(buf, size, "%s", number);
11002       break;
11003    }
11004 }
11005 
11006 static int dahdi_setlaw(int dfd, int law)
11007 {
11008    int res;
11009    res = ioctl(dfd, DAHDI_SETLAW, &law);
11010    if (res)
11011       return res;
11012    return 0;
11013 }
11014 
11015 static void *pri_dchannel(void *vpri)
11016 {
11017    struct dahdi_pri *pri = vpri;
11018    pri_event *e;
11019    struct pollfd fds[NUM_DCHANS];
11020    int res;
11021    int chanpos = 0;
11022    int x;
11023    int haveidles;
11024    int activeidles;
11025    int nextidle = -1;
11026    struct ast_channel *c;
11027    struct timeval tv, lowest, *next;
11028    struct timeval lastidle = { 0, 0 };
11029    int doidling=0;
11030    char *cc;
11031    char idlen[80];
11032    struct ast_channel *idle;
11033    pthread_t p;
11034    time_t t;
11035    int i, which=-1;
11036    int numdchans;
11037    int cause=0;
11038    struct dahdi_pvt *crv;
11039    pthread_t threadid;
11040    pthread_attr_t attr;
11041    char ani2str[6];
11042    char plancallingnum[256];
11043    char plancallingani[256];
11044    char calledtonstr[10];
11045    unsigned int len;
11046 
11047    pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
11048 
11049    gettimeofday(&lastidle, NULL);
11050    if (!ast_strlen_zero(pri->idledial) && !ast_strlen_zero(pri->idleext)) {
11051       /* Need to do idle dialing, check to be sure though */
11052       cc = strchr(pri->idleext, '@');
11053       if (cc) {
11054          *cc = '\0';
11055          cc++;
11056          ast_copy_string(pri->idlecontext, cc, sizeof(pri->idlecontext));
11057 #if 0
11058          /* Extensions may not be loaded yet */
11059          if (!ast_exists_extension(NULL, pri->idlecontext, pri->idleext, 1, NULL))
11060             ast_log(LOG_WARNING, "Extension '%s @ %s' does not exist\n", pri->idleext, pri->idlecontext);
11061          else
11062 #endif
11063             doidling = 1;
11064       } else
11065          ast_log(LOG_WARNING, "Idle dial string '%s' lacks '@context'\n", pri->idleext);
11066    }
11067    for (;;) {
11068       for (i = 0; i < NUM_DCHANS; i++) {
11069          if (!pri->dchannels[i])
11070             break;
11071          fds[i].fd = pri->fds[i];
11072          fds[i].events = POLLIN | POLLPRI;
11073          fds[i].revents = 0;
11074       }
11075       numdchans = i;
11076       time(&t);
11077       ast_mutex_lock(&pri->lock);
11078       if (pri->switchtype != PRI_SWITCH_GR303_TMC && (pri->resetinterval > 0)) {
11079          if (pri->resetting && pri_is_up(pri)) {
11080             if (pri->resetpos < 0) {
11081                pri_check_restart(pri);
11082             }
11083          } else {
11084             if (!pri->resetting  && (t - pri->lastreset) >= pri->resetinterval) {
11085                pri->resetting = 1;
11086                pri->resetpos = -1;
11087             }
11088          }
11089       }
11090       /* Look for any idle channels if appropriate */
11091       if (doidling && pri_is_up(pri)) {
11092          nextidle = -1;
11093          haveidles = 0;
11094          activeidles = 0;
11095          for (x = pri->numchans; x >= 0; x--) {
11096             if (pri->pvts[x]) {
11097                if (sig_pri_is_chan_available(pri->pvts[x])) {
11098                   if (haveidles < pri->minunused) {
11099                      haveidles++;
11100                   } else {
11101                      nextidle = x;
11102                      break;
11103                   }
11104                } else if (pri->pvts[x]->owner && pri->pvts[x]->isidlecall) {
11105                   activeidles++;
11106                }
11107             }
11108          }
11109          if (nextidle > -1) {
11110             if (ast_tvdiff_ms(ast_tvnow(), lastidle) > 1000) {
11111                /* Don't create a new idle call more than once per second */
11112                snprintf(idlen, sizeof(idlen), "%d/%s", pri->pvts[nextidle]->channel, pri->idledial);
11113                /*
11114                 * Release the PRI lock while we create the channel so other
11115                 * threads can send D channel messages.
11116                 */
11117                ast_mutex_unlock(&pri->lock);
11118                idle = dahdi_request(dahdi_chan_name, AST_FORMAT_ULAW, idlen, &cause);
11119                ast_mutex_lock(&pri->lock);
11120                if (idle) {
11121                   pri->pvts[nextidle]->isidlecall = 1;
11122                   if (ast_pthread_create_background(&p, NULL, do_idle_thread, idle)) {
11123                      ast_log(LOG_WARNING, "Unable to start new thread for idle channel '%s'\n", idle->name);
11124                      ast_mutex_unlock(&pri->lock);
11125                      ast_hangup(idle);
11126                      ast_mutex_lock(&pri->lock);
11127                   }
11128                } else {
11129                   ast_log(LOG_WARNING, "Unable to request channel 'DAHDI/%s' for idle call\n", idlen);
11130                }
11131                gettimeofday(&lastidle, NULL);
11132             }
11133          } else if ((haveidles < pri->minunused) &&
11134                (activeidles > pri->minidle)) {
11135             /* Mark something for hangup if there is something 
11136                that can be hungup */
11137             for (x = pri->numchans; x >= 0; x--) {
11138                /* find a candidate channel */
11139                if (pri->pvts[x] && pri->pvts[x]->owner && pri->pvts[x]->isidlecall) {
11140                   pri->pvts[x]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
11141                   haveidles++;
11142                   /* Stop if we have enough idle channels or
11143                     can't spare any more active idle ones */
11144                   if ((haveidles >= pri->minunused) ||
11145                       (activeidles <= pri->minidle))
11146                      break;
11147                } 
11148             }
11149          }
11150       }
11151       /* Start with reasonable max */
11152       lowest = ast_tv(60, 0);
11153       for (i = 0; i < NUM_DCHANS; i++) {
11154          /* Find lowest available d-channel */
11155          if (!pri->dchannels[i])
11156             break;
11157          if ((next = pri_schedule_next(pri->dchans[i]))) {
11158             /* We need relative time here */
11159             tv = ast_tvsub(*next, ast_tvnow());
11160             if (tv.tv_sec < 0) {
11161                tv = ast_tv(0,0);
11162             }
11163             if (doidling || pri->resetting) {
11164                if (tv.tv_sec > 1) {
11165                   tv = ast_tv(1, 0);
11166                }
11167             } else {
11168                if (tv.tv_sec > 60) {
11169                   tv = ast_tv(60, 0);
11170                }
11171             }
11172          } else if (doidling || pri->resetting) {
11173             /* Make sure we stop at least once per second if we're
11174                monitoring idle channels */
11175             tv = ast_tv(1,0);
11176          } else {
11177             /* Don't poll for more than 60 seconds */
11178             tv = ast_tv(60, 0);
11179          }
11180          if (!i || ast_tvcmp(tv, lowest) < 0) {
11181             lowest = tv;
11182          }
11183       }
11184       ast_mutex_unlock(&pri->lock);
11185 
11186       pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
11187       pthread_testcancel();
11188       e = NULL;
11189       res = poll(fds, numdchans, lowest.tv_sec * 1000 + lowest.tv_usec / 1000);
11190       pthread_testcancel();
11191       pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
11192 
11193       ast_mutex_lock(&pri->lock);
11194       if (!res) {
11195          for (which = 0; which < NUM_DCHANS; which++) {
11196             if (!pri->dchans[which])
11197                break;
11198             /* Just a timeout, run the scheduler */
11199             e = pri_schedule_run(pri->dchans[which]);
11200             if (e)
11201                break;
11202          }
11203       } else if (res > -1) {
11204          for (which = 0; which < NUM_DCHANS; which++) {
11205             if (!pri->dchans[which])
11206                break;
11207             if (fds[which].revents & POLLPRI) {
11208                /* Check for an event */
11209                x = 0;
11210                res = ioctl(pri->fds[which], DAHDI_GETEVENT, &x);
11211                if (x) 
11212                   ast_log(LOG_NOTICE, "PRI got event: %s (%d) on %s D-channel of span %d\n", event2str(x), x, pri_order(which), pri->span);
11213                /* Keep track of alarm state */  
11214                if (x == DAHDI_EVENT_ALARM) {
11215                   pri->dchanavail[which] &= ~(DCHAN_NOTINALARM | DCHAN_UP);
11216                   pri_find_dchan(pri);
11217                } else if (x == DAHDI_EVENT_NOALARM) {
11218                   pri->dchanavail[which] |= DCHAN_NOTINALARM;
11219                   pri_restart(pri->dchans[which]);
11220                }
11221             
11222                if (option_debug)
11223                   ast_log(LOG_DEBUG, "Got event %s (%d) on D-channel for span %d\n", event2str(x), x, pri->span);
11224             } else if (fds[which].revents & POLLIN) {
11225                e = pri_check_event(pri->dchans[which]);
11226             }
11227             if (e)
11228                break;
11229          }
11230       } else if (errno != EINTR)
11231          ast_log(LOG_WARNING, "pri_event returned error %d (%s)\n", errno, strerror(errno));
11232 
11233       if (e) {
11234          if (pri->debug)
11235             pri_dump_event(pri->dchans[which], e);
11236 
11237          if (e->e != PRI_EVENT_DCHAN_DOWN) {
11238             if (!(pri->dchanavail[which] & DCHAN_UP)) {
11239                if (option_verbose > 1) 
11240                   ast_verbose(VERBOSE_PREFIX_2 "%s D-Channel on span %d up\n", pri_order(which), pri->span);
11241             }
11242             pri->dchanavail[which] |= DCHAN_UP;
11243          } else {
11244             if (pri->dchanavail[which] & DCHAN_UP) {
11245                if (option_verbose > 1) 
11246                   ast_verbose(VERBOSE_PREFIX_2 "%s D-Channel on span %d down\n", pri_order(which), pri->span);
11247             }
11248             pri->dchanavail[which] &= ~DCHAN_UP;
11249          }
11250 
11251          if ((e->e != PRI_EVENT_DCHAN_UP) && (e->e != PRI_EVENT_DCHAN_DOWN) && (pri->pri != pri->dchans[which]))
11252             /* Must be an NFAS group that has the secondary dchan active */
11253             pri->pri = pri->dchans[which];
11254 
11255          switch (e->e) {
11256          case PRI_EVENT_DCHAN_UP:
11257             pri->no_d_channels = 0;
11258             if (!pri->pri) pri_find_dchan(pri);
11259 
11260             /* Note presense of D-channel */
11261             time(&pri->lastreset);
11262 
11263             /* Restart in 5 seconds */
11264             if (pri->resetinterval > -1) {
11265                pri->lastreset -= pri->resetinterval;
11266                pri->lastreset += 5;
11267             }
11268             /* Take the channels from inalarm condition */
11269             pri->resetting = 0;
11270             for (i = 0; i < pri->numchans; i++) {
11271                if (pri->pvts[i]) {
11272                   pri->pvts[i]->inalarm = 0;
11273                   pri->pvts[i]->resetting = 0;
11274                }
11275             }
11276             break;
11277          case PRI_EVENT_DCHAN_DOWN:
11278             pri_find_dchan(pri);
11279             if (!pri_is_up(pri)) {
11280                /* Hangup active channels and put them in alarm mode */
11281                pri->resetting = 0;
11282                for (i = 0; i < pri->numchans; i++) {
11283                   struct dahdi_pvt *p = pri->pvts[i];
11284                   if (p) {
11285                      if (!p->pri || !p->pri->pri || pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0) {
11286                         /* T309 is not enabled : destroy calls when alarm occurs */
11287                         if (p->call) {
11288                            if (p->pri && p->pri->pri) {
11289                               pri_destroycall(p->pri->pri, p->call);
11290                               p->call = NULL;
11291                            } else
11292                               ast_log(LOG_WARNING, "The PRI Call has not been destroyed\n");
11293                         }
11294                         if (p->realcall) {
11295                            pri_hangup_all(p->realcall, pri);
11296                         } else if (p->owner)
11297                            p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
11298                      }
11299                      p->inalarm = 1;
11300                      p->resetting = 0;
11301                   }
11302                }
11303             }
11304             break;
11305          case PRI_EVENT_RESTART:
11306             if (e->restart.channel > -1 && PRI_CHANNEL(e->ring.channel) != 0xFF) {
11307                chanpos = pri_find_principle(pri, e->restart.channel);
11308                if (chanpos < 0)
11309                   ast_log(LOG_WARNING,
11310                      "Span %d: Restart requested on odd/unavailable channel number %d/%d\n",
11311                      pri->span, PRI_SPAN(e->restart.channel),
11312                      PRI_CHANNEL(e->restart.channel));
11313                else {
11314                   if (option_verbose > 2)
11315                      ast_verbose(VERBOSE_PREFIX_3 "Span %d: Channel %d/%d restarted\n",
11316                         pri->span, PRI_SPAN(e->restart.channel),
11317                         PRI_CHANNEL(e->restart.channel));
11318                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
11319                   if (pri->pvts[chanpos]->call) {
11320                      pri_destroycall(pri->pri, pri->pvts[chanpos]->call);
11321                      pri->pvts[chanpos]->call = NULL;
11322                   }
11323                   /* Force soft hangup if appropriate */
11324                   if (pri->pvts[chanpos]->realcall) 
11325                      pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
11326                   else if (pri->pvts[chanpos]->owner)
11327                      pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
11328                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
11329                }
11330             } else {
11331                if (option_verbose > 2)
11332                   ast_verbose(VERBOSE_PREFIX_2 "Restart requested on entire span %d\n",
11333                      pri->span);
11334                for (x = 0; x < pri->numchans; x++)
11335                   if (pri->pvts[x]) {
11336                      ast_mutex_lock(&pri->pvts[x]->lock);
11337                      if (pri->pvts[x]->call) {
11338                         pri_destroycall(pri->pri, pri->pvts[x]->call);
11339                         pri->pvts[x]->call = NULL;
11340                      }
11341                      if (pri->pvts[x]->realcall) 
11342                         pri_hangup_all(pri->pvts[x]->realcall, pri);
11343                      else if (pri->pvts[x]->owner)
11344                         pri->pvts[x]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
11345                      ast_mutex_unlock(&pri->pvts[x]->lock);
11346                   }
11347             }
11348             break;
11349          case PRI_EVENT_KEYPAD_DIGIT:
11350             chanpos = pri_find_principle_by_call(pri, e->digit.call);
11351             if (chanpos < 0) {
11352                ast_log(LOG_WARNING,
11353                   "Span %d: Received keypad digits for unknown call.\n", pri->span);
11354                break;
11355             }
11356             ast_mutex_lock(&pri->pvts[chanpos]->lock);
11357             /* queue DTMF frame if the PBX for this call was already started (we're forwarding KEYPAD_DIGITs further on */
11358             if ((pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)
11359                && pri->pvts[chanpos]->owner) {
11360                /* how to do that */
11361                int digitlen = strlen(e->digit.digits);
11362                char digit;
11363                int i;
11364                for (i = 0; i < digitlen; i++) {
11365                   digit = e->digit.digits[i];
11366                   {
11367                      struct ast_frame f = { AST_FRAME_DTMF, digit, };
11368                      dahdi_queue_frame(pri->pvts[chanpos], &f, pri);
11369                   }
11370                }
11371             }
11372             ast_mutex_unlock(&pri->pvts[chanpos]->lock);
11373             break;
11374             
11375          case PRI_EVENT_INFO_RECEIVED:
11376             chanpos = pri_find_principle_by_call(pri, e->ring.call);
11377             if (chanpos < 0) {
11378                ast_log(LOG_WARNING,
11379                   "Span %d: Received INFORMATION for unknown call.\n", pri->span);
11380                break;
11381             }
11382             ast_mutex_lock(&pri->pvts[chanpos]->lock);
11383             /* queue DTMF frame if the PBX for this call was already started (we're forwarding INFORMATION further on */
11384             if ((pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)
11385                && pri->pvts[chanpos]->owner) {
11386                /* how to do that */
11387                int digitlen = strlen(e->ring.callednum);
11388                char digit;
11389                int i;
11390                for (i = 0; i < digitlen; i++) {
11391                   digit = e->ring.callednum[i];
11392                   {
11393                      struct ast_frame f = { AST_FRAME_DTMF, digit, };
11394                      dahdi_queue_frame(pri->pvts[chanpos], &f, pri);
11395                   }
11396                }
11397             }
11398             ast_mutex_unlock(&pri->pvts[chanpos]->lock);
11399             break;
11400          case PRI_EVENT_RING:
11401             crv = NULL;
11402             chanpos = pri_find_principle_by_call(pri, e->ring.call);
11403             if (-1 < chanpos) {
11404                /* Libpri has already filtered out duplicate SETUPs. */
11405                ast_log(LOG_WARNING,
11406                   "Span %d: Got SETUP with duplicate call ptr.  Dropping call.\n",
11407                   pri->span);
11408                pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_NORMAL_TEMPORARY_FAILURE);
11409                break;
11410             }
11411             if (e->ring.channel == -1 || PRI_CHANNEL(e->ring.channel) == 0xFF) {
11412                /* Any channel requested. */
11413                chanpos = pri_find_empty_chan(pri, 1);
11414             } else if (PRI_CHANNEL(e->ring.channel) == 0x00) {
11415                /* No channel specified. */
11416                {
11417                   /* We will not accept incoming call waiting calls. */
11418                   pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_INCOMPATIBLE_DESTINATION);
11419                   break;
11420                }
11421             } else {
11422                /* A channel is specified. */
11423                chanpos = pri_find_principle(pri, e->ring.channel);
11424                if (chanpos < 0) {
11425                   ast_log(LOG_WARNING,
11426                      "Span %d: SETUP on unconfigured channel %d/%d\n",
11427                      pri->span, PRI_SPAN(e->ring.channel),
11428                      PRI_CHANNEL(e->ring.channel));
11429                } else if (!sig_pri_is_chan_available(pri->pvts[chanpos])) {
11430                   /* This is where we handle initial glare */
11431                   ast_log(LOG_DEBUG,
11432                      "Span %d: SETUP requested unavailable channel %d/%d.  Attempting to renegotiate.\n",
11433                      pri->span, PRI_SPAN(e->ring.channel),
11434                      PRI_CHANNEL(e->ring.channel));
11435                   chanpos = -1;
11436                }
11437 #if defined(ALWAYS_PICK_CHANNEL)
11438                if (e->ring.flexible) {
11439                   chanpos = -1;
11440                }
11441 #endif   /* defined(ALWAYS_PICK_CHANNEL) */
11442                if (chanpos < 0 && e->ring.flexible) {
11443                   /* We can try to pick another channel. */
11444                   chanpos = pri_find_empty_chan(pri, 1);
11445                }
11446             }
11447             if (chanpos < 0) {
11448                if (e->ring.flexible) {
11449                   pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION);
11450                } else {
11451                   pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_REQUESTED_CHAN_UNAVAIL);
11452                }
11453                break;
11454             }
11455 
11456             ast_mutex_lock(&pri->pvts[chanpos]->lock);
11457             if (pri->switchtype == PRI_SWITCH_GR303_TMC) {
11458                /* Should be safe to lock CRV AFAIK while bearer is still locked */
11459                crv = pri_find_crv(pri, pri_get_crv(pri->pri, e->ring.call, NULL));
11460                if (crv)
11461                   ast_mutex_lock(&crv->lock);
11462                if (!crv || crv->owner) {
11463                   pri->pvts[chanpos]->call = NULL;
11464                   if (crv) {
11465                      if (crv->owner)
11466                         crv->owner->_softhangup |= AST_SOFTHANGUP_DEV;
11467                      ast_log(LOG_WARNING, "Call received for busy CRV %d on span %d\n", pri_get_crv(pri->pri, e->ring.call, NULL), pri->span);
11468                   } else
11469                      ast_log(LOG_NOTICE, "Call received for unconfigured CRV %d on span %d\n", pri_get_crv(pri->pri, e->ring.call, NULL), pri->span);
11470                   pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_INVALID_CALL_REFERENCE);
11471                   if (crv)
11472                      ast_mutex_unlock(&crv->lock);
11473                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
11474                   break;
11475                }
11476             }
11477 
11478             /* Mark channel as in use so noone else will steal it. */
11479             pri->pvts[chanpos]->call = e->ring.call;
11480 
11481             apply_plan_to_number(plancallingnum, sizeof(plancallingnum), pri, e->ring.callingnum, e->ring.callingplan);
11482             if (pri->pvts[chanpos]->use_callerid) {
11483                ast_shrink_phone_number(plancallingnum);
11484                ast_copy_string(pri->pvts[chanpos]->cid_num, plancallingnum, sizeof(pri->pvts[chanpos]->cid_num));
11485 #ifdef PRI_ANI
11486                if (!ast_strlen_zero(e->ring.callingani)) {
11487                   apply_plan_to_number(plancallingani, sizeof(plancallingani), pri, e->ring.callingani, e->ring.callingplanani);
11488                   ast_shrink_phone_number(plancallingani);
11489                   ast_copy_string(pri->pvts[chanpos]->cid_ani, plancallingani, sizeof(pri->pvts[chanpos]->cid_ani));
11490                } else {
11491                   pri->pvts[chanpos]->cid_ani[0] = '\0';
11492                }
11493 #endif
11494                ast_copy_string(pri->pvts[chanpos]->cid_name, e->ring.callingname, sizeof(pri->pvts[chanpos]->cid_name));
11495                pri->pvts[chanpos]->cid_ton = e->ring.callingplan; /* this is the callingplan (TON/NPI), e->ring.callingplan>>4 would be the TON */
11496             } else {
11497                pri->pvts[chanpos]->cid_num[0] = '\0';
11498                pri->pvts[chanpos]->cid_ani[0] = '\0';
11499                pri->pvts[chanpos]->cid_name[0] = '\0';
11500                pri->pvts[chanpos]->cid_ton = 0;
11501             }
11502             apply_plan_to_number(pri->pvts[chanpos]->rdnis, sizeof(pri->pvts[chanpos]->rdnis), pri,
11503                       e->ring.redirectingnum, e->ring.callingplanrdnis);
11504 
11505             /* Set DNID on all incoming calls -- even immediate */
11506             ast_copy_string(pri->pvts[chanpos]->dnid, e->ring.callednum, sizeof(pri->pvts[chanpos]->dnid));
11507 
11508             /* If immediate=yes go to s|1 */
11509             if (pri->pvts[chanpos]->immediate) {
11510                if (option_verbose > 2)
11511                   ast_verbose(VERBOSE_PREFIX_3 "Going to extension s|1 because of immediate=yes\n");
11512                pri->pvts[chanpos]->exten[0] = 's';
11513                pri->pvts[chanpos]->exten[1] = '\0';
11514             }
11515             /* Get called number */
11516             else if (!ast_strlen_zero(e->ring.callednum)) {
11517                ast_copy_string(pri->pvts[chanpos]->exten, e->ring.callednum, sizeof(pri->pvts[chanpos]->exten));
11518             } else if (pri->overlapdial)
11519                pri->pvts[chanpos]->exten[0] = '\0';
11520             else {
11521                /* Some PRI circuits are set up to send _no_ digits.  Handle them as 's'. */
11522                pri->pvts[chanpos]->exten[0] = 's';
11523                pri->pvts[chanpos]->exten[1] = '\0';
11524             }
11525             /* No number yet, but received "sending complete"? */
11526             if (e->ring.complete && (ast_strlen_zero(e->ring.callednum))) {
11527                if (option_verbose > 2)
11528                   ast_verbose(VERBOSE_PREFIX_3 "Going to extension s|1 because of Complete received\n");
11529                pri->pvts[chanpos]->exten[0] = 's';
11530                pri->pvts[chanpos]->exten[1] = '\0';
11531             }
11532 
11533             /* Make sure extension exists (or in overlap dial mode, can exist) */
11534             if (((pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING) && ast_canmatch_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) ||
11535                ast_exists_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) {
11536                /* Setup law */
11537                int law;
11538                if (pri->switchtype != PRI_SWITCH_GR303_TMC) {
11539                   /* Set to audio mode at this point */
11540                   law = 1;
11541                   if (ioctl(pri->pvts[chanpos]->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &law) == -1)
11542                      ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d: %s\n", pri->pvts[chanpos]->channel, law, strerror(errno));
11543                }
11544                if (e->ring.layer1 == PRI_LAYER_1_ALAW)
11545                   law = DAHDI_LAW_ALAW;
11546                else
11547                   law = DAHDI_LAW_MULAW;
11548                res = dahdi_setlaw(pri->pvts[chanpos]->subs[SUB_REAL].dfd, law);
11549                if (res < 0) 
11550                   ast_log(LOG_WARNING, "Unable to set law on channel %d\n", pri->pvts[chanpos]->channel);
11551                res = set_actual_gain(pri->pvts[chanpos]->subs[SUB_REAL].dfd, 0, pri->pvts[chanpos]->rxgain, pri->pvts[chanpos]->txgain, law);
11552                if (res < 0)
11553                   ast_log(LOG_WARNING, "Unable to set gains on channel %d\n", pri->pvts[chanpos]->channel);
11554                if (e->ring.complete || !(pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)) {
11555                   /* Just announce proceeding */
11556                   pri->pvts[chanpos]->call_level = DAHDI_CALL_LEVEL_PROCEEDING;
11557                   pri_proceeding(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 0);
11558                } else if (pri->switchtype == PRI_SWITCH_GR303_TMC) {
11559                   pri->pvts[chanpos]->call_level = DAHDI_CALL_LEVEL_CONNECT;
11560                   pri_answer(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 1);
11561                } else {
11562                   pri->pvts[chanpos]->call_level = DAHDI_CALL_LEVEL_OVERLAP;
11563                   pri_need_more_info(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 1);
11564                }
11565                /* Get the use_callingpres state */
11566                pri->pvts[chanpos]->callingpres = e->ring.callingpres;
11567             
11568                /* Start PBX */
11569                if (!e->ring.complete
11570                   && (pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)
11571                   && ast_matchmore_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) {
11572                   /*
11573                    * Release the PRI lock while we create the channel so other
11574                    * threads can send D channel messages.  We must also release
11575                    * the private lock to prevent deadlock while creating the
11576                    * channel.
11577                    */
11578                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
11579                   ast_mutex_unlock(&pri->lock);
11580                   if (crv) {
11581                      /* Set bearer and such */
11582                      pri_assign_bearer(crv, pri, pri->pvts[chanpos]);
11583                      c = dahdi_new(crv, AST_STATE_RESERVED, 0, SUB_REAL, law, e->ring.ctype);
11584                      pri->pvts[chanpos]->owner = &inuse;
11585                      ast_log(LOG_DEBUG, "Started up crv %d:%d on bearer channel %d\n", pri->trunkgroup, crv->channel, crv->bearer->channel);
11586                   } else {
11587                      c = dahdi_new(pri->pvts[chanpos], AST_STATE_RESERVED, 0, SUB_REAL, law, e->ring.ctype);
11588                   }
11589                   ast_mutex_lock(&pri->lock);
11590                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
11591                   if (c) {
11592                      if (!ast_strlen_zero(e->ring.callingsubaddr)) {
11593                         pbx_builtin_setvar_helper(c, "CALLINGSUBADDR", e->ring.callingsubaddr);
11594                      }
11595                      if (e->ring.ani2 >= 0) {
11596                         snprintf(ani2str, sizeof(ani2str), "%d", e->ring.ani2);
11597                         pbx_builtin_setvar_helper(c, "ANI2", ani2str);
11598                      }
11599 
11600 #ifdef SUPPORT_USERUSER
11601                      if (!ast_strlen_zero(e->ring.useruserinfo)) {
11602                         pbx_builtin_setvar_helper(c, "USERUSERINFO", e->ring.useruserinfo);
11603                      }
11604 #endif
11605 
11606                      snprintf(calledtonstr, sizeof(calledtonstr), "%d", e->ring.calledplan);
11607                      pbx_builtin_setvar_helper(c, "CALLEDTON", calledtonstr);
11608                      if (e->ring.redirectingreason >= 0)
11609                         pbx_builtin_setvar_helper(c, "PRIREDIRECTREASON", redirectingreason2str(e->ring.redirectingreason));
11610 
11611                      if (!pri->pvts[chanpos]->digital) {
11612                         /*
11613                          * Call has a channel.
11614                          * Indicate that we are providing dialtone.
11615                          */
11616                         pri->pvts[chanpos]->progress = 1;/* No need to send plain PROGRESS again. */
11617                         pri_progress(pri->pri, e->ring.call,
11618                            PVT_TO_CHANNEL(pri->pvts[chanpos]), 1);
11619                      }
11620                   }
11621 
11622                   pthread_attr_init(&attr);
11623                   pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
11624                   if (c && !ast_pthread_create(&threadid, &attr, ss_thread, c)) {
11625                      if (option_verbose > 2)
11626                         ast_verbose(VERBOSE_PREFIX_3 "Accepting overlap call from '%s' to '%s' on channel %d/%d, span %d\n",
11627                            plancallingnum, S_OR(pri->pvts[chanpos]->exten, "<unspecified>"),
11628                            pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
11629                   } else {
11630                      ast_log(LOG_WARNING, "Unable to start PBX on channel %d/%d, span %d\n",
11631                         pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
11632                      if (c) {
11633                         /* Avoid deadlock while destroying channel */
11634                         ast_mutex_unlock(&pri->pvts[chanpos]->lock);
11635                         ast_mutex_unlock(&pri->lock);
11636                         ast_hangup(c);
11637                         ast_mutex_lock(&pri->lock);
11638                         ast_mutex_lock(&pri->pvts[chanpos]->lock);
11639                      } else {
11640                         pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_SWITCH_CONGESTION);
11641                         pri->pvts[chanpos]->call = NULL;
11642                      }
11643                   }
11644                   pthread_attr_destroy(&attr);
11645                } else {
11646                   /*
11647                    * Release the PRI lock while we create the channel so other
11648                    * threads can send D channel messages.  We must also release
11649                    * the private lock to prevent deadlock while creating the
11650                    * channel.
11651                    */
11652                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
11653                   ast_mutex_unlock(&pri->lock);
11654                   c = dahdi_new(pri->pvts[chanpos], AST_STATE_RING, 0, SUB_REAL, law, e->ring.ctype);
11655                   ast_mutex_lock(&pri->lock);
11656                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
11657                   if (c) {
11658                      /*
11659                       * It is reasonably safe to set the following
11660                       * channel variables while the PRI and DAHDI private
11661                       * structures are locked.  The PBX has not been
11662                       * started yet and it is unlikely that any other task
11663                       * will do anything with the channel we have just
11664                       * created.
11665                       */
11666                      if (!ast_strlen_zero(e->ring.callingsubaddr)) {
11667                         pbx_builtin_setvar_helper(c, "CALLINGSUBADDR", e->ring.callingsubaddr);
11668                      }
11669                      if (e->ring.ani2 >= 0) {
11670                         snprintf(ani2str, sizeof(ani2str), "%d", e->ring.ani2);
11671                         pbx_builtin_setvar_helper(c, "ANI2", ani2str);
11672                      }
11673 
11674 #ifdef SUPPORT_USERUSER
11675                      if (!ast_strlen_zero(e->ring.useruserinfo)) {
11676                         pbx_builtin_setvar_helper(c, "USERUSERINFO", e->ring.useruserinfo);
11677                      }
11678 #endif
11679 
11680                      if (e->ring.redirectingreason >= 0)
11681                         pbx_builtin_setvar_helper(c, "PRIREDIRECTREASON", redirectingreason2str(e->ring.redirectingreason));
11682 
11683                      snprintf(calledtonstr, sizeof(calledtonstr), "%d", e->ring.calledplan);
11684                      pbx_builtin_setvar_helper(c, "CALLEDTON", calledtonstr);
11685                   }
11686                   if (c && !ast_pbx_start(c)) {
11687                      if (option_verbose > 2)
11688                         ast_verbose(VERBOSE_PREFIX_3 "Accepting call from '%s' to '%s' on channel %d/%d, span %d\n",
11689                            plancallingnum, pri->pvts[chanpos]->exten,
11690                            pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
11691 
11692                      dahdi_enable_ec(pri->pvts[chanpos]);
11693                   } else {
11694                      ast_log(LOG_WARNING, "Unable to start PBX on channel %d/%d, span %d\n",
11695                         pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
11696                      if (c) {
11697                         /* Avoid deadlock while destroying channel */
11698                         ast_mutex_unlock(&pri->pvts[chanpos]->lock);
11699                         ast_mutex_unlock(&pri->lock);
11700                         ast_hangup(c);
11701                         ast_mutex_lock(&pri->lock);
11702                         ast_mutex_lock(&pri->pvts[chanpos]->lock);
11703                      } else {
11704                         pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_SWITCH_CONGESTION);
11705                         pri->pvts[chanpos]->call = NULL;
11706                      }
11707                   }
11708                }
11709             } else {
11710                if (option_verbose > 2)
11711                   ast_verbose(VERBOSE_PREFIX_3 "Span %d: Extension %s@%s does not exist.  Rejecting call from '%s'.\n",
11712                      pri->span, pri->pvts[chanpos]->exten, pri->pvts[chanpos]->context,
11713                      pri->pvts[chanpos]->cid_num);
11714                pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_UNALLOCATED);
11715                pri->pvts[chanpos]->call = NULL;
11716                pri->pvts[chanpos]->exten[0] = '\0';
11717             }
11718             if (crv)
11719                ast_mutex_unlock(&crv->lock);
11720             ast_mutex_unlock(&pri->pvts[chanpos]->lock);
11721             break;
11722          case PRI_EVENT_RINGING:
11723             chanpos = pri_find_fixup_principle(pri, e->ringing.channel,
11724                e->ringing.call);
11725             if (chanpos < 0) {
11726                break;
11727             }
11728             ast_mutex_lock(&pri->pvts[chanpos]->lock);
11729             if (ast_strlen_zero(pri->pvts[chanpos]->dop.dialstr)) {
11730                dahdi_enable_ec(pri->pvts[chanpos]);
11731                pri->pvts[chanpos]->subs[SUB_REAL].needringing = 1;
11732                if (pri->pvts[chanpos]->call_level < DAHDI_CALL_LEVEL_ALERTING) {
11733                   pri->pvts[chanpos]->call_level = DAHDI_CALL_LEVEL_ALERTING;
11734                }
11735             } else
11736                ast_log(LOG_DEBUG, "Deferring ringing notification because of extra digits to dial...\n");
11737             if (
11738 #ifdef PRI_PROGRESS_MASK
11739                e->ringing.progressmask & PRI_PROG_INBAND_AVAILABLE
11740 #else
11741                e->ringing.progress == 8
11742 #endif
11743                ) {
11744                /* Now we can do call progress detection */
11745                if (pri->pvts[chanpos]->dsp && pri->pvts[chanpos]->dsp_features) {
11746                   /* RINGING detection isn't required because we got ALERTING signal */
11747                   ast_dsp_set_features(pri->pvts[chanpos]->dsp, pri->pvts[chanpos]->dsp_features & ~DSP_PROGRESS_RINGING);
11748                   pri->pvts[chanpos]->dsp_features = 0;
11749                }
11750             }
11751 
11752 #ifdef SUPPORT_USERUSER
11753             if (!ast_strlen_zero(e->ringing.useruserinfo)) {
11754                struct ast_channel *owner = pri->pvts[chanpos]->owner;
11755                ast_mutex_unlock(&pri->pvts[chanpos]->lock);
11756                pbx_builtin_setvar_helper(owner, "USERUSERINFO", e->ringing.useruserinfo);
11757                ast_mutex_lock(&pri->pvts[chanpos]->lock);
11758             }
11759 #endif
11760 
11761             ast_mutex_unlock(&pri->pvts[chanpos]->lock);
11762             break;
11763          case PRI_EVENT_PROGRESS:
11764             chanpos = pri_find_fixup_principle(pri, e->proceeding.channel,
11765                e->proceeding.call);
11766             if (chanpos < 0) {
11767                break;
11768             }
11769             if ((!pri->pvts[chanpos]->progress)
11770 #ifdef PRI_PROGRESS_MASK
11771                || (e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE)
11772 #else
11773                || (e->proceeding.progress == 8)
11774 #endif
11775                ) {
11776                struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, };
11777 
11778                if (e->proceeding.cause > -1) {
11779                   if (option_verbose > 2)
11780                      ast_verbose(VERBOSE_PREFIX_3 "PROGRESS with cause code %d received\n", e->proceeding.cause);
11781 
11782                   /* Work around broken, out of spec USER_BUSY cause in a progress message */
11783                   if (e->proceeding.cause == AST_CAUSE_USER_BUSY) {
11784                      if (pri->pvts[chanpos]->owner) {
11785                         if (option_verbose > 2)
11786                            ast_verbose(VERBOSE_PREFIX_3 "PROGRESS with 'user busy' received, signaling AST_CONTROL_BUSY instead of AST_CONTROL_PROGRESS\n");
11787 
11788                         pri->pvts[chanpos]->owner->hangupcause = e->proceeding.cause;
11789                         f.subclass = AST_CONTROL_BUSY;
11790                      }
11791                   }
11792                }
11793 
11794                ast_mutex_lock(&pri->pvts[chanpos]->lock);
11795                ast_log(LOG_DEBUG, "Queuing frame from PRI_EVENT_PROGRESS on channel %d/%d span %d\n",
11796                   pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset,pri->span);
11797                dahdi_queue_frame(pri->pvts[chanpos], &f, pri);
11798                if (
11799 #ifdef PRI_PROGRESS_MASK
11800                   e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE
11801 #else
11802                   e->proceeding.progress == 8
11803 #endif
11804                   ) {
11805                   /* Now we can do call progress detection */
11806                   if (pri->pvts[chanpos]->dsp && pri->pvts[chanpos]->dsp_features) {
11807                      ast_dsp_set_features(pri->pvts[chanpos]->dsp, pri->pvts[chanpos]->dsp_features);
11808                      pri->pvts[chanpos]->dsp_features = 0;
11809                   }
11810                   /* Bring voice path up */
11811                   f.subclass = AST_CONTROL_PROGRESS;
11812                   dahdi_queue_frame(pri->pvts[chanpos], &f, pri);
11813                }
11814                pri->pvts[chanpos]->progress = 1;
11815                pri->pvts[chanpos]->dialing = 0;
11816                ast_mutex_unlock(&pri->pvts[chanpos]->lock);
11817             }
11818             break;
11819          case PRI_EVENT_PROCEEDING:
11820             chanpos = pri_find_fixup_principle(pri, e->proceeding.channel,
11821                e->proceeding.call);
11822             if (chanpos < 0) {
11823                break;
11824             }
11825             ast_mutex_lock(&pri->pvts[chanpos]->lock);
11826             if (pri->pvts[chanpos]->call_level < DAHDI_CALL_LEVEL_PROCEEDING) {
11827                struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_PROCEEDING, };
11828 
11829                pri->pvts[chanpos]->call_level = DAHDI_CALL_LEVEL_PROCEEDING;
11830                ast_log(LOG_DEBUG, "Queuing frame from PRI_EVENT_PROCEEDING on channel %d/%d span %d\n",
11831                   pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset,pri->span);
11832                dahdi_queue_frame(pri->pvts[chanpos], &f, pri);
11833                if (
11834 #ifdef PRI_PROGRESS_MASK
11835                   e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE
11836 #else
11837                   e->proceeding.progress == 8
11838 #endif
11839                   ) {
11840                   /* Now we can do call progress detection */
11841                   if (pri->pvts[chanpos]->dsp && pri->pvts[chanpos]->dsp_features) {
11842                      ast_dsp_set_features(pri->pvts[chanpos]->dsp, pri->pvts[chanpos]->dsp_features);
11843                      pri->pvts[chanpos]->dsp_features = 0;
11844                   }
11845                   /* Bring voice path up */
11846                   f.subclass = AST_CONTROL_PROGRESS;
11847                   dahdi_queue_frame(pri->pvts[chanpos], &f, pri);
11848                }
11849                pri->pvts[chanpos]->dialing = 0;
11850             }
11851             ast_mutex_unlock(&pri->pvts[chanpos]->lock);
11852             break;
11853          case PRI_EVENT_FACNAME:
11854             chanpos = pri_find_principle_by_call(pri, e->facname.call);
11855             if (chanpos < 0) {
11856                ast_log(LOG_WARNING, "Span %d: Received facility for unknown call.\n",
11857                   pri->span);
11858                break;
11859             }
11860             if (pri->pvts[chanpos]->use_callerid) {
11861                /* Re-use *69 field for PRI */
11862                ast_mutex_lock(&pri->pvts[chanpos]->lock);
11863                ast_copy_string(pri->pvts[chanpos]->lastcid_num, e->facname.callingnum, sizeof(pri->pvts[chanpos]->lastcid_num));
11864                ast_copy_string(pri->pvts[chanpos]->lastcid_name, e->facname.callingname, sizeof(pri->pvts[chanpos]->lastcid_name));
11865                pri->pvts[chanpos]->subs[SUB_REAL].needcallerid = 1;
11866                dahdi_enable_ec(pri->pvts[chanpos]);
11867                ast_mutex_unlock(&pri->pvts[chanpos]->lock);
11868             }
11869             break;            
11870          case PRI_EVENT_ANSWER:
11871             chanpos = pri_find_fixup_principle(pri, e->answer.channel, e->answer.call);
11872             if (chanpos < 0) {
11873                break;
11874             }
11875             ast_mutex_lock(&pri->pvts[chanpos]->lock);
11876             /* Now we can do call progress detection */
11877 
11878             /* We changed this so it turns on the DSP no matter what... progress or no progress.
11879              * By this time, we need DTMF detection and other features that were previously disabled
11880              * -- Matt F */
11881             if (pri->pvts[chanpos]->dsp && pri->pvts[chanpos]->dsp_features) {
11882                ast_dsp_set_features(pri->pvts[chanpos]->dsp, pri->pvts[chanpos]->dsp_features);
11883                pri->pvts[chanpos]->dsp_features = 0;
11884             }
11885             if (pri->pvts[chanpos]->realcall && (pri->pvts[chanpos]->realcall->sig == SIG_FXSKS)) {
11886                ast_log(LOG_DEBUG, "Starting up GR-303 trunk now that we got CONNECT...\n");
11887                x = DAHDI_START;
11888                res = ioctl(pri->pvts[chanpos]->subs[SUB_REAL].dfd, DAHDI_HOOK, &x);
11889                if (res < 0) {
11890                   if (errno != EINPROGRESS) {
11891                      ast_log(LOG_WARNING, "Unable to start channel: %s\n", strerror(errno));
11892                   }
11893                }
11894             } else if (!ast_strlen_zero(pri->pvts[chanpos]->dop.dialstr)) {
11895                pri->pvts[chanpos]->dialing = 1;
11896                /* Send any "w" waited stuff */
11897                res = ioctl(pri->pvts[chanpos]->subs[SUB_REAL].dfd, DAHDI_DIAL, &pri->pvts[chanpos]->dop);
11898                if (res < 0) {
11899                   ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d: %s\n", pri->pvts[chanpos]->channel, strerror(errno));
11900                   pri->pvts[chanpos]->dop.dialstr[0] = '\0';
11901                } else
11902                   ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", pri->pvts[chanpos]->dop.dialstr);
11903                pri->pvts[chanpos]->dop.dialstr[0] = '\0';
11904             } else if (pri->pvts[chanpos]->confirmanswer) {
11905                ast_log(LOG_DEBUG, "Waiting on answer confirmation on channel %d!\n", pri->pvts[chanpos]->channel);
11906             } else {
11907                pri->pvts[chanpos]->dialing = 0;
11908                if (pri->pvts[chanpos]->call_level < DAHDI_CALL_LEVEL_CONNECT) {
11909                   pri->pvts[chanpos]->call_level = DAHDI_CALL_LEVEL_CONNECT;
11910                }
11911                pri->pvts[chanpos]->subs[SUB_REAL].needanswer =1;
11912                /* Enable echo cancellation if it's not on already */
11913                dahdi_enable_ec(pri->pvts[chanpos]);
11914             }
11915 
11916 #ifdef SUPPORT_USERUSER
11917             if (!ast_strlen_zero(e->answer.useruserinfo)) {
11918                struct ast_channel *owner = pri->pvts[chanpos]->owner;
11919                ast_mutex_unlock(&pri->pvts[chanpos]->lock);
11920                pbx_builtin_setvar_helper(owner, "USERUSERINFO", e->answer.useruserinfo);
11921                ast_mutex_lock(&pri->pvts[chanpos]->lock);
11922             }
11923 #endif
11924 
11925             ast_mutex_unlock(&pri->pvts[chanpos]->lock);
11926             break;            
11927          case PRI_EVENT_HANGUP:
11928             chanpos = pri_find_principle_by_call(pri, e->hangup.call);
11929             if (chanpos < 0) {
11930                /*
11931                 * Continue hanging up the call even though
11932                 * we do not remember it (if we ever did).
11933                 */
11934                pri_hangup(pri->pri, e->hangup.call, e->hangup.cause);
11935                break;
11936             }
11937             ast_mutex_lock(&pri->pvts[chanpos]->lock);
11938             switch (e->hangup.cause) {
11939             case PRI_CAUSE_INVALID_CALL_REFERENCE:
11940                /*
11941                 * The peer denies the existence of this call so we must
11942                 * continue hanging it up and forget about it.
11943                 */
11944                pri_hangup(pri->pri, e->hangup.call, e->hangup.cause);
11945                pri->pvts[chanpos]->call = NULL;
11946                break;
11947             default:
11948                break;
11949             }
11950             if (!pri->pvts[chanpos]->alreadyhungup) {
11951                /* we're calling here dahdi_hangup so once we get there we need to clear p->call after calling pri_hangup */
11952                pri->pvts[chanpos]->alreadyhungup = 1;
11953                if (pri->pvts[chanpos]->realcall)
11954                   pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
11955                else if (pri->pvts[chanpos]->owner) {
11956                   /* Queue a BUSY instead of a hangup if our cause is appropriate */
11957                   pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause;
11958                   switch (pri->pvts[chanpos]->owner->_state) {
11959                   case AST_STATE_BUSY:
11960                   case AST_STATE_UP:
11961                      pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
11962                      break;
11963                   default:
11964                      if (!pri->pvts[chanpos]->outgoing) {
11965                         /*
11966                          * The incoming call leg hung up before getting
11967                          * connected so just hangup the call.
11968                          */
11969                         pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
11970                         break;
11971                      }
11972                      switch (e->hangup.cause) {
11973                      case PRI_CAUSE_USER_BUSY:
11974                         pri->pvts[chanpos]->subs[SUB_REAL].needbusy =1;
11975                         break;
11976                      case PRI_CAUSE_CALL_REJECTED:
11977                      case PRI_CAUSE_NETWORK_OUT_OF_ORDER:
11978                      case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
11979                      case PRI_CAUSE_SWITCH_CONGESTION:
11980                      case PRI_CAUSE_DESTINATION_OUT_OF_ORDER:
11981                      case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE:
11982                         pri->pvts[chanpos]->subs[SUB_REAL].needcongestion =1;
11983                         break;
11984                      default:
11985                         pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
11986                         break;
11987                      }
11988                      break;
11989                   }
11990                } else {
11991                   /*
11992                    * Continue hanging up the call even though
11993                    * we do not have an owner.
11994                    */
11995                   pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause);
11996                   pri->pvts[chanpos]->call = NULL;
11997                }
11998                if (option_verbose > 2) 
11999                   ast_verbose(VERBOSE_PREFIX_3 "Span %d: Channel %d/%d got hangup, cause %d\n",
12000                      pri->span, pri->pvts[chanpos]->logicalspan,
12001                      pri->pvts[chanpos]->prioffset, e->hangup.cause);
12002             } else {
12003                /* Continue hanging up the call. */
12004                pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause);
12005                pri->pvts[chanpos]->call = NULL;
12006             }
12007 #if defined(FORCE_RESTART_UNAVAIL_CHANS)
12008             if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL
12009                && !pri->resetting && !pri->pvts[chanpos]->resetting) {
12010                if (option_verbose > 2)
12011                   ast_verbose(VERBOSE_PREFIX_3
12012                      "Span %d: Forcing restart of channel %d/%d since channel reported in use\n",
12013                      pri->span, pri->pvts[chanpos]->logicalspan,
12014                      pri->pvts[chanpos]->prioffset);
12015                pri->pvts[chanpos]->resetting = 1;
12016                pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos]));
12017             }
12018 #endif   /* defined(FORCE_RESTART_UNAVAIL_CHANS) */
12019             if (e->hangup.aoc_units > -1)
12020                if (option_verbose > 2)
12021                   ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d received AOC-E charging %d unit%s\n",
12022                      pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s");
12023 
12024 #ifdef SUPPORT_USERUSER
12025             if (pri->pvts[chanpos]->owner && !ast_strlen_zero(e->hangup.useruserinfo)) {
12026                struct ast_channel *owner = pri->pvts[chanpos]->owner;
12027                ast_mutex_unlock(&pri->pvts[chanpos]->lock);
12028                pbx_builtin_setvar_helper(owner, "USERUSERINFO", e->hangup.useruserinfo);
12029                ast_mutex_lock(&pri->pvts[chanpos]->lock);
12030             }
12031 #endif
12032 
12033             ast_mutex_unlock(&pri->pvts[chanpos]->lock);
12034             break;
12035 #ifndef PRI_EVENT_HANGUP_REQ
12036 #error please update libpri
12037 #endif
12038          case PRI_EVENT_HANGUP_REQ:
12039             chanpos = pri_find_principle_by_call(pri, e->hangup.call);
12040             if (chanpos < 0) {
12041                /*
12042                 * Continue hanging up the call even though
12043                 * we do not remember it (if we ever did).
12044                 */
12045                pri_hangup(pri->pri, e->hangup.call, e->hangup.cause);
12046                break;
12047             }
12048             ast_mutex_lock(&pri->pvts[chanpos]->lock);
12049             switch (e->hangup.cause) {
12050             case PRI_CAUSE_INVALID_CALL_REFERENCE:
12051                /*
12052                 * The peer denies the existence of this call so we must
12053                 * continue hanging it up and forget about it.  We should not
12054                 * get this cause here, but for completeness we will handle it
12055                 * anyway.
12056                 */
12057                pri_hangup(pri->pri, e->hangup.call, e->hangup.cause);
12058                pri->pvts[chanpos]->call = NULL;
12059                break;
12060             default:
12061                break;
12062             }
12063             if (pri->pvts[chanpos]->realcall)
12064                pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
12065             else if (pri->pvts[chanpos]->owner) {
12066                pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause;
12067                switch (pri->pvts[chanpos]->owner->_state) {
12068                case AST_STATE_BUSY:
12069                case AST_STATE_UP:
12070                   pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
12071                   break;
12072                default:
12073                   if (!pri->pvts[chanpos]->outgoing) {
12074                      /*
12075                       * The incoming call leg hung up before getting
12076                       * connected so just hangup the call.
12077                       */
12078                      pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
12079                      break;
12080                   }
12081                   switch (e->hangup.cause) {
12082                   case PRI_CAUSE_USER_BUSY:
12083                      pri->pvts[chanpos]->subs[SUB_REAL].needbusy =1;
12084                      break;
12085                   case PRI_CAUSE_CALL_REJECTED:
12086                   case PRI_CAUSE_NETWORK_OUT_OF_ORDER:
12087                   case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
12088                   case PRI_CAUSE_SWITCH_CONGESTION:
12089                   case PRI_CAUSE_DESTINATION_OUT_OF_ORDER:
12090                   case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE:
12091                      pri->pvts[chanpos]->subs[SUB_REAL].needcongestion =1;
12092                      break;
12093                   default:
12094                      pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
12095                      break;
12096                   }
12097                   break;
12098                }
12099                if (option_verbose > 2) 
12100                   ast_verbose(VERBOSE_PREFIX_3 "Span %d: Channel %d/%d got hangup request, cause %d\n",
12101                      pri->span, pri->pvts[chanpos]->logicalspan,
12102                      pri->pvts[chanpos]->prioffset, e->hangup.cause);
12103                if (e->hangup.aoc_units > -1)
12104                   if (option_verbose > 2)
12105                      ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d received AOC-E charging %d unit%s\n",
12106                         pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s");
12107             } else {
12108                /*
12109                 * Continue hanging up the call even though
12110                 * we do not have an owner.
12111                 */
12112                pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause);
12113                pri->pvts[chanpos]->call = NULL;
12114             }
12115 #if defined(FORCE_RESTART_UNAVAIL_CHANS)
12116             if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL
12117                && !pri->resetting && !pri->pvts[chanpos]->resetting) {
12118                if (option_verbose > 2)
12119                   ast_verbose(VERBOSE_PREFIX_3
12120                      "Span %d: Forcing restart of channel %d/%d since channel reported in use\n",
12121                      pri->span, pri->pvts[chanpos]->logicalspan,
12122                      pri->pvts[chanpos]->prioffset);
12123                pri->pvts[chanpos]->resetting = 1;
12124                pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos]));
12125             }
12126 #endif   /* defined(FORCE_RESTART_UNAVAIL_CHANS) */
12127 
12128 #ifdef SUPPORT_USERUSER
12129             if (!ast_strlen_zero(e->hangup.useruserinfo)) {
12130                struct ast_channel *owner = pri->pvts[chanpos]->owner;
12131                ast_mutex_unlock(&pri->pvts[chanpos]->lock);
12132                pbx_builtin_setvar_helper(owner, "USERUSERINFO", e->hangup.useruserinfo);
12133                ast_mutex_lock(&pri->pvts[chanpos]->lock);
12134             }
12135 #endif
12136 
12137             ast_mutex_unlock(&pri->pvts[chanpos]->lock);
12138             break;
12139          case PRI_EVENT_HANGUP_ACK:
12140             chanpos = pri_find_principle_by_call(pri, e->hangup.call);
12141             if (chanpos < 0) {
12142                break;
12143             }
12144             ast_mutex_lock(&pri->pvts[chanpos]->lock);
12145             pri->pvts[chanpos]->call = NULL;
12146             if (pri->pvts[chanpos]->owner) {
12147                if (option_verbose > 2) 
12148                   ast_verbose(VERBOSE_PREFIX_3 "Span %d: Channel %d/%d got hangup ACK\n",
12149                      pri->span, pri->pvts[chanpos]->logicalspan,
12150                      pri->pvts[chanpos]->prioffset);
12151             }
12152 #ifdef SUPPORT_USERUSER
12153             if (!ast_strlen_zero(e->hangup.useruserinfo)) {
12154                struct ast_channel *owner = pri->pvts[chanpos]->owner;
12155                ast_mutex_unlock(&pri->pvts[chanpos]->lock);
12156                pbx_builtin_setvar_helper(owner, "USERUSERINFO", e->hangup.useruserinfo);
12157                ast_mutex_lock(&pri->pvts[chanpos]->lock);
12158             }
12159 #endif
12160 
12161             ast_mutex_unlock(&pri->pvts[chanpos]->lock);
12162             break;
12163          case PRI_EVENT_CONFIG_ERR:
12164             ast_log(LOG_WARNING, "PRI Error on span %d: %s\n", pri->span, e->err.err);
12165             break;
12166          case PRI_EVENT_RESTART_ACK:
12167             chanpos = pri_find_principle(pri, e->restartack.channel);
12168             if (chanpos < 0) {
12169                /* Sometime switches (e.g. I421 / British Telecom) don't give us the
12170                   channel number, so we have to figure it out...  This must be why
12171                   everybody resets exactly a channel at a time. */
12172                for (x = 0; x < pri->numchans; x++) {
12173                   if (pri->pvts[x] && pri->pvts[x]->resetting) {
12174                      chanpos = x;
12175                      ast_mutex_lock(&pri->pvts[chanpos]->lock);
12176                      ast_log(LOG_DEBUG,
12177                         "Span %d: Assuming restart ack is for channel %d/%d\n",
12178                         pri->span, pri->pvts[chanpos]->logicalspan,
12179                         pri->pvts[chanpos]->prioffset);
12180                      if (pri->pvts[chanpos]->realcall)
12181                         pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
12182                      else if (pri->pvts[chanpos]->owner) {
12183                         ast_log(LOG_WARNING,
12184                            "Span %d: Got restart ack on channel %d/%d with owner\n",
12185                            pri->span, pri->pvts[chanpos]->logicalspan,
12186                            pri->pvts[chanpos]->prioffset);
12187                         pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
12188                      }
12189                      pri->pvts[chanpos]->resetting = 0;
12190                      if (option_verbose > 2)
12191                         ast_verbose(VERBOSE_PREFIX_3
12192                            "Span %d: Channel %d/%d successfully restarted\n",
12193                            pri->span, pri->pvts[chanpos]->logicalspan,
12194                            pri->pvts[chanpos]->prioffset);
12195                      ast_mutex_unlock(&pri->pvts[chanpos]->lock);
12196                      if (pri->resetting)
12197                         pri_check_restart(pri);
12198                      break;
12199                   }
12200                }
12201                if (chanpos < 0) {
12202                   ast_log(LOG_WARNING,
12203                      "Span %d: Restart ACK on strange channel %d/%d\n",
12204                      pri->span, PRI_SPAN(e->restartack.channel),
12205                      PRI_CHANNEL(e->restartack.channel));
12206                }
12207             } else {
12208                ast_mutex_lock(&pri->pvts[chanpos]->lock);
12209                if (pri->pvts[chanpos]->realcall) 
12210                   pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
12211                else if (pri->pvts[chanpos]->owner) {
12212                   ast_log(LOG_WARNING,
12213                      "Span %d: Got restart ack on channel %d/%d with owner\n",
12214                      pri->span, pri->pvts[chanpos]->logicalspan,
12215                      pri->pvts[chanpos]->prioffset);
12216                   pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
12217                }
12218                pri->pvts[chanpos]->resetting = 0;
12219                if (option_verbose > 2)
12220                   ast_verbose(VERBOSE_PREFIX_3
12221                      "Span %d: Channel %d/%d successfully restarted\n",
12222                      pri->span, pri->pvts[chanpos]->logicalspan,
12223                      pri->pvts[chanpos]->prioffset);
12224                ast_mutex_unlock(&pri->pvts[chanpos]->lock);
12225                if (pri->resetting)
12226                   pri_check_restart(pri);
12227             }
12228             break;
12229          case PRI_EVENT_SETUP_ACK:
12230             chanpos = pri_find_fixup_principle(pri, e->setup_ack.channel,
12231                e->setup_ack.call);
12232             if (chanpos < 0) {
12233                break;
12234             }
12235             ast_mutex_lock(&pri->pvts[chanpos]->lock);
12236             if (pri->pvts[chanpos]->call_level < DAHDI_CALL_LEVEL_OVERLAP) {
12237                pri->pvts[chanpos]->call_level = DAHDI_CALL_LEVEL_OVERLAP;
12238             }
12239 
12240             /* Send any queued digits */
12241             len = strlen(pri->pvts[chanpos]->dialdest);
12242             for (x = 0; x < len; ++x) {
12243                ast_log(LOG_DEBUG, "Sending pending digit '%c'\n", pri->pvts[chanpos]->dialdest[x]);
12244                pri_information(pri->pri, pri->pvts[chanpos]->call,
12245                   pri->pvts[chanpos]->dialdest[x]);
12246             }
12247 
12248             if (!pri->pvts[chanpos]->progress
12249                && (pri->overlapdial & DAHDI_OVERLAPDIAL_OUTGOING)
12250                && !pri->pvts[chanpos]->digital) {
12251                /*
12252                 * Call has a channel.
12253                 * Indicate for overlap dialing that dialtone may be present.
12254                 */
12255                struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, };
12256                dahdi_queue_frame(pri->pvts[chanpos], &f, pri);
12257                pri->pvts[chanpos]->progress = 1;/* Claim to have seen inband-information */
12258                pri->pvts[chanpos]->dialing = 0;
12259                if (pri->pvts[chanpos]->dsp && pri->pvts[chanpos]->dsp_features) {
12260                   ast_dsp_set_features(pri->pvts[chanpos]->dsp, pri->pvts[chanpos]->dsp_features);
12261                   pri->pvts[chanpos]->dsp_features = 0;
12262                }
12263             }
12264             ast_mutex_unlock(&pri->pvts[chanpos]->lock);
12265             break;
12266          case PRI_EVENT_NOTIFY:
12267 #if defined(HAVE_PRI_CALL_HOLD)
12268             chanpos = pri_find_principle_by_call(pri, e->notify.call);
12269             if (chanpos < 0) {
12270                ast_log(LOG_WARNING, "Span %d: Received NOTIFY for unknown call.\n",
12271                   pri->span);
12272                break;
12273             }
12274 #else
12275             /*
12276              * This version of libpri does not supply a call pointer for
12277              * this message.  We are just going to have to trust that the
12278              * correct principle is found.
12279              */
12280             chanpos = pri_find_principle(pri, e->notify.channel);
12281             if (chanpos < 0) {
12282                ast_log(LOG_WARNING, "Received NOTIFY on unconfigured channel %d/%d span %d\n",
12283                   PRI_SPAN(e->notify.channel), PRI_CHANNEL(e->notify.channel), pri->span);
12284                break;
12285             }
12286 #endif   /* !defined(HAVE_PRI_CALL_HOLD) */
12287             {
12288                struct ast_frame f = { AST_FRAME_CONTROL, };
12289                ast_mutex_lock(&pri->pvts[chanpos]->lock);
12290                switch (e->notify.info) {
12291                case PRI_NOTIFY_REMOTE_HOLD:
12292                   f.subclass = AST_CONTROL_HOLD;
12293                   dahdi_queue_frame(pri->pvts[chanpos], &f, pri);
12294                   break;
12295                case PRI_NOTIFY_REMOTE_RETRIEVAL:
12296                   f.subclass = AST_CONTROL_UNHOLD;
12297                   dahdi_queue_frame(pri->pvts[chanpos], &f, pri);
12298                   break;
12299                }
12300                ast_mutex_unlock(&pri->pvts[chanpos]->lock);
12301             }
12302             break;
12303          default:
12304             ast_log(LOG_DEBUG, "Event: %d\n", e->e);
12305          }
12306       }  
12307       ast_mutex_unlock(&pri->lock);
12308    }
12309    /* Never reached */
12310    return NULL;
12311 }
12312 
12313 static int start_pri(struct dahdi_pri *pri)
12314 {
12315    int res, x;
12316    struct dahdi_params p;
12317    struct dahdi_bufferinfo bi;
12318    struct dahdi_spaninfo si;
12319    int i;
12320    
12321    for (i = 0; i < NUM_DCHANS; i++) {
12322       if (!pri->dchannels[i])
12323          break;
12324       pri->fds[i] = open(DAHDI_FILE_CHANNEL, O_RDWR, 0600);
12325       x = pri->dchannels[i];
12326       if ((pri->fds[i] < 0) || (ioctl(pri->fds[i],DAHDI_SPECIFY,&x) == -1)) {
12327          ast_log(LOG_ERROR, "Unable to open D-channel %d (%s)\n", x, strerror(errno));
12328          return -1;
12329       }
12330       memset(&p, 0, sizeof(p));
12331       res = ioctl(pri->fds[i], DAHDI_GET_PARAMS, &p);
12332       if (res) {
12333          dahdi_close_pri_fd(pri, i);
12334          ast_log(LOG_ERROR, "Unable to get parameters for D-channel %d (%s)\n", x, strerror(errno));
12335          return -1;
12336       }
12337       if ((p.sigtype != DAHDI_SIG_HDLCFCS) && (p.sigtype != DAHDI_SIG_HARDHDLC)) {
12338          dahdi_close_pri_fd(pri, i);
12339          ast_log(LOG_ERROR, "D-channel %d is not in HDLC/FCS mode.  See /etc/dahdi/system.conf\n", x);
12340          return -1;
12341       }
12342       memset(&si, 0, sizeof(si));
12343       res = ioctl(pri->fds[i], DAHDI_SPANSTAT, &si);
12344       if (res) {
12345          dahdi_close_pri_fd(pri, i);
12346          ast_log(LOG_ERROR, "Unable to get span state for D-channel %d (%s)\n", x, strerror(errno));
12347       }
12348       if (!si.alarms)
12349          pri->dchanavail[i] |= DCHAN_NOTINALARM;
12350       else
12351          pri->dchanavail[i] &= ~DCHAN_NOTINALARM;
12352       memset(&bi, 0, sizeof(bi));
12353       bi.txbufpolicy = DAHDI_POLICY_IMMEDIATE;
12354       bi.rxbufpolicy = DAHDI_POLICY_IMMEDIATE;
12355       bi.numbufs = 32;
12356       bi.bufsize = 1024;
12357       if (ioctl(pri->fds[i], DAHDI_SET_BUFINFO, &bi)) {
12358          ast_log(LOG_ERROR, "Unable to set appropriate buffering on channel %d: %s\n", x, strerror(errno));
12359          dahdi_close_pri_fd(pri, i);
12360          return -1;
12361       }
12362       pri->dchans[i] = pri_new(pri->fds[i], pri->nodetype, pri->switchtype);
12363       /* Force overlap dial if we're doing GR-303! */
12364       if (pri->switchtype == PRI_SWITCH_GR303_TMC)
12365          pri->overlapdial |= DAHDI_OVERLAPDIAL_BOTH;
12366       pri_set_overlapdial(pri->dchans[i],(pri->overlapdial & DAHDI_OVERLAPDIAL_OUTGOING)?1:0);
12367 #ifdef HAVE_PRI_INBANDDISCONNECT
12368       pri_set_inbanddisconnect(pri->dchans[i], pri->inbanddisconnect);
12369 #endif
12370       /* Enslave to master if appropriate */
12371       if (i)
12372          pri_enslave(pri->dchans[0], pri->dchans[i]);
12373       if (!pri->dchans[i]) {
12374          dahdi_close_pri_fd(pri, i);
12375          ast_log(LOG_ERROR, "Unable to create PRI structure\n");
12376          return -1;
12377       }
12378       pri_set_debug(pri->dchans[i], DEFAULT_PRI_DEBUG);
12379       pri_set_nsf(pri->dchans[i], pri->nsf);
12380 #ifdef PRI_GETSET_TIMERS
12381       for (x = 0; x < PRI_MAX_TIMERS; x++) {
12382          if (pritimers[x] != 0)
12383             pri_set_timer(pri->dchans[i], x, pritimers[x]);
12384       }
12385 #endif
12386    }
12387    /* Assume primary is the one we use */
12388    pri->pri = pri->dchans[0];
12389    pri->resetpos = -1;
12390    if (ast_pthread_create_background(&pri->master, NULL, pri_dchannel, pri)) {
12391       for (i = 0; i < NUM_DCHANS; i++) {
12392          if (!pri->dchannels[i])
12393             break;
12394          dahdi_close_pri_fd(pri, i);
12395       }
12396       ast_log(LOG_ERROR, "Unable to spawn D-channel: %s\n", strerror(errno));
12397       return -1;
12398    }
12399    return 0;
12400 }
12401 
12402 static char *complete_span_helper(const char *line, const char *word, int pos, int state, int rpos)
12403 {
12404    int which, span;
12405    char *ret = NULL;
12406 
12407    if (pos != rpos)
12408       return ret;
12409 
12410    for (which = span = 0; span < NUM_SPANS; span++) {
12411       if (pris[span].pri && ++which > state) {
12412          if (asprintf(&ret, "%d", span + 1) < 0) { /* user indexes start from 1 */
12413             ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
12414          }
12415          break;
12416       }
12417    }
12418    return ret;
12419 }
12420 
12421 static char *complete_span_4(const char *line, const char *word, int pos, int state)
12422 {
12423    return complete_span_helper(line,word,pos,state,3);
12424 }
12425 
12426 static char *complete_span_5(const char *line, const char *word, int pos, int state)
12427 {
12428    return complete_span_helper(line,word,pos,state,4);
12429 }
12430 
12431 static int handle_pri_set_debug_file(int fd, int argc, char **argv)
12432 {
12433    int myfd;
12434 
12435    if (!strncasecmp(argv[1], "set", 3)) {
12436       if (argc < 5) 
12437          return RESULT_SHOWUSAGE;
12438 
12439       if (ast_strlen_zero(argv[4]))
12440          return RESULT_SHOWUSAGE;
12441 
12442       myfd = open(argv[4], O_CREAT|O_WRONLY, 0600);
12443       if (myfd < 0) {
12444          ast_cli(fd, "Unable to open '%s' for writing\n", argv[4]);
12445          return RESULT_SUCCESS;
12446       }
12447 
12448       ast_mutex_lock(&pridebugfdlock);
12449 
12450       if (pridebugfd >= 0)
12451          close(pridebugfd);
12452 
12453       pridebugfd = myfd;
12454       ast_copy_string(pridebugfilename,argv[4],sizeof(pridebugfilename));
12455       
12456       ast_mutex_unlock(&pridebugfdlock);
12457 
12458       ast_cli(fd, "PRI debug output will be sent to '%s'\n", argv[4]);
12459    } else {
12460       /* Assume it is unset */
12461       ast_mutex_lock(&pridebugfdlock);
12462       close(pridebugfd);
12463       pridebugfd = -1;
12464       ast_cli(fd, "PRI debug output to file disabled\n");
12465       ast_mutex_unlock(&pridebugfdlock);
12466    }
12467 
12468    return RESULT_SUCCESS;
12469 }
12470 
12471 #ifdef HAVE_PRI_VERSION
12472 static int handle_pri_version(int fd, int agc, char *argv[]) {
12473    ast_cli(fd, "libpri version: %s\n", pri_get_version());
12474    return RESULT_SUCCESS;
12475 }
12476 #endif
12477 
12478 static int handle_pri_debug(int fd, int argc, char *argv[])
12479 {
12480    int span;
12481    int x;
12482    if (argc < 4) {
12483       return RESULT_SHOWUSAGE;
12484    }
12485    span = atoi(argv[3]);
12486    if ((span < 1) || (span > NUM_SPANS)) {
12487       ast_cli(fd, "Invalid span %s.  Should be a number %d to %d\n", argv[3], 1, NUM_SPANS);
12488       return RESULT_SUCCESS;
12489    }
12490    if (!pris[span-1].pri) {
12491       ast_cli(fd, "No PRI running on span %d\n", span);
12492       return RESULT_SUCCESS;
12493    }
12494    for (x = 0; x < NUM_DCHANS; x++) {
12495       if (pris[span-1].dchans[x])
12496          pri_set_debug(pris[span-1].dchans[x], PRI_DEBUG_APDU |
12497                                                PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q931_STATE |
12498                                                PRI_DEBUG_Q921_STATE);
12499    }
12500    ast_cli(fd, "Enabled debugging on span %d\n", span);
12501    return RESULT_SUCCESS;
12502 }
12503 
12504 
12505 
12506 static int handle_pri_no_debug(int fd, int argc, char *argv[])
12507 {
12508    int span;
12509    int x;
12510    if (argc < 5)
12511       return RESULT_SHOWUSAGE;
12512    span = atoi(argv[4]);
12513    if ((span < 1) || (span > NUM_SPANS)) {
12514       ast_cli(fd, "Invalid span %s.  Should be a number %d to %d\n", argv[4], 1, NUM_SPANS);
12515       return RESULT_SUCCESS;
12516    }
12517    if (!pris[span-1].pri) {
12518       ast_cli(fd, "No PRI running on span %d\n", span);
12519       return RESULT_SUCCESS;
12520    }
12521    for (x = 0; x < NUM_DCHANS; x++) {
12522       if (pris[span-1].dchans[x])
12523          pri_set_debug(pris[span-1].dchans[x], 0);
12524    }
12525    ast_cli(fd, "Disabled debugging on span %d\n", span);
12526    return RESULT_SUCCESS;
12527 }
12528 
12529 static int handle_pri_really_debug(int fd, int argc, char *argv[])
12530 {
12531    int span;
12532    int x;
12533    if (argc < 5)
12534       return RESULT_SHOWUSAGE;
12535    span = atoi(argv[4]);
12536    if ((span < 1) || (span > NUM_SPANS)) {
12537       ast_cli(fd, "Invalid span %s.  Should be a number %d to %d\n", argv[4], 1, NUM_SPANS);
12538       return RESULT_SUCCESS;
12539    }
12540    if (!pris[span-1].pri) {
12541       ast_cli(fd, "No PRI running on span %d\n", span);
12542       return RESULT_SUCCESS;
12543    }
12544    for (x = 0; x < NUM_DCHANS; x++) {
12545       if (pris[span-1].dchans[x])
12546          pri_set_debug(pris[span-1].dchans[x], PRI_DEBUG_APDU |
12547                                                PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q931_STATE |
12548                                                PRI_DEBUG_Q921_RAW | PRI_DEBUG_Q921_DUMP | PRI_DEBUG_Q921_STATE);
12549    }
12550    ast_cli(fd, "Enabled EXTENSIVE debugging on span %d\n", span);
12551    return RESULT_SUCCESS;
12552 }
12553 
12554 static void build_status(char *s, size_t len, int status, int active)
12555 {
12556    if (!s || len < 1) {
12557       return;
12558    }
12559    s[0] = '\0';
12560    if (status & DCHAN_PROVISIONED)
12561       strncat(s, "Provisioned, ", len - strlen(s) - 1);
12562    if (!(status & DCHAN_NOTINALARM))
12563       strncat(s, "In Alarm, ", len - strlen(s) - 1);
12564    if (status & DCHAN_UP)
12565       strncat(s, "Up", len - strlen(s) - 1);
12566    else
12567       strncat(s, "Down", len - strlen(s) - 1);
12568    if (active)
12569       strncat(s, ", Active", len - strlen(s) - 1);
12570    else
12571       strncat(s, ", Standby", len - strlen(s) - 1);
12572    s[len - 1] = '\0';
12573 }
12574 
12575 static int handle_pri_show_spans(int fd, int argc, char *argv[])
12576 {
12577    int span;
12578    int x;
12579    char status[256];
12580    if (argc != 3)
12581       return RESULT_SHOWUSAGE;
12582 
12583    for (span = 0; span < NUM_SPANS; span++) {
12584       if (pris[span].pri) {
12585          for (x = 0; x < NUM_DCHANS; x++) {
12586             if (pris[span].dchannels[x]) {
12587                build_status(status, sizeof(status), pris[span].dchanavail[x], pris[span].dchans[x] == pris[span].pri);
12588                ast_cli(fd, "PRI span %d/%d: %s\n", span + 1, x, status);
12589             }
12590          }
12591       }
12592    }
12593    return RESULT_SUCCESS;
12594 }
12595 
12596 static int handle_pri_show_span(int fd, int argc, char *argv[])
12597 {
12598    int span;
12599    int x;
12600    char status[256];
12601    if (argc < 4)
12602       return RESULT_SHOWUSAGE;
12603    span = atoi(argv[3]);
12604    if ((span < 1) || (span > NUM_SPANS)) {
12605       ast_cli(fd, "Invalid span '%s'.  Should be a number from %d to %d\n", argv[3], 1, NUM_SPANS);
12606       return RESULT_SUCCESS;
12607    }
12608    if (!pris[span-1].pri) {
12609       ast_cli(fd, "No PRI running on span %d\n", span);
12610       return RESULT_SUCCESS;
12611    }
12612    for (x = 0; x < NUM_DCHANS; x++) {
12613       if (pris[span-1].dchannels[x]) {
12614 #ifdef PRI_DUMP_INFO_STR
12615          char *info_str = NULL;
12616 #endif
12617          ast_cli(fd, "%s D-channel: %d\n", pri_order(x), pris[span-1].dchannels[x]);
12618          build_status(status, sizeof(status), pris[span-1].dchanavail[x], pris[span-1].dchans[x] == pris[span-1].pri);
12619          ast_cli(fd, "Status: %s\n", status);
12620          ast_mutex_lock(&pris[span - 1].lock);
12621 #ifdef PRI_DUMP_INFO_STR
12622          info_str = pri_dump_info_str(pris[span-1].pri);
12623          if (info_str) {
12624             ast_cli(fd, "%s", info_str);
12625             free(info_str);
12626          }
12627 #else
12628          pri_dump_info(pris[span-1].pri);
12629 #endif
12630          ast_mutex_unlock(&pris[span - 1].lock);
12631          ast_cli(fd, "Overlap Recv: %s\n\n", (pris[span-1].overlapdial & DAHDI_OVERLAPDIAL_INCOMING)?"Yes":"No");
12632       }
12633    }
12634    return RESULT_SUCCESS;
12635 }
12636 
12637 static int handle_pri_show_debug(int fd, int argc, char *argv[])
12638 {
12639    int x;
12640    int span;
12641    int count=0;
12642    int debug=0;
12643 
12644    for (span = 0; span < NUM_SPANS; span++) {
12645            if (pris[span].pri) {
12646          for (x = 0; x < NUM_DCHANS; x++) {
12647             debug = 0;
12648                if (pris[span].dchans[x]) {
12649                   debug = pri_get_debug(pris[span].dchans[x]);
12650                ast_cli(fd, "Span %d: Debug: %s\tIntense: %s\n", span+1, (debug&PRI_DEBUG_Q931_STATE)? "Yes" : "No" ,(debug&PRI_DEBUG_Q921_RAW)? "Yes" : "No" );
12651                count++;
12652             }
12653          }
12654       }
12655 
12656    }
12657    ast_mutex_lock(&pridebugfdlock);
12658    if (pridebugfd >= 0) 
12659       ast_cli(fd, "Logging PRI debug to file %s\n", pridebugfilename);
12660    ast_mutex_unlock(&pridebugfdlock);
12661        
12662    if (!count) 
12663       ast_cli(fd, "No debug set or no PRI running\n");
12664    return RESULT_SUCCESS;
12665 }
12666 
12667 static const char pri_debug_help[] = 
12668    "Usage: pri debug span <span>\n"
12669    "       Enables debugging on a given PRI span\n";
12670    
12671 static const char pri_no_debug_help[] = 
12672    "Usage: pri no debug span <span>\n"
12673    "       Disables debugging on a given PRI span\n";
12674 
12675 static const char pri_really_debug_help[] = 
12676    "Usage: pri intensive debug span <span>\n"
12677    "       Enables debugging down to the Q.921 level\n";
12678 
12679 static const char pri_show_span_help[] = 
12680    "Usage: pri show span <span>\n"
12681    "       Displays PRI Information on a given PRI span\n";
12682 
12683 static const char pri_show_spans_help[] = 
12684    "Usage: pri show spans\n"
12685    "       Displays PRI Information\n";
12686 
12687 static struct ast_cli_entry dahdi_pri_cli[] = {
12688    { { "pri", "debug", "span", NULL },
12689    handle_pri_debug, "Enables PRI debugging on a span",
12690    pri_debug_help, complete_span_4 },
12691 
12692    { { "pri", "no", "debug", "span", NULL },
12693    handle_pri_no_debug, "Disables PRI debugging on a span",
12694    pri_no_debug_help, complete_span_5 },
12695 
12696    { { "pri", "intense", "debug", "span", NULL },
12697    handle_pri_really_debug, "Enables REALLY INTENSE PRI debugging",
12698    pri_really_debug_help, complete_span_5 },
12699 
12700    { { "pri", "show", "spans", NULL },
12701    handle_pri_show_spans, "Displays PRI Information",
12702    pri_show_spans_help },
12703 
12704    { { "pri", "show", "span", NULL },
12705    handle_pri_show_span, "Displays PRI Information",
12706    pri_show_span_help, complete_span_4 },
12707 
12708    { { "pri", "show", "debug", NULL },
12709    handle_pri_show_debug, "Displays current PRI debug settings" },
12710 
12711    { { "pri", "set", "debug", "file", NULL },
12712    handle_pri_set_debug_file, "Sends PRI debug output to the specified file" },
12713 
12714    { { "pri", "unset", "debug", "file", NULL },
12715    handle_pri_set_debug_file, "Ends PRI debug output to file" },
12716 
12717 #ifdef HAVE_PRI_VERSION
12718    { { "pri", "show", "version", NULL },
12719    handle_pri_version, "Displays version of libpri" },
12720 #endif
12721 };
12722 
12723 #endif /* HAVE_PRI */
12724 
12725 #ifdef HAVE_OPENR2
12726 
12727 static int handle_mfcr2_version(int fd, int argc, char *argv[])
12728 {
12729    ast_cli(fd, "OpenR2 version: %s, revision: %s\n", openr2_get_version(), openr2_get_revision());
12730    return RESULT_SUCCESS;
12731 }
12732 
12733 static int handle_mfcr2_show_variants(int fd, int argc, char *argv[]) 
12734 {
12735 #define FORMAT "%4s %40s\n"
12736    int numvariants = 0;
12737    int i;
12738    const openr2_variant_entry_t *variants;
12739    if (!(variants = openr2_proto_get_variant_list(&numvariants))) {
12740       ast_cli(fd, "Failed to get list of variants.\n");
12741       return RESULT_FAILURE;
12742    }
12743    ast_cli(fd, FORMAT, "Variant Code", "Country");
12744    for (i = 0; i < numvariants; i++) {
12745       ast_cli(fd, FORMAT, variants[i].name, variants[i].country);
12746    }
12747    return RESULT_SUCCESS;
12748 #undef FORMAT
12749 }  
12750 
12751 static int handle_mfcr2_show_channels(int fd, int argc, char *argv[])
12752 {
12753 #define FORMAT "%4s %-7.7s %-7.7s %-8.8s %-9.9s %-16.16s %-8.8s %-8.8s\n"
12754    int filtertype = 0;
12755    int targetnum = 0;
12756    char channo[5];
12757    char anino[5];
12758    char dnisno[5];
12759    struct dahdi_pvt *p;
12760    openr2_context_t *r2context;
12761    openr2_variant_t r2variant;
12762    if (!((argc == 3) || (argc == 5))) {
12763       return RESULT_SHOWUSAGE;
12764    }
12765    if (argc == 5) {
12766       if (!strcasecmp(argv[3], "group")) {
12767          targetnum = atoi(argv[4]);
12768          if ((targetnum < 0) || (targetnum > 63))
12769             return RESULT_SHOWUSAGE;
12770          targetnum = 1 << targetnum;
12771          filtertype = 1;
12772       } else if (!strcasecmp(argv[3], "context")) {
12773          filtertype = 2;
12774       } else {
12775          return RESULT_SHOWUSAGE;
12776       }
12777    }
12778    ast_cli(fd, FORMAT, "Chan", "Variant", "Max ANI", "Max DNIS", "ANI First", "Immediate Accept", "Tx CAS", "Rx CAS");
12779    ast_mutex_lock(&iflock);
12780    p = iflist;
12781    while (p) {
12782       if (!(p->sig & SIG_MFCR2) || !p->r2chan) {
12783          p = p->next;
12784          continue;
12785       }
12786       if (filtertype) {
12787          switch(filtertype) {
12788          case 1: /* mfcr2 show channels group <group> */
12789             if (p->group != targetnum) {
12790                p = p->next;
12791                continue;
12792             }
12793             break;
12794          case 2: /* mfcr2 show channels context <context> */
12795             if (strcasecmp(p->context, argv[4])) {
12796                p= p->next;
12797                continue;
12798             }
12799             break;
12800          default:
12801             ;
12802          }
12803       }
12804       r2context = openr2_chan_get_context(p->r2chan);
12805       r2variant = openr2_context_get_variant(r2context);
12806       snprintf(channo, sizeof(channo), "%d", p->channel);
12807       snprintf(anino, sizeof(anino), "%d", openr2_context_get_max_ani(r2context));
12808       snprintf(dnisno, sizeof(dnisno), "%d", openr2_context_get_max_dnis(r2context));
12809       ast_cli(fd, FORMAT, channo, openr2_proto_get_variant_string(r2variant), 
12810             anino, dnisno, openr2_context_get_ani_first(r2context) ? "Yes" : "No",  
12811             openr2_context_get_immediate_accept(r2context) ? "Yes" : "No",
12812             openr2_chan_get_tx_cas_string(p->r2chan), openr2_chan_get_rx_cas_string(p->r2chan));
12813       p = p->next;
12814    }
12815    ast_mutex_unlock(&iflock);
12816    return RESULT_SUCCESS;
12817 #undef FORMAT
12818 }
12819 
12820 static int handle_mfcr2_set_debug(int fd, int argc, char *argv[])
12821 {
12822    struct dahdi_pvt *p = NULL;
12823    int channo = 0;
12824    char *toklevel = NULL;
12825    char *saveptr = NULL;
12826    char *logval = NULL;
12827    openr2_log_level_t loglevel = OR2_LOG_NOTHING;
12828    openr2_log_level_t tmplevel = OR2_LOG_NOTHING;
12829    if (argc < 4) {
12830       return RESULT_SHOWUSAGE;
12831    }
12832    channo = (argc == 5) ? atoi(argv[4]) : -1;
12833    logval = ast_strdupa(argv[3]);
12834    toklevel = strtok_r(logval, ",", &saveptr);
12835    if (-1 == (tmplevel = openr2_log_get_level(toklevel))) {
12836       ast_cli(fd, "Invalid MFC/R2 logging level '%s'.\n", argv[3]);
12837       return RESULT_FAILURE;
12838    } else if (OR2_LOG_NOTHING == tmplevel) {
12839       loglevel = tmplevel;
12840    } else {
12841       loglevel |= tmplevel;
12842       while ((toklevel = strtok_r(NULL, ",", &saveptr))) {
12843          if (-1 == (tmplevel = openr2_log_get_level(toklevel))) {
12844             ast_cli(fd, "Ignoring invalid logging level: '%s'.\n", toklevel);
12845             continue;
12846          }
12847          loglevel |= tmplevel;
12848       }
12849    }
12850    ast_mutex_lock(&iflock);
12851    p = iflist;
12852    while (p) {
12853       if (!(p->sig & SIG_MFCR2) || !p->r2chan) {
12854          p = p->next;
12855          continue;
12856       }
12857       if ((channo != -1) && (p->channel != channo )) {
12858          p = p->next;
12859          continue;
12860       }
12861       openr2_chan_set_log_level(p->r2chan, loglevel);
12862       if (channo != -1) {
12863          ast_cli(fd, "MFC/R2 debugging set to '%s' for channel %d.\n", argv[3], p->channel);
12864          break;
12865       } else {
12866          p = p->next;
12867       }
12868    }
12869    if ((channo != -1) && !p) {
12870       ast_cli(fd, "MFC/R2 channel %d not found.\n", channo);
12871    }
12872    if (channo == -1) {
12873       ast_cli(fd, "MFC/R2 debugging set to '%s' for all channels.\n", argv[3]);
12874    }
12875    ast_mutex_unlock(&iflock);
12876    return RESULT_SUCCESS;
12877 }
12878 
12879 static int handle_mfcr2_call_files(int fd, int argc, char *argv[])
12880 {
12881    struct dahdi_pvt *p = NULL;
12882    int channo = 0;
12883    if (argc < 4) {
12884       return RESULT_SHOWUSAGE;
12885    }
12886    channo = (argc == 5) ? atoi(argv[4]) : -1;
12887    ast_mutex_lock(&iflock);
12888    p = iflist;
12889    while (p) {
12890       if (!(p->sig & SIG_MFCR2) || !p->r2chan) {
12891          p = p->next;
12892          continue;
12893       }
12894       if ((channo != -1) && (p->channel != channo )) {
12895          p = p->next;
12896          continue;
12897       }
12898       if (ast_true(argv[3])) {
12899          openr2_chan_enable_call_files(p->r2chan);
12900       } else {
12901          openr2_chan_disable_call_files(p->r2chan);
12902       }
12903       if (channo != -1) {
12904          if (ast_true(argv[3])) {
12905             ast_cli(fd, "MFC/R2 call files enabled for channel %d.\n", p->channel);
12906          } else {
12907             ast_cli(fd, "MFC/R2 call files disabled for channel %d.\n", p->channel);
12908          }
12909          break;
12910       } else {
12911          p = p->next;
12912       }
12913    }
12914    if ((channo != -1) && !p) {
12915       ast_cli(fd, "MFC/R2 channel %d not found.\n", channo);
12916    }
12917    if (channo == -1) {
12918       if (ast_true(argv[3])) {
12919          ast_cli(fd, "MFC/R2 Call files enabled for all channels.\n");
12920       } else {
12921          ast_cli(fd, "MFC/R2 Call files disabled for all channels.\n");
12922       }  
12923    }
12924    ast_mutex_unlock(&iflock);
12925    return RESULT_SUCCESS;
12926 }  
12927 
12928 static int handle_mfcr2_set_idle(int fd, int argc, char *argv[])
12929 {
12930    struct dahdi_pvt *p = NULL;
12931    int channo = 0;
12932    channo = (argc == 4) ? atoi(argv[3]) : -1;
12933    ast_mutex_lock(&iflock);
12934    p = iflist;
12935    while (p) {
12936       if (!(p->sig & SIG_MFCR2) || !p->r2chan) {
12937          p = p->next;
12938          continue;
12939       }
12940       if ((channo != -1) && (p->channel != channo )) {
12941          p = p->next;
12942          continue;
12943       }
12944       if (!openr2_chan_set_idle(p->r2chan)) {
12945          ast_mutex_lock(&p->lock);
12946          p->mfcr2call = 0;
12947          p->mfcr2block &= ~DAHDI_R2_LOCAL_BLOCK;
12948          ast_mutex_unlock(&p->lock);
12949       }
12950       if (channo != -1) {
12951          break;
12952       } else {
12953          p = p->next;
12954       }
12955    }
12956    if ((channo != -1) && !p) {
12957       ast_cli(fd, "MFC/R2 channel %d not found.\n", channo);
12958    }
12959    ast_mutex_unlock(&iflock);
12960    return RESULT_SUCCESS;
12961 }
12962 
12963 static int handle_mfcr2_set_blocked(int fd, int argc, char *argv[])
12964 {
12965    struct dahdi_pvt *p = NULL;
12966    int channo = 0;
12967    channo = (argc == 4) ? atoi(argv[3]) : -1;
12968    ast_mutex_lock(&iflock);
12969    p = iflist;
12970    while (p) {
12971       if (!(p->sig & SIG_MFCR2) || !p->r2chan) {
12972          p = p->next;
12973          continue;
12974       }
12975       if ((channo != -1) && (p->channel != channo )) {
12976          p = p->next;
12977          continue;
12978       }
12979       if (!openr2_chan_set_blocked(p->r2chan)) {
12980          ast_mutex_lock(&p->lock);
12981          p->mfcr2block |= DAHDI_R2_LOCAL_BLOCK;
12982          ast_mutex_unlock(&p->lock);
12983       } else {
12984          ast_cli(fd, "MFC/R2 channel %d could not be blocked.\n", p->channel);
12985       }
12986       if (channo != -1) {
12987          break;
12988       } else {
12989          p = p->next;
12990       }
12991    }
12992    if ((channo != -1) && !p) {
12993       ast_cli(fd, "MFC/R2 channel %d not found.\n", channo);
12994    }
12995    ast_mutex_unlock(&iflock);
12996    return RESULT_SUCCESS;
12997 }
12998 
12999 static const char dahdi_r2_version_help[] = 
13000          "Usage: mfcr2 show version\n"
13001          "       Shows the version of the OpenR2 library being used.\n";
13002 static const char dahdi_r2_variants_help[] = 
13003          "Usage: mfcr2 show variants\n"
13004          "       Show supported MFC/R2 variants.\n";
13005 static const char dahdi_r2_showchannels_help[] =
13006          "Usage: mfcr2 show channels [group <group> | context <context>]\n"
13007          "       Shows the zap channels configured with MFC/R2 signaling.\n";
13008 static const char dahdi_r2_setdebug_help[] =
13009          "Usage: mfcr2 set debug <loglevel> <channel>\n"
13010          "       Set a new logging level for the specified channel.\n"
13011          "       If no channel is specified the logging level will be applied to all channels.\n";
13012 static const char dahdi_r2_callfiles_help[] =
13013          "Usage: mfcr2 call files [on|off] <channel>\n"
13014          "       Enable call files creation on the specified channel.\n"
13015          "       If no channel is specified call files creation policy will be applied to all channels.\n";
13016 static const char dahdi_r2_setidle_help[] =
13017          "Usage: mfcr2 set idle <channel>\n"
13018          "       DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING.\n"
13019          "       Force the given channel into IDLE state.\n"
13020          "       If no channel is specified, all channels will be set to IDLE.\n";
13021 static const char dahdi_r2_setblocked_help[] =
13022          "Usage: mfcr2 set blocked <channel>\n"
13023          "       DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING.\n"
13024          "       Force the given channel into BLOCKED state.\n"
13025          "       If no channel is specified, all channels will be set to BLOCKED.\n";
13026 
13027 static struct ast_cli_entry dahdi_mfcr2_cli[] = {
13028    { { "mfcr2", "show", "version", NULL },
13029    handle_mfcr2_version, "Show OpenR2 library version",
13030    dahdi_r2_version_help },
13031 
13032    { { "mfcr2", "show", "variants", NULL },
13033    handle_mfcr2_show_variants, "Show supported MFC/R2 variants",
13034    dahdi_r2_variants_help },
13035 
13036    { { "mfcr2", "show", "channels", NULL },
13037    handle_mfcr2_show_channels, "Show MFC/R2 channels",
13038    dahdi_r2_showchannels_help },
13039 
13040    { { "mfcr2", "set", "debug", NULL },
13041    handle_mfcr2_set_debug, "Set MFC/R2 channel logging level",
13042    dahdi_r2_setdebug_help },
13043 
13044    { { "mfcr2", "call", "files", NULL },
13045    handle_mfcr2_call_files, "Enable/Disable MFC/R2 call files",
13046    dahdi_r2_callfiles_help },
13047 
13048    { { "mfcr2", "set", "idle", NULL },
13049    handle_mfcr2_set_idle, "Reset MFC/R2 channel forcing it to IDLE",
13050    dahdi_r2_setidle_help },
13051 
13052    { { "mfcr2", "set", "blocked", NULL },
13053    handle_mfcr2_set_blocked, "Reset MFC/R2 channel forcing it to BLOCKED",
13054    dahdi_r2_setblocked_help }
13055 
13056 };
13057 
13058 #endif /* HAVE_OPENR2 */
13059 
13060 static int dahdi_destroy_channel(int fd, int argc, char **argv)
13061 {
13062    int channel;
13063    
13064    if (argc != 4)
13065       return RESULT_SHOWUSAGE;
13066    
13067    channel = atoi(argv[3]);
13068 
13069    return dahdi_destroy_channel_bynum(channel);
13070 }
13071 
13072 static void dahdi_softhangup_all(void)
13073 {
13074    struct dahdi_pvt *p;
13075 retry:
13076    ast_mutex_lock(&iflock);
13077     for (p = iflist; p; p = p->next) {
13078       ast_mutex_lock(&p->lock);
13079         if (p->owner && !p->restartpending) {
13080          if (ast_channel_trylock(p->owner)) {
13081             if (option_debug > 2)
13082                ast_verbose("Avoiding deadlock\n");
13083             /* Avoid deadlock since you're not supposed to lock iflock or pvt before a channel */
13084             ast_mutex_unlock(&p->lock);
13085             ast_mutex_unlock(&iflock);
13086             goto retry;
13087          }
13088          if (option_debug > 2)
13089             ast_verbose("Softhanging up on %s\n", p->owner->name);
13090          ast_softhangup_nolock(p->owner, AST_SOFTHANGUP_EXPLICIT);
13091          p->restartpending = 1;
13092          num_restart_pending++;
13093          ast_channel_unlock(p->owner);
13094       }
13095       ast_mutex_unlock(&p->lock);
13096     }
13097    ast_mutex_unlock(&iflock);
13098 }
13099 
13100 static int setup_dahdi(int reload);
13101 static int dahdi_restart(void)
13102 {
13103 
13104 #ifdef HAVE_OPENR2
13105    int r;
13106 #endif
13107   
13108 #if defined(HAVE_PRI)
13109    int i, j;
13110 #endif
13111    int cancel_code;
13112    struct dahdi_pvt *p;
13113 
13114    ast_mutex_lock(&restart_lock);
13115  
13116    if (option_verbose)
13117       ast_verbose("Destroying channels and reloading DAHDI configuration.\n");
13118    dahdi_softhangup_all();
13119    if (option_verbose > 3)
13120       ast_verbose("Initial softhangup of all DAHDI channels complete.\n");
13121 
13122 #ifdef HAVE_OPENR2
13123    for (r = 0; r < NUM_SPANS; r++) {
13124       if (r2links[r].master != AST_PTHREADT_NULL) {
13125          ast_log(LOG_DEBUG, "Killing MFC/R2 monitor thread %p\n", &r2links[r].master);
13126          pthread_cancel(r2links[r].master);
13127          pthread_join(r2links[r].master, NULL);
13128          openr2_context_delete(r2links[r].protocol_context);
13129       }
13130    }
13131    init_mfcr2_globals();
13132 #endif
13133    
13134    #if defined(HAVE_PRI)
13135    for (i = 0; i < NUM_SPANS; i++) {
13136       if (pris[i].master && (pris[i].master != AST_PTHREADT_NULL)) {
13137          cancel_code = pthread_cancel(pris[i].master);
13138          pthread_kill(pris[i].master, SIGURG);
13139          if (option_debug > 3)
13140             ast_verbose("Waiting to join thread of span %d with pid=%p, cancel_code=%d\n", i, (void *) pris[i].master, cancel_code);
13141             pthread_join(pris[i].master, NULL);
13142          if (option_debug > 3)
13143             ast_verbose("Joined thread of span %d\n", i);
13144       }
13145     }
13146    #endif
13147 
13148     ast_mutex_lock(&monlock);
13149     if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) {
13150       cancel_code = pthread_cancel(monitor_thread);
13151       pthread_kill(monitor_thread, SIGURG);
13152       if (option_debug > 3)
13153          ast_verbose("Waiting to join monitor thread with pid=%p, cancel_code=%d\n", (void *) monitor_thread, cancel_code);
13154         pthread_join(monitor_thread, NULL);
13155       if (option_debug > 3)
13156          ast_verbose("Joined monitor thread\n");
13157     }
13158    monitor_thread = AST_PTHREADT_NULL; /* prepare to restart thread in setup_dahdi once channels are reconfigured */
13159 
13160    ast_mutex_lock(&ss_thread_lock);
13161    while (ss_thread_count > 0) { /* let ss_threads finish and run dahdi_hangup before dahvi_pvts are destroyed */
13162       int x = DAHDI_FLASH;
13163       if (option_debug > 2)
13164          ast_verbose("Waiting on %d ss_thread(s) to finish\n", ss_thread_count);
13165 
13166       for (p = iflist; p; p = p->next) {
13167          if (p->owner)
13168             ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x); /* important to create an event for dahdi_wait_event to register so that all ss_threads terminate */    
13169       }
13170       ast_cond_wait(&ss_thread_complete, &ss_thread_lock);
13171    }
13172 
13173    /* ensure any created channels before monitor threads were stopped are hungup */
13174    dahdi_softhangup_all();
13175    if (option_verbose > 3)
13176       ast_verbose("Final softhangup of all DAHDI channels complete.\n");
13177    destroy_all_channels();
13178    if (option_debug)
13179       ast_verbose("Channels destroyed. Now re-reading config. %d active channels remaining.\n", ast_active_channels());
13180 
13181     ast_mutex_unlock(&monlock);
13182 
13183    #ifdef HAVE_PRI
13184    for (i = 0; i < NUM_SPANS; i++) {
13185       for (j = 0; j < NUM_DCHANS; j++)
13186             dahdi_close_pri_fd(&(pris[i]), j);
13187    }
13188 
13189    memset(pris, 0, sizeof(pris));
13190    for (i = 0; i < NUM_SPANS; i++) {
13191       ast_mutex_init(&pris[i].lock);
13192       pris[i].offset = -1;
13193       pris[i].master = AST_PTHREADT_NULL;
13194       for (j = 0; j < NUM_DCHANS; j++)
13195          pris[i].fds[j] = -1;
13196    }
13197    pri_set_error(dahdi_pri_error);
13198    pri_set_message(dahdi_pri_message);
13199    #endif
13200 
13201    if (setup_dahdi(2) != 0) {
13202       ast_log(LOG_WARNING, "Reload channels from dahdi config failed!\n");
13203       ast_mutex_unlock(&ss_thread_lock);
13204       return 1;
13205    }
13206    ast_mutex_unlock(&ss_thread_lock);
13207    ast_mutex_unlock(&restart_lock);
13208    return 0;
13209 }
13210 
13211 static int dahdi_restart_cmd(int fd, int argc, char **argv)
13212 {
13213    if (argc != 2) {
13214       return RESULT_SHOWUSAGE;
13215    }
13216 
13217    if (dahdi_restart() != 0)
13218       return RESULT_FAILURE;
13219    return RESULT_SUCCESS;
13220 }
13221 
13222 static int dahdi_show_channels(int fd, int argc, char **argv)
13223 {
13224 #define FORMAT "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n"
13225 #define FORMAT2 "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n"
13226    struct dahdi_pvt *tmp = NULL;
13227    char tmps[20] = "";
13228    ast_mutex_t *lock;
13229    struct dahdi_pvt *start;
13230 #ifdef HAVE_PRI
13231    int trunkgroup;
13232    struct dahdi_pri *pri = NULL;
13233    int x;
13234 #endif
13235 
13236    lock = &iflock;
13237    start = iflist;
13238 
13239 #ifdef HAVE_PRI
13240    if (argc == 4) {
13241       if ((trunkgroup = atoi(argv[3])) < 1)
13242          return RESULT_SHOWUSAGE;
13243       for (x = 0; x < NUM_SPANS; x++) {
13244          if (pris[x].trunkgroup == trunkgroup) {
13245             pri = pris + x;
13246             break;
13247          }
13248       }
13249       if (pri) {
13250          start = pri->crvs;
13251          lock = &pri->lock;
13252       } else {
13253          ast_cli(fd, "No such trunk group %d\n", trunkgroup);
13254          return RESULT_FAILURE;
13255       }
13256    } else
13257 #endif
13258    if (argc != 3)
13259       return RESULT_SHOWUSAGE;
13260 
13261    ast_mutex_lock(lock);
13262 #ifdef HAVE_PRI
13263    ast_cli(fd, FORMAT2, pri ? "CRV" : "Chan", "Extension", "Context", "Language", "MOH Interpret");
13264 #else
13265    ast_cli(fd, FORMAT2, "Chan", "Extension", "Context", "Language", "MOH Interpret");
13266 #endif   
13267    
13268    tmp = start;
13269    while (tmp) {
13270       if (tmp->channel > 0) {
13271          snprintf(tmps, sizeof(tmps), "%d", tmp->channel);
13272       } else
13273          ast_copy_string(tmps, "pseudo", sizeof(tmps));
13274       ast_cli(fd, FORMAT, tmps, tmp->exten, tmp->context, tmp->language, tmp->mohinterpret);
13275       tmp = tmp->next;
13276    }
13277    ast_mutex_unlock(lock);
13278    return RESULT_SUCCESS;
13279 #undef FORMAT
13280 #undef FORMAT2
13281 }
13282 
13283 static int dahdi_show_channel(int fd, int argc, char **argv)
13284 {
13285    int channel;
13286    struct dahdi_pvt *tmp = NULL;
13287    struct dahdi_confinfo ci;
13288    struct dahdi_params ps;
13289    int x;
13290    ast_mutex_t *lock;
13291    struct dahdi_pvt *start;
13292 #ifdef HAVE_PRI
13293    char *c;
13294    int trunkgroup;
13295    struct dahdi_pri *pri=NULL;
13296 #endif
13297 
13298    lock = &iflock;
13299    start = iflist;
13300 
13301    if (argc != 4)
13302       return RESULT_SHOWUSAGE;
13303 #ifdef HAVE_PRI
13304    if ((c = strchr(argv[3], ':'))) {
13305       if (sscanf(argv[3], "%30d:%30d", &trunkgroup, &channel) != 2)
13306          return RESULT_SHOWUSAGE;
13307       if ((trunkgroup < 1) || (channel < 1))
13308          return RESULT_SHOWUSAGE;
13309       for (x = 0; x < NUM_SPANS; x++) {
13310          if (pris[x].trunkgroup == trunkgroup) {
13311             pri = pris + x;
13312             break;
13313          }
13314       }
13315       if (pri) {
13316          start = pri->crvs;
13317          lock = &pri->lock;
13318       } else {
13319          ast_cli(fd, "No such trunk group %d\n", trunkgroup);
13320          return RESULT_FAILURE;
13321       }
13322    } else
13323 #endif
13324       channel = atoi(argv[3]);
13325 
13326    ast_mutex_lock(lock);
13327    tmp = start;
13328    while (tmp) {
13329       if (tmp->channel == channel) {
13330 #ifdef HAVE_PRI
13331          if (pri) 
13332             ast_cli(fd, "Trunk/CRV: %d/%d\n", trunkgroup, tmp->channel);
13333          else
13334 #endif         
13335          ast_cli(fd, "Channel: %d\n", tmp->channel);
13336          ast_cli(fd, "File Descriptor: %d\n", tmp->subs[SUB_REAL].dfd);
13337          ast_cli(fd, "Span: %d\n", tmp->span);
13338          ast_cli(fd, "Extension: %s\n", tmp->exten);
13339          ast_cli(fd, "Dialing: %s\n", tmp->dialing ? "yes" : "no");
13340          ast_cli(fd, "Context: %s\n", tmp->context);
13341          ast_cli(fd, "Caller ID: %s\n", tmp->cid_num);
13342          ast_cli(fd, "Calling TON: %d\n", tmp->cid_ton);
13343          ast_cli(fd, "Caller ID name: %s\n", tmp->cid_name);
13344          ast_cli(fd, "Destroy: %d\n", tmp->destroy);
13345          ast_cli(fd, "InAlarm: %d\n", tmp->inalarm);
13346          ast_cli(fd, "Signalling Type: %s\n", sig2str(tmp->sig));
13347          ast_cli(fd, "Radio: %d\n", tmp->radio);
13348          ast_cli(fd, "Owner: %s\n", tmp->owner ? tmp->owner->name : "<None>");
13349          ast_cli(fd, "Real: %s%s%s\n", tmp->subs[SUB_REAL].owner ? tmp->subs[SUB_REAL].owner->name : "<None>", tmp->subs[SUB_REAL].inthreeway ? " (Confed)" : "", tmp->subs[SUB_REAL].linear ? " (Linear)" : "");
13350          ast_cli(fd, "Callwait: %s%s%s\n", tmp->subs[SUB_CALLWAIT].owner ? tmp->subs[SUB_CALLWAIT].owner->name : "<None>", tmp->subs[SUB_CALLWAIT].inthreeway ? " (Confed)" : "", tmp->subs[SUB_CALLWAIT].linear ? " (Linear)" : "");
13351          ast_cli(fd, "Threeway: %s%s%s\n", tmp->subs[SUB_THREEWAY].owner ? tmp->subs[SUB_THREEWAY].owner->name : "<None>", tmp->subs[SUB_THREEWAY].inthreeway ? " (Confed)" : "", tmp->subs[SUB_THREEWAY].linear ? " (Linear)" : "");
13352          ast_cli(fd, "Confno: %d\n", tmp->confno);
13353          ast_cli(fd, "Propagated Conference: %d\n", tmp->propconfno);
13354          ast_cli(fd, "Real in conference: %d\n", tmp->inconference);
13355          ast_cli(fd, "DSP: %s\n", tmp->dsp ? "yes" : "no");
13356          ast_cli(fd, "Relax DTMF: %s\n", tmp->dtmfrelax ? "yes" : "no");
13357          ast_cli(fd, "Dialing/CallwaitCAS: %d/%d\n", tmp->dialing, tmp->callwaitcas);
13358          ast_cli(fd, "Default law: %s\n", tmp->law == DAHDI_LAW_MULAW ? "ulaw" : tmp->law == DAHDI_LAW_ALAW ? "alaw" : "unknown");
13359          ast_cli(fd, "Fax Handled: %s\n", tmp->faxhandled ? "yes" : "no");
13360          ast_cli(fd, "Pulse phone: %s\n", tmp->pulsedial ? "yes" : "no");
13361          ast_cli(fd, "Echo Cancellation: %d taps%s, currently %s\n", tmp->echocancel, tmp->echocanbridged ? "" : " unless TDM bridged", tmp->echocanon ? "ON" : "OFF");
13362          if (tmp->master)
13363             ast_cli(fd, "Master Channel: %d\n", tmp->master->channel);
13364          for (x = 0; x < MAX_SLAVES; x++) {
13365             if (tmp->slaves[x])
13366                ast_cli(fd, "Slave Channel: %d\n", tmp->slaves[x]->channel);
13367          }
13368 
13369 #ifdef HAVE_OPENR2
13370          if (tmp->mfcr2) {
13371             char calldir[OR2_MAX_PATH];
13372             openr2_context_t *r2context = openr2_chan_get_context(tmp->r2chan);
13373             openr2_variant_t r2variant = openr2_context_get_variant(r2context);
13374             ast_cli(fd, "MFC/R2 Call: %s\n", tmp->mfcr2call ? "Yes" : "No");
13375             ast_cli(fd, "MFC/R2 Blocked: %s\n", tmp->mfcr2block ? "Yes" : "No");
13376             ast_cli(fd, "MFC/R2 MF State: %s\n", openr2_chan_get_mf_state_string(tmp->r2chan));
13377             ast_cli(fd, "MFC/R2 MF Group: %s\n", openr2_chan_get_mf_group_string(tmp->r2chan));
13378             ast_cli(fd, "MFC/R2 State: %s\n", openr2_chan_get_r2_state_string(tmp->r2chan));
13379             ast_cli(fd, "MFC/R2 Call State: %s\n", openr2_chan_get_call_state_string(tmp->r2chan));
13380             ast_cli(fd, "MFC/R2 Call Files Enabled: %s\n", openr2_chan_get_call_files_enabled(tmp->r2chan) ? "Yes" : "No");
13381             ast_cli(fd, "MFC/R2 Variant: %s\n", openr2_proto_get_variant_string(r2variant));
13382             ast_cli(fd, "MFC/R2 Max ANI: %d\n", openr2_context_get_max_ani(r2context));
13383             ast_cli(fd, "MFC/R2 Max DNIS: %d\n", openr2_context_get_max_dnis(r2context));
13384 #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 2
13385             ast_cli(fd, "MFC/R2 DTMF Dialing: %s\n", openr2_context_get_dtmf_dialing(r2context, NULL, NULL) ? "Yes" : "No");
13386             ast_cli(fd, "MFC/R2 DTMF Detection: %s\n", openr2_context_get_dtmf_detection(r2context) ? "Yes" : "No");
13387 #endif
13388             ast_cli(fd, "MFC/R2 Get ANI First: %s\n", openr2_context_get_ani_first(r2context) ? "Yes" : "No");
13389             ast_cli(fd, "MFC/R2 Skip Category: %s\n", openr2_context_get_skip_category_request(r2context) ? "Yes" : "No");
13390             ast_cli(fd, "MFC/R2 Immediate Accept: %s\n", openr2_context_get_immediate_accept(r2context) ? "Yes" : "No");
13391             ast_cli(fd, "MFC/R2 Accept On Offer: %s\n", tmp->mfcr2_accept_on_offer ? "Yes" : "No");
13392             ast_cli(fd, "MFC/R2 Charge Calls: %s\n", tmp->mfcr2_charge_calls ? "Yes" : "No");
13393             ast_cli(fd, "MFC/R2 Allow Collect Calls: %s\n", tmp->mfcr2_allow_collect_calls ? "Yes" : "No");
13394             ast_cli(fd, "MFC/R2 Forced Release: %s\n", tmp->mfcr2_forced_release ? "Yes" : "No");
13395             ast_cli(fd, "MFC/R2 MF Back Timeout: %dms\n", openr2_context_get_mf_back_timeout(r2context));
13396             ast_cli(fd, "MFC/R2 R2 Metering Pulse Timeout: %dms\n", openr2_context_get_metering_pulse_timeout(r2context));
13397             ast_cli(fd, "MFC/R2 Rx CAS: %s\n", openr2_chan_get_rx_cas_string(tmp->r2chan));
13398             ast_cli(fd, "MFC/R2 Tx CAS : %s\n", openr2_chan_get_tx_cas_string(tmp->r2chan));
13399             ast_cli(fd, "MFC/R2 MF Tx Signal: %d\n", openr2_chan_get_tx_mf_signal(tmp->r2chan));
13400             ast_cli(fd, "MFC/R2 MF Rx Signal: %d\n", openr2_chan_get_rx_mf_signal(tmp->r2chan));
13401             ast_cli(fd, "MFC/R2 Call Files Directory: %s\n", openr2_context_get_log_directory(r2context, calldir, sizeof(calldir)));
13402          }
13403 #endif
13404 
13405 #ifdef HAVE_PRI
13406          if (tmp->pri) {
13407             ast_cli(fd, "PRI Flags: ");
13408             if (tmp->resetting)
13409                ast_cli(fd, "Resetting ");
13410             if (tmp->call)
13411                ast_cli(fd, "Call ");
13412             if (tmp->bearer)
13413                ast_cli(fd, "Bearer ");
13414             if (tmp->allocated) {
13415                ast_cli(fd, "Allocated ");
13416             }
13417             ast_cli(fd, "\n");
13418             if (tmp->logicalspan) 
13419                ast_cli(fd, "PRI Logical Span: %d\n", tmp->logicalspan);
13420             else
13421                ast_cli(fd, "PRI Logical Span: Implicit\n");
13422          }
13423 #endif
13424          memset(&ci, 0, sizeof(ci));
13425          ps.channo = tmp->channel;
13426          if (tmp->subs[SUB_REAL].dfd > -1) {
13427             memset(&ci, 0, sizeof(ci));
13428             if (!ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GETCONF, &ci)) {
13429                ast_cli(fd, "Actual Confinfo: Num/%d, Mode/0x%04x\n", ci.confno, ci.confmode);
13430             }
13431 #ifdef DAHDI_GETCONFMUTE
13432             if (!ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GETCONFMUTE, &x)) {
13433                ast_cli(fd, "Actual Confmute: %s\n", x ? "Yes" : "No");
13434             }
13435 #endif
13436             memset(&ps, 0, sizeof(ps));
13437             if (ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &ps) < 0) {
13438                ast_log(LOG_WARNING, "Failed to get parameters on channel %d: %s\n", tmp->channel, strerror(errno));
13439             } else {
13440                ast_cli(fd, "Hookstate (FXS only): %s\n", ps.rxisoffhook ? "Offhook" : "Onhook");
13441             }
13442          }
13443          if (ISTRUNK(tmp)) {
13444             ast_cli(fd, "Call Progress: %s\n", tmp->callprogress ? "yes" : "no");  
13445             if (!ast_strlen_zero(progzone))
13446                ast_cli(fd, "Progress Zone: %s\n", progzone);
13447             ast_cli(fd, "Busy Detect: %s\n", tmp->busydetect ? "yes" : "no");  
13448             if(tmp->busydetect) {
13449                ast_cli(fd, "Busy Count: %d\n", tmp->busycount);
13450                if(tmp->busytonelength > 0) {
13451                   ast_cli(fd, "Busy Pattern:\n");
13452                   ast_cli(fd, " -- Tone Length: %6d ms\n", tmp->busytonelength);
13453                   if (tmp->busyquietlength > 0) 
13454                      ast_cli(fd, " -- Quiet Length: %6d ms\n", tmp->busyquietlength);
13455                   else 
13456                      ast_cli(fd, " -- Detect Tone Only\n");
13457                   if(tmp->busyfuzziness > 0)
13458                      ast_cli(fd, "Busy Pattern Fuziness: %d\n", tmp->busyfuzziness);
13459                }
13460             }
13461          }
13462          ast_mutex_unlock(lock);
13463          return RESULT_SUCCESS;
13464       }
13465       tmp = tmp->next;
13466    }
13467    
13468    ast_cli(fd, "Unable to find given channel %d\n", channel);
13469    ast_mutex_unlock(lock);
13470    return RESULT_FAILURE;
13471 }
13472 
13473 static char dahdi_show_cadences_usage[] =
13474 "Usage: dahdi show cadences\n"
13475 "       Shows all cadences currently defined\n";
13476 
13477 static int handle_dahdi_show_cadences(int fd, int argc, char *argv[])
13478 {
13479    int i, j;
13480    for (i = 0; i < num_cadence; i++) {
13481       char output[1024];
13482       char tmp[16], tmp2[64];
13483       snprintf(tmp, sizeof(tmp), "r%d: ", i + 1);
13484       term_color(output, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(output));
13485 
13486       for (j = 0; j < 16; j++) {
13487          if (cadences[i].ringcadence[j] == 0)
13488             break;
13489          snprintf(tmp, sizeof(tmp), "%d", cadences[i].ringcadence[j]);
13490          if (cidrings[i] * 2 - 1 == j)
13491             term_color(tmp2, tmp, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp2) - 1);
13492          else
13493             term_color(tmp2, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(tmp2) - 1);
13494          if (j != 0)
13495             strncat(output, ",", sizeof(output) - strlen(output) - 1);
13496          strncat(output, tmp2, sizeof(output) - strlen(output) - 1);
13497       }
13498       ast_cli(fd,"%s\n",output);
13499    }
13500    return 0;
13501 }
13502 
13503 /* Based on irqmiss.c */
13504 static int dahdi_show_status(int fd, int argc, char *argv[]) {
13505    #define FORMAT "%-40.40s %-10.10s %-10d %-10d %-10d\n"
13506    #define FORMAT2 "%-40.40s %-10.10s %-10.10s %-10.10s %-10.10s\n"
13507 
13508    int span;
13509    int res;
13510    char alarms[50];
13511 
13512    int ctl;
13513    struct dahdi_spaninfo s;
13514 
13515    if ((ctl = open(DAHDI_FILE_CTL, O_RDWR)) < 0) {
13516       ast_log(LOG_WARNING, "Unable to open " DAHDI_FILE_CTL ": %s\n", strerror(errno));
13517       ast_cli(fd, "No " DAHDI_NAME " interface found.\n");
13518       return RESULT_FAILURE;
13519    }
13520    ast_cli(fd, FORMAT2, "Description", "Alarms", "IRQ", "bpviol", "CRC4");
13521 
13522    for (span = 1; span < DAHDI_MAX_SPANS; ++span) {
13523       s.spanno = span;
13524       res = ioctl(ctl, DAHDI_SPANSTAT, &s);
13525       if (res) {
13526          continue;
13527       }
13528       alarms[0] = '\0';
13529       if (s.alarms > 0) {
13530          if (s.alarms & DAHDI_ALARM_BLUE)
13531             strcat(alarms, "BLU/");
13532          if (s.alarms & DAHDI_ALARM_YELLOW)
13533             strcat(alarms, "YEL/");
13534          if (s.alarms & DAHDI_ALARM_RED)
13535             strcat(alarms, "RED/");
13536          if (s.alarms & DAHDI_ALARM_LOOPBACK)
13537             strcat(alarms, "LB/");
13538          if (s.alarms & DAHDI_ALARM_RECOVER)
13539             strcat(alarms, "REC/");
13540          if (s.alarms & DAHDI_ALARM_NOTOPEN)
13541             strcat(alarms, "NOP/");
13542          if (!strlen(alarms))
13543             strcat(alarms, "UUU/");
13544          if (strlen(alarms)) {
13545             /* Strip trailing / */
13546             alarms[strlen(alarms) - 1] = '\0';
13547          }
13548       } else {
13549          if (s.numchans)
13550             strcpy(alarms, "OK");
13551          else
13552             strcpy(alarms, "UNCONFIGURED");
13553       }
13554 
13555       ast_cli(fd, FORMAT, s.desc, alarms, s.irqmisses, s.bpvcount, s.crc4count);
13556    }
13557    close(ctl);
13558 
13559    return RESULT_SUCCESS;
13560 #undef FORMAT
13561 #undef FORMAT2
13562 }
13563 
13564 static char show_channels_usage[] =
13565    "Usage: dahdi show channels\n"
13566    "  Shows a list of available channels\n";
13567 
13568 static char show_channel_usage[] =
13569    "Usage: dahdi show channel <chan num>\n"
13570    "  Detailed information about a given channel\n";
13571 
13572 static char dahdi_show_status_usage[] =
13573    "Usage: dahdi show status\n"
13574    "       Shows a list of DAHDI cards with status\n";
13575 
13576 static char destroy_channel_usage[] =
13577    "Usage: dahdi destroy channel <chan num>\n"
13578    "  DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING.  Immediately removes a given channel, whether it is in use or not\n";
13579 
13580 static char dahdi_restart_usage[] =
13581    "Usage: dahdi restart\n"
13582    "  Restarts the DAHDI channels: destroys them all and then\n"
13583    "  re-reads them from chan_dahdi.conf.\n"
13584    "  Note that this will STOP any running CALL on DAHDI channels.\n"
13585    "";
13586 
13587 static struct ast_cli_entry cli_zap_show_cadences_deprecated = {
13588    { "zap", "show", "cadences", NULL },
13589    handle_dahdi_show_cadences, NULL,
13590    NULL };
13591 
13592 static struct ast_cli_entry cli_zap_show_channels_deprecated = {
13593    { "zap", "show", "channels", NULL },
13594    dahdi_show_channels, NULL,
13595    NULL };
13596 
13597 static struct ast_cli_entry cli_zap_show_channel_deprecated = {
13598    { "zap", "show", "channel", NULL },
13599    dahdi_show_channel, NULL,
13600    NULL };
13601 
13602 static struct ast_cli_entry cli_zap_destroy_channel_deprecated = {
13603    { "zap", "destroy", "channel", NULL },
13604    dahdi_destroy_channel, NULL,
13605    NULL };
13606 
13607 static struct ast_cli_entry cli_zap_restart_deprecated = {
13608    { "zap", "restart", NULL },
13609    dahdi_restart_cmd, NULL,
13610    NULL };
13611 
13612 static struct ast_cli_entry cli_zap_show_status_deprecated = {
13613    { "zap", "show", "status", NULL },
13614    dahdi_show_status, NULL,
13615    NULL };
13616 
13617 static struct ast_cli_entry dahdi_cli[] = {
13618    { { "dahdi", "show", "cadences", NULL },
13619    handle_dahdi_show_cadences, "List cadences",
13620    dahdi_show_cadences_usage, NULL, &cli_zap_show_cadences_deprecated },
13621 
13622    { { "dahdi", "show", "channels", NULL},
13623    dahdi_show_channels, "Show active DAHDI channels",
13624    show_channels_usage, NULL, &cli_zap_show_channels_deprecated },
13625 
13626    { { "dahdi", "show", "channel", NULL},
13627    dahdi_show_channel, "Show information on a channel",
13628    show_channel_usage, NULL, &cli_zap_show_channel_deprecated },
13629 
13630    { { "dahdi", "destroy", "channel", NULL},
13631    dahdi_destroy_channel, "Destroy a channel",
13632    destroy_channel_usage, NULL, &cli_zap_destroy_channel_deprecated },
13633 
13634    { { "dahdi", "restart", NULL},
13635    dahdi_restart_cmd, "Fully restart DAHDI channels",
13636    dahdi_restart_usage, NULL, &cli_zap_restart_deprecated },
13637 
13638    { { "dahdi", "show", "status", NULL},
13639    dahdi_show_status, "Show all DAHDI cards status",
13640    dahdi_show_status_usage, NULL, &cli_zap_show_status_deprecated },
13641 };
13642 
13643 #define TRANSFER  0
13644 #define HANGUP    1
13645 
13646 static int dahdi_fake_event(struct dahdi_pvt *p, int mode)
13647 {
13648    if (p) {
13649       switch (mode) {
13650          case TRANSFER:
13651             p->fake_event = DAHDI_EVENT_WINKFLASH;
13652             break;
13653          case HANGUP:
13654             p->fake_event = DAHDI_EVENT_ONHOOK;
13655             break;
13656          default:
13657             ast_log(LOG_WARNING, "I don't know how to handle transfer event with this: %d on channel %s\n",mode, p->owner->name);   
13658       }
13659    }
13660    return 0;
13661 }
13662 static struct dahdi_pvt *find_channel(int channel)
13663 {
13664    struct dahdi_pvt *p = iflist;
13665    while (p) {
13666       if (p->channel == channel) {
13667          break;
13668       }
13669       p = p->next;
13670    }
13671    return p;
13672 }
13673 
13674 #define local_astman_ack(s, m, msg, zap) do { if (!zap) astman_send_ack(s, m, "DAHDI" msg); else astman_send_ack(s, m, "Zap" msg); } while (0)
13675 #define local_astman_header(m, hdr, zap) astman_get_header(m, (!zap) ? "DAHDI" hdr : "Zap" hdr)
13676 
13677 static int __action_dnd(struct mansession *s, const struct message *m, int zap_mode, int dnd)
13678 {
13679    struct dahdi_pvt *p = NULL;
13680    const char *channel = local_astman_header(m, "Channel", zap_mode);
13681 
13682    if (ast_strlen_zero(channel)) {
13683       astman_send_error(s, m, "No channel specified");
13684       return 0;
13685    }
13686    if (!(p = find_channel(atoi(channel)))) {
13687       astman_send_error(s, m, "No such channel");
13688       return 0;
13689    }
13690    p->dnd = dnd;
13691    local_astman_ack(s, m, "DND", zap_mode);
13692 
13693    return 0;
13694 }
13695 
13696 static int zap_action_dndon(struct mansession *s, const struct message *m)
13697 {
13698    return __action_dnd(s, m, 1, 1);
13699 }
13700 
13701 static int dahdi_action_dndon(struct mansession *s, const struct message *m)
13702 {
13703    return __action_dnd(s, m, 0, 1);
13704 }
13705 
13706 static int zap_action_dndoff(struct mansession *s, const struct message *m)
13707 {
13708    return __action_dnd(s, m, 1, 0);
13709 }
13710 
13711 static int dahdi_action_dndoff(struct mansession *s, const struct message *m)
13712 {
13713    return __action_dnd(s, m, 0, 0);
13714 }
13715 
13716 static int __action_transfer(struct mansession *s, const struct message *m, int zap_mode)
13717 {
13718    struct dahdi_pvt *p = NULL;
13719    const char *channel = local_astman_header(m, "Channel", zap_mode);
13720 
13721    if (ast_strlen_zero(channel)) {
13722       astman_send_error(s, m, "No channel specified");
13723       return 0;
13724    }
13725    if (!(p = find_channel(atoi(channel)))) {
13726       astman_send_error(s, m, "No such channel");
13727       return 0;
13728    }
13729    dahdi_fake_event(p,TRANSFER);
13730    local_astman_ack(s, m, "Transfer", zap_mode);
13731 
13732    return 0;
13733 }
13734 
13735 static int zap_action_transfer(struct mansession *s, const struct message *m)
13736 {
13737    return __action_transfer(s, m, 1);
13738 }
13739 
13740 static int dahdi_action_transfer(struct mansession *s, const struct message *m)
13741 {
13742    return __action_transfer(s, m, 0);
13743 }
13744 
13745 static int __action_transferhangup(struct mansession *s, const struct message *m, int zap_mode)
13746 {
13747    struct dahdi_pvt *p = NULL;
13748    const char *channel = local_astman_header(m, "Channel", zap_mode);
13749 
13750    if (ast_strlen_zero(channel)) {
13751       astman_send_error(s, m, "No channel specified");
13752       return 0;
13753    }
13754    if (!(p = find_channel(atoi(channel)))) {
13755       astman_send_error(s, m, "No such channel");
13756       return 0;
13757    }
13758    dahdi_fake_event(p, HANGUP);
13759    local_astman_ack(s, m, "Hangup", zap_mode);
13760    return 0;
13761 }
13762 
13763 static int zap_action_transferhangup(struct mansession *s, const struct message *m)
13764 {
13765    return __action_transferhangup(s, m, 1);
13766 }
13767 
13768 static int dahdi_action_transferhangup(struct mansession *s, const struct message *m)
13769 {
13770    return __action_transferhangup(s, m, 0);
13771 }
13772 
13773 static int __action_dialoffhook(struct mansession *s, const struct message *m, int zap_mode)
13774 {
13775    struct dahdi_pvt *p = NULL;
13776    const char *channel = local_astman_header(m, "Channel", zap_mode);
13777    const char *number = astman_get_header(m, "Number");
13778    int i;
13779 
13780    if (ast_strlen_zero(channel)) {
13781       astman_send_error(s, m, "No channel specified");
13782       return 0;
13783    }
13784    if (ast_strlen_zero(number)) {
13785       astman_send_error(s, m, "No number specified");
13786       return 0;
13787    }
13788    if (!(p = find_channel(atoi(channel)))) {
13789       astman_send_error(s, m, "No such channel");
13790       return 0;
13791    }
13792    if (!p->owner) {
13793       astman_send_error(s, m, "Channel does not have an owner");
13794       return 0;
13795    }
13796    for (i = 0; i < strlen(number); i++) {
13797       struct ast_frame f = { AST_FRAME_DTMF, number[i] };
13798 
13799       dahdi_queue_frame(p, &f, NULL); 
13800    }
13801    local_astman_ack(s, m, "DialOffHook", zap_mode);
13802 
13803    return 0;
13804 }
13805 
13806 static int zap_action_dialoffhook(struct mansession *s, const struct message *m)
13807 {
13808    return __action_dialoffhook(s, m, 1);
13809 }
13810 
13811 static int dahdi_action_dialoffhook(struct mansession *s, const struct message *m)
13812 {
13813    return __action_dialoffhook(s, m, 0);
13814 }
13815 
13816 static int __action_showchannels(struct mansession *s, const struct message *m, int zap_mode)
13817 {
13818    struct dahdi_pvt *tmp = NULL;
13819    const char *id = astman_get_header(m, "ActionID");
13820    char idText[256] = "";
13821 
13822    local_astman_ack(s, m, " channel status will follow", zap_mode);
13823    if (!ast_strlen_zero(id))
13824       snprintf(idText, sizeof(idText) - 1, "ActionID: %s\r\n", id);
13825 
13826    ast_mutex_lock(&iflock);
13827    
13828    tmp = iflist;
13829    while (tmp) {
13830       if (tmp->channel > 0) {
13831          int alarm = get_alarms(tmp);
13832          astman_append(s,
13833                   "Event: %sShowChannels\r\n"
13834                   "Channel: %d\r\n"
13835                   "Signalling: %s\r\n"
13836                   "Context: %s\r\n"
13837                   "DND: %s\r\n"
13838                   "Alarm: %s\r\n"
13839                   "%s"
13840                   "\r\n",
13841                   dahdi_chan_name,
13842                   tmp->channel, sig2str(tmp->sig), tmp->context, 
13843                   tmp->dnd ? "Enabled" : "Disabled",
13844                   alarm2str(alarm), idText);
13845       } 
13846 
13847       tmp = tmp->next;
13848    }
13849 
13850    ast_mutex_unlock(&iflock);
13851    
13852    astman_append(s, 
13853             "Event: %sShowChannelsComplete\r\n"
13854             "%s"
13855             "\r\n",
13856             dahdi_chan_name,
13857             idText);
13858    return 0;
13859 }
13860 
13861 static int zap_action_showchannels(struct mansession *s, const struct message *m)
13862 {
13863    return __action_showchannels(s, m, 1);
13864 }
13865 
13866 static int dahdi_action_showchannels(struct mansession *s, const struct message *m)
13867 {
13868    return __action_showchannels(s, m, 0);
13869 }
13870 
13871 static int __action_restart(struct mansession *s, const struct message *m, int zap_mode)
13872 {
13873    if (dahdi_restart() != 0) {
13874       if (zap_mode) {
13875          astman_send_error(s, m, "Failed to restart Zap");
13876       } else {
13877          astman_send_error(s, m, "Failed to restart DAHDI");
13878       }
13879       return 1;
13880    }
13881    local_astman_ack(s, m, "Restart: Success", zap_mode);
13882    return 0;
13883 }
13884 
13885 static int zap_action_restart(struct mansession *s, const struct message *m)
13886 {
13887    return __action_restart(s, m, 1);
13888 }
13889 
13890 static int dahdi_action_restart(struct mansession *s, const struct message *m)
13891 {
13892    return __action_restart(s, m, 0);
13893 }
13894 
13895 #define local_astman_unregister(a) do { \
13896                if (*dahdi_chan_mode == CHAN_DAHDI_PLUS_ZAP_MODE) { \
13897                   ast_manager_unregister("DAHDI" a); \
13898                } \
13899                ast_manager_unregister("Zap" a); \
13900                } while (0)
13901 
13902 static int __unload_module(void)
13903 {
13904    struct dahdi_pvt *p;
13905 
13906 #ifdef HAVE_OPENR2
13907    int r;
13908 #endif
13909 
13910 #ifdef HAVE_PRI
13911    int i, j;
13912    for (i = 0; i < NUM_SPANS; i++) {
13913       if (pris[i].master != AST_PTHREADT_NULL) 
13914          pthread_cancel(pris[i].master);
13915    }
13916    ast_cli_unregister_multiple(dahdi_pri_cli, sizeof(dahdi_pri_cli) / sizeof(struct ast_cli_entry));
13917 
13918    if (*dahdi_chan_mode == CHAN_DAHDI_PLUS_ZAP_MODE) {
13919       ast_unregister_application(dahdi_send_keypad_facility_app);
13920    }
13921    ast_unregister_application(zap_send_keypad_facility_app);
13922 #endif
13923 
13924 #ifdef HAVE_OPENR2
13925    for (r = 0; r < NUM_SPANS; r++) {
13926       if (r2links[r].master != AST_PTHREADT_NULL) {
13927          pthread_cancel(r2links[r].master);
13928          pthread_join(r2links[r].master, NULL);
13929       }
13930    }
13931    ast_cli_unregister_multiple(dahdi_mfcr2_cli, sizeof(dahdi_mfcr2_cli) / sizeof(dahdi_mfcr2_cli[0]));
13932    if (*dahdi_chan_mode == CHAN_DAHDI_PLUS_ZAP_MODE) {
13933       ast_unregister_application(dahdi_accept_r2_call_app);
13934    }
13935    ast_unregister_application(zap_accept_r2_call_app);
13936 #endif
13937 
13938    ast_cli_unregister_multiple(dahdi_cli, sizeof(dahdi_cli) / sizeof(struct ast_cli_entry));
13939    local_astman_unregister("DialOffHook");
13940    local_astman_unregister("Hangup");
13941    local_astman_unregister("Transfer");
13942    local_astman_unregister("DNDoff");
13943    local_astman_unregister("DNDon");
13944    local_astman_unregister("ShowChannels");
13945    local_astman_unregister("Restart");
13946    ast_channel_unregister(chan_tech);
13947    ast_mutex_lock(&iflock);
13948    /* Hangup all interfaces if they have an owner */
13949    p = iflist;
13950    while (p) {
13951       if (p->owner)
13952          ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
13953       p = p->next;
13954    }
13955    ast_mutex_unlock(&iflock);
13956    ast_mutex_lock(&monlock);
13957    if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) {
13958       pthread_cancel(monitor_thread);
13959       pthread_kill(monitor_thread, SIGURG);
13960       pthread_join(monitor_thread, NULL);
13961    }
13962    monitor_thread = AST_PTHREADT_STOP;
13963    ast_mutex_unlock(&monlock);
13964 
13965    destroy_all_channels();
13966 #ifdef HAVE_PRI      
13967    for (i = 0; i < NUM_SPANS; i++) {
13968       if (pris[i].master && (pris[i].master != AST_PTHREADT_NULL))
13969          pthread_join(pris[i].master, NULL);
13970       for (j = 0; j < NUM_DCHANS; j++) {
13971          dahdi_close_pri_fd(&(pris[i]), j);
13972       }
13973    }
13974 #endif
13975 
13976 #ifdef HAVE_OPENR2
13977    for (r = 0; r < NUM_SPANS; r++) {
13978       if (r2links[r].protocol_context) {
13979          openr2_context_delete(r2links[r].protocol_context);
13980       }
13981    }
13982 #endif
13983 
13984    ast_cond_destroy(&ss_thread_complete);
13985    return 0;
13986 }
13987 
13988 static int unload_module(void)
13989 {
13990 #ifdef HAVE_PRI      
13991    int y;
13992    for (y = 0; y < NUM_SPANS; y++)
13993       ast_mutex_destroy(&pris[y].lock);
13994 #endif
13995    return __unload_module();
13996 }
13997 
13998 static int build_channels(struct dahdi_chan_conf *conf, int iscrv, const char *value, int reload, int lineno, int *found_pseudo)
13999 {
14000    char *c, *chan;
14001    int x, start, finish;
14002    struct dahdi_pvt *tmp;
14003 #ifdef HAVE_PRI
14004    struct dahdi_pri *pri;
14005    int trunkgroup, y;
14006 #endif
14007    
14008    if ((reload == 0) && (conf->chan.sig < 0)) {
14009       ast_log(LOG_ERROR, "Signalling must be specified before any channels are.\n");
14010       return -1;
14011    }
14012 
14013    c = ast_strdupa(value);
14014 
14015 #ifdef HAVE_PRI
14016    pri = NULL;
14017    if (iscrv) {
14018       if (sscanf(c, "%30d:%n", &trunkgroup, &y) != 1) {
14019          ast_log(LOG_WARNING, "CRV must begin with trunkgroup followed by a colon at line %d\n", lineno);
14020          return -1;
14021       }
14022       if (trunkgroup < 1) {
14023          ast_log(LOG_WARNING, "CRV trunk group must be a positive number at line %d\n", lineno);
14024          return -1;
14025       }
14026       c += y;
14027       for (y = 0; y < NUM_SPANS; y++) {
14028          if (pris[y].trunkgroup == trunkgroup) {
14029             pri = pris + y;
14030             break;
14031          }
14032       }
14033       if (!pri) {
14034          ast_log(LOG_WARNING, "No such trunk group %d at CRV declaration at line %d\n", trunkgroup, lineno);
14035          return -1;
14036       }
14037    }
14038 #endif         
14039 
14040    while ((chan = strsep(&c, ","))) {
14041       if (sscanf(chan, "%30d-%30d", &start, &finish) == 2) {
14042          /* Range */
14043       } else if (sscanf(chan, "%30d", &start)) {
14044          /* Just one */
14045          finish = start;
14046       } else if (!strcasecmp(chan, "pseudo")) {
14047          finish = start = CHAN_PSEUDO;
14048          if (found_pseudo)
14049             *found_pseudo = 1;
14050       } else {
14051          ast_log(LOG_ERROR, "Syntax error parsing '%s' at '%s'\n", value, chan);
14052          return -1;
14053       }
14054       if (finish < start) {
14055          ast_log(LOG_WARNING, "Sillyness: %d < %d\n", start, finish);
14056          x = finish;
14057          finish = start;
14058          start = x;
14059       }
14060 
14061       for (x = start; x <= finish; x++) {
14062 #ifdef HAVE_PRI
14063          tmp = mkintf(x, conf, pri, reload);
14064 #else       
14065          tmp = mkintf(x, conf, NULL, reload);
14066 #endif         
14067 
14068          if (tmp) {
14069             if (option_verbose > 2) {
14070 #ifdef HAVE_PRI
14071                if (pri)
14072                   ast_verbose(VERBOSE_PREFIX_3 "%s CRV %d:%d, %s signalling\n", reload ? "Reconfigured" : "Registered", trunkgroup, x, sig2str(tmp->sig));
14073                else
14074 #endif
14075                   ast_verbose(VERBOSE_PREFIX_3 "%s channel %d, %s signalling\n", reload ? "Reconfigured" : "Registered", x, sig2str(tmp->sig));
14076             }
14077          } else {
14078             ast_log(LOG_ERROR, "Unable to %s channel '%s'\n",
14079                (reload == 1) ? "reconfigure" : "register", value);
14080             return -1;
14081          }
14082       }
14083 
14084 #ifdef HAVE_OPENR2
14085       if (reload != 1 && r2links[mfcr2_cur_context_index].protocol_context) {
14086          mfcr2_cur_context_index++;
14087       }  
14088 #endif
14089 
14090    }
14091 
14092    return 0;
14093 }
14094 
14095 /** The length of the parameters list of 'dahdichan'. 
14096  * \todo Move definition of MAX_CHANLIST_LEN to a proper place. */
14097 #define MAX_CHANLIST_LEN 80
14098 static int process_dahdi(struct dahdi_chan_conf *confp, const char *cat, struct ast_variable *v, int reload, int skipchannels)
14099 {
14100    struct dahdi_pvt *tmp;
14101    int y;
14102    int found_pseudo = 0;
14103         char dahdichan[MAX_CHANLIST_LEN] = {};
14104 
14105    for (; v; v = v->next) {
14106       if (!ast_jb_read_conf(&global_jbconf, v->name, v->value))
14107          continue;
14108 
14109       /* Create the interface list */
14110       if (!strcasecmp(v->name, "channel")
14111 #ifdef HAVE_PRI
14112           || !strcasecmp(v->name, "crv")
14113 #endif         
14114          ) {
14115          int iscrv;
14116          if (skipchannels)
14117             continue;
14118          iscrv = !strcasecmp(v->name, "crv");
14119          if (build_channels(confp, iscrv, v->value, reload, v->lineno, &found_pseudo))
14120                return -1;
14121       } else if (!strcasecmp(v->name, "zapchan") || !strcasecmp(v->name, "dahdichan")) {
14122          ast_copy_string(dahdichan, v->value, sizeof(dahdichan));
14123          if (v->name[0] == 'z' || v->name[0] == 'Z') {
14124             ast_log(LOG_WARNING, "Option zapchan has been deprecated in favor of dahdichan (found in [%s])\n", cat);
14125          }
14126       } else if (!strcasecmp(v->name, "buffers")) {
14127          if (parse_buffers_policy(v->value, &confp->chan.buf_no, &confp->chan.buf_policy)) {
14128             ast_log(LOG_WARNING, "Using default buffer policy.\n");
14129             confp->chan.buf_no = numbufs;
14130             confp->chan.buf_policy = DAHDI_POLICY_IMMEDIATE;
14131          }
14132       } else if (!strcasecmp(v->name, "usedistinctiveringdetection")) {
14133          if (ast_true(v->value))
14134             confp->chan.usedistinctiveringdetection = 1;
14135       } else if (!strcasecmp(v->name, "distinctiveringaftercid")) {
14136          if (ast_true(v->value))
14137             distinctiveringaftercid = 1;
14138       } else if (!strcasecmp(v->name, "dring1context")) {
14139          ast_copy_string(drings.ringContext[0].contextData, v->value, sizeof(drings.ringContext[0].contextData));
14140       } else if (!strcasecmp(v->name, "dring2context")) {
14141          ast_copy_string(drings.ringContext[1].contextData, v->value, sizeof(drings.ringContext[1].contextData));
14142       } else if (!strcasecmp(v->name, "dring3context")) {
14143          ast_copy_string(drings.ringContext[2].contextData, v->value, sizeof(drings.ringContext[2].contextData));
14144       } else if (!strcasecmp(v->name, "dring1")) {
14145          sscanf(v->value, "%30d,%30d,%30d", &drings.ringnum[0].ring[0], &drings.ringnum[0].ring[1], &drings.ringnum[0].ring[2]);
14146       } else if (!strcasecmp(v->name, "dring2")) {
14147          sscanf(v->value, "%30d,%30d,%30d", &drings.ringnum[1].ring[0], &drings.ringnum[1].ring[1], &drings.ringnum[1].ring[2]);
14148       } else if (!strcasecmp(v->name, "dring3")) {
14149          sscanf(v->value, "%30d,%30d,%30d", &drings.ringnum[2].ring[0], &drings.ringnum[2].ring[1], &drings.ringnum[2].ring[2]);
14150       } else if (!strcasecmp(v->name, "usecallerid")) {
14151          confp->chan.use_callerid = ast_true(v->value);
14152       } else if (!strcasecmp(v->name, "cidsignalling")) {
14153          if (!strcasecmp(v->value, "bell"))
14154             confp->chan.cid_signalling = CID_SIG_BELL;
14155          else if (!strcasecmp(v->value, "v23"))
14156             confp->chan.cid_signalling = CID_SIG_V23;
14157          else if (!strcasecmp(v->value, "dtmf"))
14158             confp->chan.cid_signalling = CID_SIG_DTMF;
14159          else if (!strcasecmp(v->value, "smdi"))
14160             confp->chan.cid_signalling = CID_SIG_SMDI;
14161          else if (!strcasecmp(v->value, "v23_jp"))
14162             confp->chan.cid_signalling = CID_SIG_V23_JP;
14163          else if (ast_true(v->value))
14164             confp->chan.cid_signalling = CID_SIG_BELL;
14165       } else if (!strcasecmp(v->name, "cidstart")) {
14166          if (!strcasecmp(v->value, "ring"))
14167             confp->chan.cid_start = CID_START_RING;
14168          else if (!strcasecmp(v->value, "polarity"))
14169             confp->chan.cid_start = CID_START_POLARITY;
14170          else if (!strcasecmp(v->value, "dtmf"))
14171             confp->chan.cid_start = CID_START_DTMF_NOALERT;
14172          else if (ast_true(v->value))
14173             confp->chan.cid_start = CID_START_RING;
14174       } else if (!strcasecmp(v->name, "threewaycalling")) {
14175          confp->chan.threewaycalling = ast_true(v->value);
14176       } else if (!strcasecmp(v->name, "cancallforward")) {
14177          confp->chan.cancallforward = ast_true(v->value);
14178       } else if (!strcasecmp(v->name, "relaxdtmf")) {
14179          if (ast_true(v->value)) 
14180             confp->chan.dtmfrelax = DSP_DIGITMODE_RELAXDTMF;
14181          else
14182             confp->chan.dtmfrelax = 0;
14183       } else if (!strcasecmp(v->name, "mailbox")) {
14184          ast_copy_string(confp->chan.mailbox, v->value, sizeof(confp->chan.mailbox));
14185       } else if (!strcasecmp(v->name, "hasvoicemail")) {
14186          if (ast_true(v->value) && ast_strlen_zero(confp->chan.mailbox)) {
14187             ast_copy_string(confp->chan.mailbox, cat, sizeof(confp->chan.mailbox));
14188          }
14189       } else if (!strcasecmp(v->name, "adsi")) {
14190          confp->chan.adsi = ast_true(v->value);
14191       } else if (!strcasecmp(v->name, "usesmdi")) {
14192          confp->chan.use_smdi = ast_true(v->value);
14193       } else if (!strcasecmp(v->name, "smdiport")) {
14194          ast_copy_string(confp->smdi_port, v->value, sizeof(confp->smdi_port));
14195       } else if (!strcasecmp(v->name, "transfer")) {
14196          confp->chan.transfer = ast_true(v->value);
14197       } else if (!strcasecmp(v->name, "canpark")) {
14198          confp->chan.canpark = ast_true(v->value);
14199       } else if (!strcasecmp(v->name, "echocancelwhenbridged")) {
14200          confp->chan.echocanbridged = ast_true(v->value);
14201       } else if (!strcasecmp(v->name, "busydetect")) {
14202          confp->chan.busydetect = ast_true(v->value);
14203       } else if (!strcasecmp(v->name, "busycount")) {
14204          confp->chan.busycount = atoi(v->value);
14205       } else if (!strcasecmp(v->name, "silencethreshold")) {
14206             confp->chan.silencethreshold = atoi(v->value);
14207       } else if (!strcasecmp(v->name, "busycompare")) {
14208             confp->chan.busycompare = ast_true(v->value);
14209       } else if (!strcasecmp(v->name, "busypattern")) {
14210          int count = sscanf(v->value, "%30d,%30d", &confp->chan.busytonelength, &confp->chan.busyquietlength);
14211          if (count == 1)
14212             confp->chan.busyquietlength = 0;
14213          else if (count < 1)
14214                ast_log(LOG_ERROR, "busypattern= expects busypattern=tonelength[,quietlength]\n");
14215       } else if (!strcasecmp(v->name, "busyfuzziness")) {
14216             confp->chan.busyfuzziness = atoi(v->value);
14217       } else if (!strcasecmp(v->name, "callprogress")) {
14218          if (ast_true(v->value))
14219             confp->chan.callprogress |= 1;
14220          else
14221             confp->chan.callprogress &= ~1;
14222       } else if (!strcasecmp(v->name, "faxdetect")) {
14223          if (!strcasecmp(v->value, "incoming")) {
14224             confp->chan.callprogress |= 4;
14225             confp->chan.callprogress &= ~2;
14226          } else if (!strcasecmp(v->value, "outgoing")) {
14227             confp->chan.callprogress &= ~4;
14228             confp->chan.callprogress |= 2;
14229          } else if (!strcasecmp(v->value, "both") || ast_true(v->value))
14230             confp->chan.callprogress |= 6;
14231          else
14232             confp->chan.callprogress &= ~6;
14233       } else if (!strcasecmp(v->name, "echocancel")) {
14234          if (!ast_strlen_zero(v->value)) {
14235             y = atoi(v->value);
14236          } else
14237             y = 0;
14238          if ((y == 32) || (y == 64) || (y == 128) || (y == 256) || (y == 512) || (y == 1024))
14239             confp->chan.echocancel = y;
14240          else {
14241             confp->chan.echocancel = ast_true(v->value);
14242             if (confp->chan.echocancel)
14243                confp->chan.echocancel=128;
14244          }
14245       } else if (!strcasecmp(v->name, "echotraining")) {
14246          if (sscanf(v->value, "%30d", &y) == 1) {
14247             if ((y < 10) || (y > 4000)) {
14248                ast_log(LOG_WARNING, "Echo training time must be within the range of 10 to 4000 ms at line %d\n", v->lineno);              
14249             } else {
14250                confp->chan.echotraining = y;
14251             }
14252          } else if (ast_true(v->value)) {
14253             confp->chan.echotraining = 400;
14254          } else
14255             confp->chan.echotraining = 0;
14256       } else if (!strcasecmp(v->name, "hidecallerid")) {
14257          confp->chan.hidecallerid = ast_true(v->value);
14258       } else if (!strcasecmp(v->name, "hidecalleridname")) {
14259          confp->chan.hidecalleridname = ast_true(v->value);
14260       } else if (!strcasecmp(v->name, "pulsedial")) {
14261          confp->chan.pulse = ast_true(v->value);
14262       } else if (!strcasecmp(v->name, "callreturn")) {
14263          confp->chan.callreturn = ast_true(v->value);
14264       } else if (!strcasecmp(v->name, "callwaiting")) {
14265          confp->chan.callwaiting = ast_true(v->value);
14266       } else if (!strcasecmp(v->name, "callwaitingcallerid")) {
14267          confp->chan.callwaitingcallerid = ast_true(v->value);
14268       } else if (!strcasecmp(v->name, "context")) {
14269          ast_copy_string(confp->chan.context, v->value, sizeof(confp->chan.context));
14270       } else if (!strcasecmp(v->name, "language")) {
14271          ast_copy_string(confp->chan.language, v->value, sizeof(confp->chan.language));
14272       } else if (!strcasecmp(v->name, "progzone")) {
14273          ast_copy_string(progzone, v->value, sizeof(progzone));
14274       } else if (!strcasecmp(v->name, "mohinterpret") 
14275          ||!strcasecmp(v->name, "musiconhold") || !strcasecmp(v->name, "musicclass")) {
14276          ast_copy_string(confp->chan.mohinterpret, v->value, sizeof(confp->chan.mohinterpret));
14277       } else if (!strcasecmp(v->name, "mohsuggest")) {
14278          ast_copy_string(confp->chan.mohsuggest, v->value, sizeof(confp->chan.mohsuggest));
14279       } else if (!strcasecmp(v->name, "stripmsd")) {
14280          confp->chan.stripmsd = atoi(v->value);
14281       } else if (!strcasecmp(v->name, "jitterbuffers")) {
14282          numbufs = atoi(v->value);
14283       } else if (!strcasecmp(v->name, "group")) {
14284          confp->chan.group = ast_get_group(v->value);
14285       } else if (!strcasecmp(v->name, "callgroup")) {
14286          confp->chan.callgroup = ast_get_group(v->value);
14287       } else if (!strcasecmp(v->name, "pickupgroup")) {
14288          confp->chan.pickupgroup = ast_get_group(v->value);
14289       } else if (!strcasecmp(v->name, "immediate")) {
14290          confp->chan.immediate = ast_true(v->value);
14291       } else if (!strcasecmp(v->name, "transfertobusy")) {
14292          confp->chan.transfertobusy = ast_true(v->value);
14293       } else if (!strcasecmp(v->name, "rxgain")) {
14294          if (sscanf(v->value, "%30f", &confp->chan.rxgain) != 1) {
14295             ast_log(LOG_WARNING, "Invalid rxgain: %s\n", v->value);
14296          }
14297       } else if (!strcasecmp(v->name, "txgain")) {
14298          if (sscanf(v->value, "%30f", &confp->chan.txgain) != 1) {
14299             ast_log(LOG_WARNING, "Invalid txgain: %s\n", v->value);
14300          }
14301       } else if (!strcasecmp(v->name, "tonezone")) {
14302          if (sscanf(v->value, "%30d", &confp->chan.tonezone) != 1) {
14303             ast_log(LOG_WARNING, "Invalid tonezone: %s\n", v->value);
14304          }
14305       } else if (!strcasecmp(v->name, "callerid")) {
14306          if (!strcasecmp(v->value, "asreceived")) {
14307             confp->chan.cid_num[0] = '\0';
14308             confp->chan.cid_name[0] = '\0';
14309          } else {
14310             ast_callerid_split(v->value, confp->chan.cid_name, sizeof(confp->chan.cid_name), confp->chan.cid_num, sizeof(confp->chan.cid_num));
14311          } 
14312       } else if (!strcasecmp(v->name, "fullname")) {
14313          ast_copy_string(confp->chan.cid_name, v->value, sizeof(confp->chan.cid_name));
14314       } else if (!strcasecmp(v->name, "cid_number")) {
14315          ast_copy_string(confp->chan.cid_num, v->value, sizeof(confp->chan.cid_num));
14316       } else if (!strcasecmp(v->name, "useincomingcalleridondahditransfer") || !strcasecmp(v->name, "useincomingcalleridonzaptransfer")) {
14317          confp->chan.dahditrcallerid = ast_true(v->value);
14318          if (strstr(v->name, "zap")) {
14319             ast_log(LOG_WARNING, "Option useincomingcalleridonzaptransfer has been deprecated in favor of useincomingcalleridondahditransfer (in [%s]).\n", cat);
14320          }
14321       } else if (!strcasecmp(v->name, "restrictcid")) {
14322          confp->chan.restrictcid = ast_true(v->value);
14323       } else if (!strcasecmp(v->name, "usecallingpres")) {
14324          confp->chan.use_callingpres = ast_true(v->value);
14325       } else if (!strcasecmp(v->name, "accountcode")) {
14326          ast_copy_string(confp->chan.accountcode, v->value, sizeof(confp->chan.accountcode));
14327       } else if (!strcasecmp(v->name, "amaflags")) {
14328          y = ast_cdr_amaflags2int(v->value);
14329          if (y < 0) 
14330             ast_log(LOG_WARNING, "Invalid AMA flags: %s at line %d\n", v->value, v->lineno);
14331          else
14332             confp->chan.amaflags = y;
14333       } else if (!strcasecmp(v->name, "polarityonanswerdelay")) {
14334          confp->chan.polarityonanswerdelay = atoi(v->value);
14335       } else if (!strcasecmp(v->name, "answeronpolarityswitch")) {
14336          confp->chan.answeronpolarityswitch = ast_true(v->value);
14337       } else if (!strcasecmp(v->name, "hanguponpolarityswitch")) {
14338          confp->chan.hanguponpolarityswitch = ast_true(v->value);
14339       } else if (!strcasecmp(v->name, "sendcalleridafter")) {
14340          confp->chan.sendcalleridafter = atoi(v->value);
14341       } else if (reload != 1) {
14342           if (!strcasecmp(v->name, "signalling") || !strcasecmp(v->name, "signaling")) {
14343             confp->chan.outsigmod = -1;
14344             if (!strcasecmp(v->value, "em")) {
14345                confp->chan.sig = SIG_EM;
14346             } else if (!strcasecmp(v->value, "em_e1")) {
14347                confp->chan.sig = SIG_EM_E1;
14348             } else if (!strcasecmp(v->value, "em_w")) {
14349                confp->chan.sig = SIG_EMWINK;
14350                confp->chan.radio = 0;
14351             } else if (!strcasecmp(v->value, "fxs_ls")) {
14352                confp->chan.sig = SIG_FXSLS;
14353                confp->chan.radio = 0;
14354             } else if (!strcasecmp(v->value, "fxs_gs")) {
14355                confp->chan.sig = SIG_FXSGS;
14356                confp->chan.radio = 0;
14357             } else if (!strcasecmp(v->value, "fxs_ks")) {
14358                confp->chan.sig = SIG_FXSKS;
14359                confp->chan.radio = 0;
14360             } else if (!strcasecmp(v->value, "fxo_ls")) {
14361                confp->chan.sig = SIG_FXOLS;
14362                confp->chan.radio = 0;
14363             } else if (!strcasecmp(v->value, "fxo_gs")) {
14364                confp->chan.sig = SIG_FXOGS;
14365                confp->chan.radio = 0;
14366             } else if (!strcasecmp(v->value, "fxo_ks")) {
14367                confp->chan.sig = SIG_FXOKS;
14368                confp->chan.radio = 0;
14369             } else if (!strcasecmp(v->value, "fxs_rx")) {
14370                confp->chan.sig = SIG_FXSKS;
14371                confp->chan.radio = 1;
14372             } else if (!strcasecmp(v->value, "fxo_rx")) {
14373                confp->chan.sig = SIG_FXOLS;
14374                confp->chan.radio = 1;
14375             } else if (!strcasecmp(v->value, "fxs_tx")) {
14376                confp->chan.sig = SIG_FXSLS;
14377                confp->chan.radio = 1;
14378             } else if (!strcasecmp(v->value, "fxo_tx")) {
14379                confp->chan.sig = SIG_FXOGS;
14380                confp->chan.radio = 1;
14381             } else if (!strcasecmp(v->value, "em_rx")) {
14382                confp->chan.sig = SIG_EM;
14383                confp->chan.radio = 1;
14384             } else if (!strcasecmp(v->value, "em_tx")) {
14385                confp->chan.sig = SIG_EM;
14386                confp->chan.radio = 1;
14387             } else if (!strcasecmp(v->value, "em_rxtx")) {
14388                confp->chan.sig = SIG_EM;
14389                confp->chan.radio = 2;
14390             } else if (!strcasecmp(v->value, "em_txrx")) {
14391                confp->chan.sig = SIG_EM;
14392                confp->chan.radio = 2;
14393             } else if (!strcasecmp(v->value, "sf")) {
14394                confp->chan.sig = SIG_SF;
14395                confp->chan.radio = 0;
14396             } else if (!strcasecmp(v->value, "sf_w")) {
14397                confp->chan.sig = SIG_SFWINK;
14398                confp->chan.radio = 0;
14399             } else if (!strcasecmp(v->value, "sf_featd")) {
14400                confp->chan.sig = SIG_FEATD;
14401                confp->chan.radio = 0;
14402             } else if (!strcasecmp(v->value, "sf_featdmf")) {
14403                confp->chan.sig = SIG_FEATDMF;
14404                confp->chan.radio = 0;
14405             } else if (!strcasecmp(v->value, "sf_featb")) {
14406                confp->chan.sig = SIG_SF_FEATB;
14407                confp->chan.radio = 0;
14408             } else if (!strcasecmp(v->value, "sf")) {
14409                confp->chan.sig = SIG_SF;
14410                confp->chan.radio = 0;
14411             } else if (!strcasecmp(v->value, "sf_rx")) {
14412                confp->chan.sig = SIG_SF;
14413                confp->chan.radio = 1;
14414             } else if (!strcasecmp(v->value, "sf_tx")) {
14415                confp->chan.sig = SIG_SF;
14416                confp->chan.radio = 1;
14417             } else if (!strcasecmp(v->value, "sf_rxtx")) {
14418                confp->chan.sig = SIG_SF;
14419                confp->chan.radio = 2;
14420             } else if (!strcasecmp(v->value, "sf_txrx")) {
14421                confp->chan.sig = SIG_SF;
14422                confp->chan.radio = 2;
14423             } else if (!strcasecmp(v->value, "featd")) {
14424                confp->chan.sig = SIG_FEATD;
14425                confp->chan.radio = 0;
14426             } else if (!strcasecmp(v->value, "featdmf")) {
14427                confp->chan.sig = SIG_FEATDMF;
14428                confp->chan.radio = 0;
14429             } else if (!strcasecmp(v->value, "featdmf_ta")) {
14430                confp->chan.sig = SIG_FEATDMF_TA;
14431                confp->chan.radio = 0;
14432             } else if (!strcasecmp(v->value, "e911")) {
14433                confp->chan.sig = SIG_E911;
14434                confp->chan.radio = 0;
14435             } else if (!strcasecmp(v->value, "fgccama")) {
14436                confp->chan.sig = SIG_FGC_CAMA;
14437                confp->chan.radio = 0;
14438             } else if (!strcasecmp(v->value, "fgccamamf")) {
14439                confp->chan.sig = SIG_FGC_CAMAMF;
14440                confp->chan.radio = 0;
14441             } else if (!strcasecmp(v->value, "featb")) {
14442                confp->chan.sig = SIG_FEATB;
14443                confp->chan.radio = 0;
14444 #ifdef HAVE_OPENR2
14445             } else if (!strcasecmp(v->value, "mfcr2")) {
14446                confp->chan.sig = SIG_MFCR2;
14447 #endif
14448 
14449 #ifdef HAVE_PRI
14450             } else if (!strcasecmp(v->value, "pri_net")) {
14451                confp->chan.radio = 0;
14452                confp->chan.sig = SIG_PRI;
14453                confp->pri.nodetype = PRI_NETWORK;
14454             } else if (!strcasecmp(v->value, "pri_cpe")) {
14455                confp->chan.sig = SIG_PRI;
14456                confp->chan.radio = 0;
14457                confp->pri.nodetype = PRI_CPE;
14458             } else if (!strcasecmp(v->value, "gr303fxoks_net")) {
14459                confp->chan.sig = SIG_GR303FXOKS;
14460                confp->chan.radio = 0;
14461                confp->pri.nodetype = PRI_NETWORK;
14462             } else if (!strcasecmp(v->value, "gr303fxsks_cpe")) {
14463                confp->chan.sig = SIG_GR303FXSKS;
14464                confp->chan.radio = 0;
14465                confp->pri.nodetype = PRI_CPE;
14466 #endif
14467             } else {
14468                ast_log(LOG_ERROR, "Unknown signalling method '%s'\n", v->value);
14469             }
14470           } else if (!strcasecmp(v->name, "outsignalling")) {
14471             if (!strcasecmp(v->value, "em")) {
14472                confp->chan.outsigmod = SIG_EM;
14473             } else if (!strcasecmp(v->value, "em_e1")) {
14474                confp->chan.outsigmod = SIG_EM_E1;
14475             } else if (!strcasecmp(v->value, "em_w")) {
14476                confp->chan.outsigmod = SIG_EMWINK;
14477             } else if (!strcasecmp(v->value, "sf")) {
14478                confp->chan.outsigmod = SIG_SF;
14479             } else if (!strcasecmp(v->value, "sf_w")) {
14480                confp->chan.outsigmod = SIG_SFWINK;
14481             } else if (!strcasecmp(v->value, "sf_featd")) {
14482                confp->chan.outsigmod = SIG_FEATD;
14483             } else if (!strcasecmp(v->value, "sf_featdmf")) {
14484                confp->chan.outsigmod = SIG_FEATDMF;
14485             } else if (!strcasecmp(v->value, "sf_featb")) {
14486                confp->chan.outsigmod = SIG_SF_FEATB;
14487             } else if (!strcasecmp(v->value, "sf")) {
14488                confp->chan.outsigmod = SIG_SF;
14489             } else if (!strcasecmp(v->value, "featd")) {
14490                confp->chan.outsigmod = SIG_FEATD;
14491             } else if (!strcasecmp(v->value, "featdmf")) {
14492                confp->chan.outsigmod = SIG_FEATDMF;
14493             } else if (!strcasecmp(v->value, "featdmf_ta")) {
14494                confp->chan.outsigmod = SIG_FEATDMF_TA;
14495             } else if (!strcasecmp(v->value, "e911")) {
14496                confp->chan.outsigmod = SIG_E911;
14497             } else if (!strcasecmp(v->value, "fgccama")) {
14498                confp->chan.outsigmod = SIG_FGC_CAMA;
14499             } else if (!strcasecmp(v->value, "fgccamamf")) {
14500                confp->chan.outsigmod = SIG_FGC_CAMAMF;
14501             } else if (!strcasecmp(v->value, "featb")) {
14502                confp->chan.outsigmod = SIG_FEATB;
14503             } else {
14504                ast_log(LOG_ERROR, "Unknown signalling method '%s'\n", v->value);
14505             }
14506 #ifdef HAVE_PRI
14507          } else if (!strcasecmp(v->name, "pridialplan")) {
14508             if (!strcasecmp(v->value, "national")) {
14509                confp->pri.dialplan = PRI_NATIONAL_ISDN + 1;
14510             } else if (!strcasecmp(v->value, "unknown")) {
14511                confp->pri.dialplan = PRI_UNKNOWN + 1;
14512             } else if (!strcasecmp(v->value, "private")) {
14513                confp->pri.dialplan = PRI_PRIVATE + 1;
14514             } else if (!strcasecmp(v->value, "international")) {
14515                confp->pri.dialplan = PRI_INTERNATIONAL_ISDN + 1;
14516             } else if (!strcasecmp(v->value, "local")) {
14517                confp->pri.dialplan = PRI_LOCAL_ISDN + 1;
14518             } else if (!strcasecmp(v->value, "dynamic")) {
14519                confp->pri.dialplan = -1;
14520             } else {
14521                ast_log(LOG_WARNING, "Unknown PRI dialplan '%s' at line %d.\n", v->value, v->lineno);
14522             }
14523          } else if (!strcasecmp(v->name, "prilocaldialplan")) {
14524             if (!strcasecmp(v->value, "national")) {
14525                confp->pri.localdialplan = PRI_NATIONAL_ISDN + 1;
14526             } else if (!strcasecmp(v->value, "unknown")) {
14527                confp->pri.localdialplan = PRI_UNKNOWN + 1;
14528             } else if (!strcasecmp(v->value, "private")) {
14529                confp->pri.localdialplan = PRI_PRIVATE + 1;
14530             } else if (!strcasecmp(v->value, "international")) {
14531                confp->pri.localdialplan = PRI_INTERNATIONAL_ISDN + 1;
14532             } else if (!strcasecmp(v->value, "local")) {
14533                confp->pri.localdialplan = PRI_LOCAL_ISDN + 1;
14534             } else if (!strcasecmp(v->value, "dynamic")) {
14535                confp->pri.localdialplan = -1;
14536             } else {
14537                ast_log(LOG_WARNING, "Unknown PRI dialplan '%s' at line %d.\n", v->value, v->lineno);
14538             }
14539          } else if (!strcasecmp(v->name, "switchtype")) {
14540             if (!strcasecmp(v->value, "national")) 
14541                confp->pri.switchtype = PRI_SWITCH_NI2;
14542             else if (!strcasecmp(v->value, "ni1"))
14543                confp->pri.switchtype = PRI_SWITCH_NI1;
14544             else if (!strcasecmp(v->value, "dms100"))
14545                confp->pri.switchtype = PRI_SWITCH_DMS100;
14546             else if (!strcasecmp(v->value, "4ess"))
14547                confp->pri.switchtype = PRI_SWITCH_ATT4ESS;
14548             else if (!strcasecmp(v->value, "5ess"))
14549                confp->pri.switchtype = PRI_SWITCH_LUCENT5E;
14550             else if (!strcasecmp(v->value, "euroisdn"))
14551                confp->pri.switchtype = PRI_SWITCH_EUROISDN_E1;
14552             else if (!strcasecmp(v->value, "qsig"))
14553                confp->pri.switchtype = PRI_SWITCH_QSIG;
14554             else {
14555                ast_log(LOG_ERROR, "Unknown switchtype '%s'\n", v->value);
14556                return -1;
14557             }
14558          } else if (!strcasecmp(v->name, "nsf")) {
14559             if (!strcasecmp(v->value, "sdn"))
14560                confp->pri.nsf = PRI_NSF_SDN;
14561             else if (!strcasecmp(v->value, "megacom"))
14562                confp->pri.nsf = PRI_NSF_MEGACOM;
14563             else if (!strcasecmp(v->value, "tollfreemegacom"))
14564                confp->pri.nsf = PRI_NSF_TOLL_FREE_MEGACOM;           
14565             else if (!strcasecmp(v->value, "accunet"))
14566                confp->pri.nsf = PRI_NSF_ACCUNET;
14567             else if (!strcasecmp(v->value, "none"))
14568                confp->pri.nsf = PRI_NSF_NONE;
14569             else {
14570                ast_log(LOG_WARNING, "Unknown network-specific facility '%s'\n", v->value);
14571                confp->pri.nsf = PRI_NSF_NONE;
14572             }
14573          } else if (!strcasecmp(v->name, "priindication")) {
14574             if (!strcasecmp(v->value, "outofband"))
14575                confp->chan.priindication_oob = 1;
14576             else if (!strcasecmp(v->value, "inband"))
14577                confp->chan.priindication_oob = 0;
14578             else
14579                ast_log(LOG_WARNING, "'%s' is not a valid pri indication value, should be 'inband' or 'outofband' at line %d\n",
14580                   v->value, v->lineno);
14581          } else if (!strcasecmp(v->name, "priexclusive")) {
14582             confp->chan.priexclusive = ast_true(v->value);
14583          } else if (!strcasecmp(v->name, "internationalprefix")) {
14584             ast_copy_string(confp->pri.internationalprefix, v->value, sizeof(confp->pri.internationalprefix));
14585          } else if (!strcasecmp(v->name, "nationalprefix")) {
14586             ast_copy_string(confp->pri.nationalprefix, v->value, sizeof(confp->pri.nationalprefix));
14587          } else if (!strcasecmp(v->name, "localprefix")) {
14588             ast_copy_string(confp->pri.localprefix, v->value, sizeof(confp->pri.localprefix));
14589          } else if (!strcasecmp(v->name, "privateprefix")) {
14590             ast_copy_string(confp->pri.privateprefix, v->value, sizeof(confp->pri.privateprefix));
14591          } else if (!strcasecmp(v->name, "unknownprefix")) {
14592             ast_copy_string(confp->pri.unknownprefix, v->value, sizeof(confp->pri.unknownprefix));
14593          } else if (!strcasecmp(v->name, "resetinterval")) {
14594             if (!strcasecmp(v->value, "never"))
14595                confp->pri.resetinterval = -1;
14596             else if (atoi(v->value) >= 60)
14597                confp->pri.resetinterval = atoi(v->value);
14598             else
14599                ast_log(LOG_WARNING, "'%s' is not a valid reset interval, should be >= 60 seconds or 'never' at line %d\n",
14600                   v->value, v->lineno);
14601          } else if (!strcasecmp(v->name, "minunused")) {
14602             confp->pri.minunused = atoi(v->value);
14603          } else if (!strcasecmp(v->name, "minidle")) {
14604             confp->pri.minidle = atoi(v->value); 
14605          } else if (!strcasecmp(v->name, "idleext")) {
14606             ast_copy_string(confp->pri.idleext, v->value, sizeof(confp->pri.idleext));
14607          } else if (!strcasecmp(v->name, "idledial")) {
14608             ast_copy_string(confp->pri.idledial, v->value, sizeof(confp->pri.idledial));
14609          } else if (!strcasecmp(v->name, "overlapdial")) {
14610             if (ast_true(v->value)) {
14611                confp->pri.overlapdial = DAHDI_OVERLAPDIAL_BOTH;
14612             } else if (!strcasecmp(v->value, "incoming")) {
14613                confp->pri.overlapdial = DAHDI_OVERLAPDIAL_INCOMING;
14614             } else if (!strcasecmp(v->value, "outgoing")) {
14615                confp->pri.overlapdial = DAHDI_OVERLAPDIAL_OUTGOING;
14616             } else if (!strcasecmp(v->value, "both") || ast_true(v->value)) {
14617                confp->pri.overlapdial = DAHDI_OVERLAPDIAL_BOTH;
14618             } else {
14619                confp->pri.overlapdial = DAHDI_OVERLAPDIAL_NONE;
14620             }
14621 #ifdef HAVE_PRI_INBANDDISCONNECT
14622          } else if (!strcasecmp(v->name, "inbanddisconnect")) {
14623             confp->pri.inbanddisconnect = ast_true(v->value);
14624 #endif
14625          } else if (!strcasecmp(v->name, "pritimer")) {
14626 #ifdef PRI_GETSET_TIMERS
14627             char tmp[20];
14628             char *timerc;
14629             char *c;
14630             int timer;
14631             int timeridx;
14632 
14633             ast_copy_string(tmp, v->value, sizeof(tmp));
14634             c = tmp;
14635             timerc = strsep(&c, ",");
14636             if (!ast_strlen_zero(timerc) && !ast_strlen_zero(c)) {
14637                timeridx = pri_timer2idx(timerc);
14638                timer = atoi(c);
14639                if (timeridx < 0 || PRI_MAX_TIMERS <= timeridx) {
14640                   ast_log(LOG_WARNING,
14641                      "'%s' is not a valid ISDN timer at line %d.\n", timerc,
14642                      v->lineno);
14643                } else if (!timer) {
14644                   ast_log(LOG_WARNING,
14645                      "'%s' is not a valid value for ISDN timer '%s' at line %d.\n",
14646                      c, timerc, v->lineno);
14647                } else {
14648                   pritimers[timeridx] = timer;
14649                }
14650             } else {
14651                ast_log(LOG_WARNING,
14652                   "'%s' is not a valid ISDN timer configuration string at line %d.\n",
14653                   v->value, v->lineno);
14654             }
14655 #endif /* PRI_GETSET_TIMERS */
14656          } else if (!strcasecmp(v->name, "facilityenable")) {
14657             confp->pri.facilityenable = ast_true(v->value);
14658 #endif /* HAVE_PRI */
14659 
14660 #ifdef HAVE_OPENR2
14661          } else if (!strcasecmp(v->name, "mfcr2_advanced_protocol_file")) {
14662             ast_copy_string(mfcr2_cur_r2proto_file, v->value, sizeof(mfcr2_cur_r2proto_file));
14663             ast_log(LOG_WARNING, "MFC/R2 Protocol file '%s' will be used, you only should use this if you *REALLY  KNOW WHAT YOU ARE DOING*.\n", mfcr2_cur_r2proto_file);
14664          } else if (!strcasecmp(v->name, "mfcr2_logdir")) {
14665             ast_copy_string(mfcr2_cur_logdir, v->value, sizeof(mfcr2_cur_logdir));
14666          } else if (!strcasecmp(v->name, "mfcr2_variant")) {
14667             mfcr2_cur_variant = openr2_proto_get_variant(v->value);
14668             if (OR2_VAR_UNKNOWN == mfcr2_cur_variant) {
14669                ast_log(LOG_WARNING, "Unknown MFC/R2 variant '%s' at line %d.\n", v->value, v->lineno);
14670             }
14671          } else if (!strcasecmp(v->name, "mfcr2_mfback_timeout")) {
14672             mfcr2_cur_mfback_timeout = atoi(v->value);
14673             if (!mfcr2_cur_mfback_timeout) {
14674                ast_log(LOG_WARNING, "MF timeout of 0? hum, I will protect you from your ignorance. Setting default.\n");
14675                mfcr2_cur_mfback_timeout = -1;
14676             } else if (mfcr2_cur_mfback_timeout > 0 && mfcr2_cur_mfback_timeout < 500) {
14677                ast_log(LOG_WARNING, "MF timeout less than 500ms is not recommended, you have been warned!\n");
14678             }
14679          } else if (!strcasecmp(v->name, "mfcr2_metering_pulse_timeout")) {
14680             mfcr2_cur_metering_pulse_timeout = atoi(v->value);
14681             if (mfcr2_cur_metering_pulse_timeout > 500) {
14682                ast_log(LOG_WARNING, "mfcr2_metering_pulse_timeout greater than 500ms is not recommended, you have been warned!\n");
14683             }
14684 #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 2
14685          } else if (!strcasecmp(v->name, "mfcr2_dtmf_detection")) {
14686             mfcr2_cur_dtmf_detection = ast_true(v->value) ? 1 : 0;
14687          } else if (!strcasecmp(v->name, "mfcr2_dtmf_dialing")) {
14688             mfcr2_cur_dtmf_dialing = ast_true(v->value) ? 1 : 0;
14689          } else if (!strcasecmp(v->name, "mfcr2_dtmf_time_on")) {
14690             mfcr2_cur_dtmf_time_on = atoi(v->value);
14691          } else if (!strcasecmp(v->name, "mfcr2_dtmf_time_off")) {
14692             mfcr2_cur_dtmf_time_off = atoi(v->value);
14693 #endif
14694          } else if (!strcasecmp(v->name, "mfcr2_get_ani_first")) {
14695             mfcr2_cur_get_ani_first = ast_true(v->value) ? 1 : 0;
14696          } else if (!strcasecmp(v->name, "mfcr2_skip_category")) {
14697             mfcr2_cur_skip_category = ast_true(v->value) ? 1 : 0;
14698          } else if (!strcasecmp(v->name, "mfcr2_double_answer")) {
14699             mfcr2_cur_double_answer = ast_true(v->value) ? 1 : 0;
14700          } else if (!strcasecmp(v->name, "mfcr2_accept_on_offer")) {
14701             mfcr2_cur_accept_on_offer = ast_true(v->value) ? 1 : 0;
14702          } else if (!strcasecmp(v->name, "mfcr2_charge_calls")) {
14703             mfcr2_cur_charge_calls = ast_true(v->value) ? 1 : 0;
14704          } else if (!strcasecmp(v->name, "mfcr2_allow_collect_calls")) {
14705             mfcr2_cur_allow_collect_calls = ast_true(v->value) ? 1 : 0;
14706          } else if (!strcasecmp(v->name, "mfcr2_forced_release")) {
14707             mfcr2_cur_forced_release= ast_true(v->value) ? 1 : 0;
14708          } else if (!strcasecmp(v->name, "mfcr2_immediate_accept")) {
14709             mfcr2_cur_immediate_accept = ast_true(v->value) ? 1 : 0;
14710          } else if (!strcasecmp(v->name, "mfcr2_call_files")) {
14711             mfcr2_cur_call_files = ast_true(v->value) ? 1 : 0;
14712          } else if (!strcasecmp(v->name, "mfcr2_max_ani")) {
14713             mfcr2_cur_max_ani = atoi(v->value);
14714             if (mfcr2_cur_max_ani >= AST_MAX_EXTENSION) {
14715                mfcr2_cur_max_ani = AST_MAX_EXTENSION - 1;
14716             }
14717          } else if (!strcasecmp(v->name, "mfcr2_max_dnis")) {
14718             mfcr2_cur_max_dnis = atoi(v->value);
14719             if (mfcr2_cur_max_dnis >= AST_MAX_EXTENSION) {
14720                mfcr2_cur_max_dnis = AST_MAX_EXTENSION - 1;
14721             }
14722          } else if (!strcasecmp(v->name, "mfcr2_category")) {
14723             mfcr2_cur_category = openr2_proto_get_category(v->value);
14724             if (OR2_CALLING_PARTY_CATEGORY_UNKNOWN == mfcr2_cur_category) {
14725                mfcr2_cur_category = OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER;
14726                ast_log(LOG_WARNING, "Invalid MFC/R2 caller category '%s' at line %d. Using national subscriber as default.\n", 
14727                      v->value, v->lineno);
14728             }
14729          } else if (!strcasecmp(v->name, "mfcr2_logging")) {
14730             openr2_log_level_t tmplevel;
14731             char *toklevel = NULL;
14732             char *saveptr = NULL;
14733             char *logval = ast_strdupa(v->value);
14734             toklevel = strtok_r(logval, ",", &saveptr);
14735             if (-1 == (tmplevel = openr2_log_get_level(toklevel))) {
14736                ast_log(LOG_WARNING, "Invalid MFC/R2 logging level '%s' at line %d.\n", v->value, v->lineno);
14737             } else if (OR2_LOG_NOTHING == tmplevel) {
14738                mfcr2_cur_loglevel = tmplevel;
14739             } else {
14740                mfcr2_cur_loglevel |= tmplevel;
14741                while ((toklevel = strtok_r(NULL, ",", &saveptr))) {
14742                   if (-1 == (tmplevel = openr2_log_get_level(toklevel))) {
14743                      ast_log(LOG_WARNING, "Ignoring invalid logging level: '%s' at line %d.\n", toklevel, v->lineno);
14744                      continue;
14745                   }
14746                   mfcr2_cur_loglevel |= tmplevel;
14747                }
14748             }
14749 #endif /* HAVE_OPENR2 */
14750 
14751          } else if (!strcasecmp(v->name, "cadence")) {
14752             /* setup to scan our argument */
14753             int element_count, c[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
14754             int i;
14755             struct dahdi_ring_cadence new_cadence;
14756             int cid_location = -1;
14757             int firstcadencepos = 0;
14758             char original_args[80];
14759             int cadence_is_ok = 1;
14760 
14761             ast_copy_string(original_args, v->value, sizeof(original_args));
14762             /* 16 cadences allowed (8 pairs) */
14763             element_count = sscanf(v->value, "%30d,%30d,%30d,%30d,%30d,%30d,%30d,%30d,%30d,%30d,%30d,%30d,%30d,%30d,%30d,%30d", &c[0], &c[1], &c[2], &c[3], &c[4], &c[5], &c[6], &c[7], &c[8], &c[9], &c[10], &c[11], &c[12], &c[13], &c[14], &c[15]);
14764    
14765             /* Cadence must be even (on/off) */
14766             if (element_count % 2 == 1) {
14767                ast_log(LOG_ERROR, "Must be a silence duration for each ring duration: %s\n",original_args);
14768                cadence_is_ok = 0;
14769             }
14770    
14771             /* Ring cadences cannot be negative */
14772             for (i = 0; i < element_count; i++) {
14773                if (c[i] == 0) {
14774                   ast_log(LOG_ERROR, "Ring or silence duration cannot be zero: %s\n", original_args);
14775                   cadence_is_ok = 0;
14776                   break;
14777                } else if (c[i] < 0) {
14778                   if (i % 2 == 1) {
14779                      /* Silence duration, negative possibly okay */
14780                      if (cid_location == -1) {
14781                         cid_location = i;
14782                         c[i] *= -1;
14783                      } else {
14784                         ast_log(LOG_ERROR, "CID location specified twice: %s\n",original_args);
14785                         cadence_is_ok = 0;
14786                         break;
14787                      }
14788                   } else {
14789                      if (firstcadencepos == 0) {
14790                         firstcadencepos = i; /* only recorded to avoid duplicate specification */
14791                                  /* duration will be passed negative to the DAHDI driver */
14792                      } else {
14793                          ast_log(LOG_ERROR, "First cadence position specified twice: %s\n",original_args);
14794                         cadence_is_ok = 0;
14795                         break;
14796                      }
14797                   }
14798                }
14799             }
14800    
14801             /* Substitute our scanned cadence */
14802             for (i = 0; i < 16; i++) {
14803                new_cadence.ringcadence[i] = c[i];
14804             }
14805    
14806             if (cadence_is_ok) {
14807                /* ---we scanned it without getting annoyed; now some sanity checks--- */
14808                if (element_count < 2) {
14809                   ast_log(LOG_ERROR, "Minimum cadence is ring,pause: %s\n", original_args);
14810                } else {
14811                   if (cid_location == -1) {
14812                      /* user didn't say; default to first pause */
14813                      cid_location = 1;
14814                   } else {
14815                      /* convert element_index to cidrings value */
14816                      cid_location = (cid_location + 1) / 2;
14817                   }
14818                   /* ---we like their cadence; try to install it--- */
14819                   if (!user_has_defined_cadences++)
14820                      /* this is the first user-defined cadence; clear the default user cadences */
14821                      num_cadence = 0;
14822                   if ((num_cadence+1) >= NUM_CADENCE_MAX)
14823                      ast_log(LOG_ERROR, "Already %d cadences; can't add another: %s\n", NUM_CADENCE_MAX, original_args);
14824                   else {
14825                      cadences[num_cadence] = new_cadence;
14826                      cidrings[num_cadence++] = cid_location;
14827                      if (option_verbose > 2)
14828                         ast_verbose(VERBOSE_PREFIX_3 "cadence 'r%d' added: %s\n",num_cadence,original_args);
14829                   }
14830                }
14831             }
14832          } else if (!strcasecmp(v->name, "ringtimeout")) {
14833             ringt_base = (atoi(v->value) * 8) / READ_SIZE;
14834          } else if (!strcasecmp(v->name, "prewink")) {
14835             confp->timing.prewinktime = atoi(v->value);
14836          } else if (!strcasecmp(v->name, "preflash")) {
14837             confp->timing.preflashtime = atoi(v->value);
14838          } else if (!strcasecmp(v->name, "wink")) {
14839             confp->timing.winktime = atoi(v->value);
14840          } else if (!strcasecmp(v->name, "flash")) {
14841             confp->timing.flashtime = atoi(v->value);
14842          } else if (!strcasecmp(v->name, "start")) {
14843             confp->timing.starttime = atoi(v->value);
14844          } else if (!strcasecmp(v->name, "rxwink")) {
14845             confp->timing.rxwinktime = atoi(v->value);
14846          } else if (!strcasecmp(v->name, "rxflash")) {
14847             confp->timing.rxflashtime = atoi(v->value);
14848          } else if (!strcasecmp(v->name, "debounce")) {
14849             confp->timing.debouncetime = atoi(v->value);
14850          } else if (!strcasecmp(v->name, "toneduration")) {
14851             int toneduration;
14852             int ctlfd;
14853             int res;
14854             struct dahdi_dialparams dps;
14855 
14856             ctlfd = open(DAHDI_FILE_CTL, O_RDWR);
14857 
14858             if (ctlfd == -1) {
14859                ast_log(LOG_ERROR, "Unable to open " DAHDI_FILE_CTL " to set toneduration\n");
14860                return -1;
14861             }
14862 
14863             toneduration = atoi(v->value);
14864             if (toneduration > -1) {
14865                memset(&dps, 0, sizeof(dps));
14866 
14867                dps.dtmf_tonelen = dps.mfv1_tonelen = toneduration;
14868                res = ioctl(ctlfd, DAHDI_SET_DIALPARAMS, &dps);
14869                if (res < 0) {
14870                   ast_log(LOG_ERROR, "Invalid tone duration: %d ms: %s\n", toneduration, strerror(errno));
14871                   close(ctlfd);
14872                   return -1;
14873                }
14874             }
14875             close(ctlfd);
14876          } else if (!strcasecmp(v->name, "defaultcic")) {
14877             ast_copy_string(defaultcic, v->value, sizeof(defaultcic));
14878          } else if (!strcasecmp(v->name, "defaultozz")) {
14879             ast_copy_string(defaultozz, v->value, sizeof(defaultozz));
14880          } else if (!strcasecmp(v->name, "dtmfcidlevel")) {
14881             dtmfcid_level = atoi(v->value);
14882          } 
14883       } else if (!skipchannels)
14884          ast_log(LOG_WARNING, "Ignoring any changes to '%s' (on reload)\n", v->name);
14885    }
14886    if (dahdichan[0]) { 
14887       /* The user has set 'dahdichan' */
14888       /*< \todo pass proper line number instead of 0 */
14889       if (build_channels(confp, 0, dahdichan, reload, 0, &found_pseudo)) {
14890          return -1;
14891       }
14892    }
14893    /*< \todo why check for the pseudo in the per-channel section.
14894     * Any actual use for manual setup of the pseudo channel? */
14895    if (!found_pseudo && reload != 1) {
14896       /* use the default configuration for a channel, so
14897          that any settings from real configured channels
14898          don't "leak" into the pseudo channel config
14899       */
14900       struct dahdi_chan_conf conf = dahdi_chan_conf_default();
14901 
14902       tmp = mkintf(CHAN_PSEUDO, &conf, NULL, reload);
14903 
14904       if (tmp) {
14905          if (option_verbose > 2)
14906             ast_verbose(VERBOSE_PREFIX_3 "Automatically generated pseudo channel\n");
14907       } else {
14908          ast_log(LOG_WARNING, "Unable to register pseudo channel!\n");
14909       }
14910    }
14911    return 0;
14912 }
14913       
14914 static int setup_dahdi(int reload)
14915 {
14916    struct ast_config *cfg;
14917    struct ast_variable *v;
14918    struct dahdi_chan_conf conf = dahdi_chan_conf_default();
14919    int res;
14920 
14921 #ifdef HAVE_PRI
14922    char *c;
14923    int spanno;
14924    int i, x;
14925    int logicalspan;
14926    int trunkgroup;
14927    int dchannels[NUM_DCHANS];
14928 #endif
14929 
14930 #ifdef HAVE_ZAPTEL
14931    int load_from_zapata_conf = 1;
14932 #else
14933    int load_from_zapata_conf = (*dahdi_chan_mode == CHAN_ZAP_MODE);
14934 #endif
14935 
14936    if (load_from_zapata_conf) {
14937       if (!(cfg = ast_config_load("zapata.conf"))) {
14938          ast_log(LOG_ERROR, "Unable to load zapata.conf\n");
14939          return 0;
14940       }
14941    } else {
14942       if (!(cfg = ast_config_load("chan_dahdi.conf"))) {
14943          ast_log(LOG_ERROR, "Unable to load chan_dahdi.conf\n");
14944          return 0;
14945       }
14946    }
14947 
14948    /* It's a little silly to lock it, but we mind as well just to be sure */
14949    ast_mutex_lock(&iflock);
14950 #ifdef HAVE_PRI
14951    if (reload != 1) {
14952       /* Process trunkgroups first */
14953       v = ast_variable_browse(cfg, "trunkgroups");
14954       while (v) {
14955          if (!strcasecmp(v->name, "trunkgroup")) {
14956             trunkgroup = atoi(v->value);
14957             if (trunkgroup > 0) {
14958                if ((c = strchr(v->value, ','))) {
14959                   i = 0;
14960                   memset(dchannels, 0, sizeof(dchannels));
14961                   while (c && (i < NUM_DCHANS)) {
14962                      dchannels[i] = atoi(c + 1);
14963                      if (dchannels[i] < 0) {
14964                         ast_log(LOG_WARNING, "D-channel for trunk group %d must be a postiive number at line %d of chan_dahdi.conf\n", trunkgroup, v->lineno);
14965                      } else
14966                         i++;
14967                      c = strchr(c + 1, ',');
14968                   }
14969                   if (i) {
14970                      if (pri_create_trunkgroup(trunkgroup, dchannels)) {
14971                         ast_log(LOG_WARNING, "Unable to create trunk group %d with Primary D-channel %d at line %d of chan_dahdi.conf\n", trunkgroup, dchannels[0], v->lineno);
14972                      } else if (option_verbose > 1)
14973                         ast_verbose(VERBOSE_PREFIX_2 "Created trunk group %d with Primary D-channel %d and %d backup%s\n", trunkgroup, dchannels[0], i - 1, (i == 1) ? "" : "s");
14974                   } else
14975                      ast_log(LOG_WARNING, "Trunk group %d lacks any valid D-channels at line %d of chan_dahdi.conf\n", trunkgroup, v->lineno);
14976                } else
14977                   ast_log(LOG_WARNING, "Trunk group %d lacks a primary D-channel at line %d of chan_dahdi.conf\n", trunkgroup, v->lineno);
14978             } else
14979                ast_log(LOG_WARNING, "Trunk group identifier must be a positive integer at line %d of chan_dahdi.conf\n", v->lineno);
14980          } else if (!strcasecmp(v->name, "spanmap")) {
14981             spanno = atoi(v->value);
14982             if (spanno > 0) {
14983                if ((c = strchr(v->value, ','))) {
14984                   trunkgroup = atoi(c + 1);
14985                   if (trunkgroup > 0) {
14986                      if ((c = strchr(c + 1, ','))) 
14987                         logicalspan = atoi(c + 1);
14988                      else
14989                         logicalspan = 0;
14990                      if (logicalspan >= 0) {
14991                         if (pri_create_spanmap(spanno - 1, trunkgroup, logicalspan)) {
14992                            ast_log(LOG_WARNING, "Failed to map span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan);
14993                         } else if (option_verbose > 1) 
14994                            ast_verbose(VERBOSE_PREFIX_2 "Mapped span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan);
14995                      } else
14996                         ast_log(LOG_WARNING, "Logical span must be a postive number, or '0' (for unspecified) at line %d of chan_dahdi.conf\n", v->lineno);
14997                   } else
14998                      ast_log(LOG_WARNING, "Trunk group must be a postive number at line %d of chan_dahdi.conf\n", v->lineno);
14999                } else
15000                   ast_log(LOG_WARNING, "Missing trunk group for span map at line %d of chan_dahdi.conf\n", v->lineno);
15001             } else
15002                ast_log(LOG_WARNING, "Span number must be a postive integer at line %d of chan_dahdi.conf\n", v->lineno);
15003          } else {
15004             ast_log(LOG_NOTICE, "Ignoring unknown keyword '%s' in trunkgroups\n", v->name);
15005          }
15006          v = v->next;
15007       }
15008    }
15009 #endif
15010    
15011    /* Copy the default jb config over global_jbconf */
15012    memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
15013 
15014    v = ast_variable_browse(cfg, "channels");
15015    res = process_dahdi(&conf, "", v, reload, 0);
15016    ast_mutex_unlock(&iflock);
15017    ast_config_destroy(cfg);
15018    if (res)
15019       return res;
15020    cfg = ast_config_load("users.conf");
15021    if (cfg) {
15022       char *cat;
15023 
15024       /* Reset conf back to defaults, so values from chan_dahdi.conf don't leak in. */
15025       conf = dahdi_chan_conf_default();
15026       process_dahdi(&conf, "", ast_variable_browse(cfg, "general"), 1, 1);
15027       for (cat = ast_category_browse(cfg, NULL); cat ; cat = ast_category_browse(cfg, cat)) {
15028          if (!strcasecmp(cat, "general"))
15029             continue;
15030          if (!ast_strlen_zero(ast_variable_retrieve(cfg, cat, "dahdichan")) || !ast_strlen_zero(ast_variable_retrieve(cfg, cat, "zapchan"))) {
15031             struct dahdi_chan_conf sect_conf;
15032             memcpy(&sect_conf, &conf, sizeof(sect_conf));
15033 
15034             process_dahdi(&sect_conf, cat, ast_variable_browse(cfg, cat), reload, 0);
15035          }
15036       }
15037       ast_config_destroy(cfg);
15038    }
15039 #ifdef HAVE_PRI
15040    if (reload != 1) {
15041       for (x = 0; x < NUM_SPANS; x++) {
15042          if (pris[x].pvts[0]) {
15043             if (start_pri(pris + x)) {
15044                ast_log(LOG_ERROR, "Unable to start D-channel on span %d\n", x + 1);
15045                return -1;
15046             } else if (option_verbose > 1)
15047                ast_verbose(VERBOSE_PREFIX_2 "Starting D-Channel on span %d\n", x + 1);
15048          }
15049       }
15050    }
15051 #endif
15052 
15053 #ifdef HAVE_OPENR2
15054    if (reload != 1) {
15055       int x;
15056       for (x = 0; x < NUM_SPANS; x++) {
15057          if (r2links[x].protocol_context) {
15058             if (ast_pthread_create(&r2links[x].master, NULL, mfcr2_monitor, &r2links[x])) {
15059                ast_log(LOG_ERROR, "Unable to start R2 context on span %d\n", x + 1);
15060                return -1;
15061             } else {
15062                ast_verbose(VERBOSE_PREFIX_2 "Starting R2 context on span %d\n", x + 1);
15063             }
15064          }
15065       }
15066    }
15067 #endif
15068 
15069    /* And start the monitor for the first time */
15070    restart_monitor();
15071    return 0;
15072 }
15073 
15074 #define local_astman_register(a, b, c, d) do { \
15075                   if (*dahdi_chan_mode == CHAN_DAHDI_PLUS_ZAP_MODE) { \
15076                      ast_manager_register("DAHDI" a, b, dahdi_ ## c, d); \
15077                   } \
15078                   ast_manager_register("Zap" a, b, zap_ ## c, d); \
15079                  } while (0)
15080 
15081 static int load_module(void)
15082 {
15083    int res;
15084 
15085 #ifdef HAVE_PRI
15086    int y,i;
15087    memset(pris, 0, sizeof(pris));
15088    for (y = 0; y < NUM_SPANS; y++) {
15089       ast_mutex_init(&pris[y].lock);
15090       pris[y].offset = -1;
15091       pris[y].master = AST_PTHREADT_NULL;
15092       for (i = 0; i < NUM_DCHANS; i++)
15093          pris[y].fds[i] = -1;
15094    }
15095    pri_set_error(dahdi_pri_error);
15096    pri_set_message(dahdi_pri_message);
15097    if (*dahdi_chan_mode == CHAN_DAHDI_PLUS_ZAP_MODE) {
15098       ast_register_application(dahdi_send_keypad_facility_app, dahdi_send_keypad_facility_exec,
15099          dahdi_send_keypad_facility_synopsis, dahdi_send_keypad_facility_descrip);
15100    }
15101    ast_register_application(zap_send_keypad_facility_app, zap_send_keypad_facility_exec,
15102       zap_send_keypad_facility_synopsis, zap_send_keypad_facility_descrip);
15103 #endif
15104 
15105 #ifdef HAVE_OPENR2
15106    init_mfcr2_globals();
15107    if (*dahdi_chan_mode == CHAN_DAHDI_PLUS_ZAP_MODE) {
15108       ast_register_application(dahdi_accept_r2_call_app, dahdi_accept_r2_call_exec,
15109          dahdi_accept_r2_call_synopsis, dahdi_accept_r2_call_descrip);
15110    }
15111    ast_register_application(zap_accept_r2_call_app, zap_accept_r2_call_exec,
15112       zap_accept_r2_call_synopsis, zap_accept_r2_call_descrip);
15113 #endif
15114 
15115    if ((res = setup_dahdi(0))) {
15116       return AST_MODULE_LOAD_DECLINE;
15117    }
15118    if (*dahdi_chan_mode == CHAN_DAHDI_PLUS_ZAP_MODE) {
15119       chan_tech = &dahdi_tech;
15120    } else {
15121       chan_tech = &zap_tech;
15122    }
15123    if (ast_channel_register(chan_tech)) {
15124       ast_log(LOG_ERROR, "Unable to register channel class '%s'\n", chan_tech->type);
15125       __unload_module();
15126       return -1;
15127    }
15128 #ifdef HAVE_PRI
15129    ast_string_field_init(&inuse, 16);
15130    ast_string_field_set(&inuse, name, "GR-303InUse");
15131    ast_cli_register_multiple(dahdi_pri_cli, sizeof(dahdi_pri_cli) / sizeof(struct ast_cli_entry));
15132 #endif   
15133 
15134 #ifdef HAVE_OPENR2
15135    ast_cli_register_multiple(dahdi_mfcr2_cli, sizeof(dahdi_mfcr2_cli)/sizeof(dahdi_mfcr2_cli[0]));
15136 #endif
15137 
15138    ast_cli_register_multiple(dahdi_cli, sizeof(dahdi_cli) / sizeof(struct ast_cli_entry));
15139    
15140    memset(round_robin, 0, sizeof(round_robin));
15141    local_astman_register("Transfer", 0, action_transfer, "Transfer Channel");
15142    local_astman_register("Hangup", 0, action_transferhangup, "Hangup Channel");
15143    local_astman_register("DialOffHook", 0, action_dialoffhook, "Dial over channel while offhook");
15144    local_astman_register("DNDon", 0, action_dndon, "Toggle channel Do Not Disturb status ON");
15145    local_astman_register("DNDoff", 0, action_dndoff, "Toggle channel Do Not Disturb status OFF");
15146    local_astman_register("ShowChannels", 0, action_showchannels, "Show status channels");
15147    local_astman_register("Restart", 0, action_restart, "Fully Restart channels (terminates calls)");
15148 
15149    ast_cond_init(&ss_thread_complete, NULL);
15150 
15151    return res;
15152 }
15153 
15154 static int dahdi_sendtext(struct ast_channel *c, const char *text)
15155 {
15156 #define  END_SILENCE_LEN 400
15157 #define  HEADER_MS 50
15158 #define  TRAILER_MS 5
15159 #define  HEADER_LEN ((HEADER_MS + TRAILER_MS) * 8)
15160 #define  ASCII_BYTES_PER_CHAR 80
15161 
15162    unsigned char *buf,*mybuf;
15163    struct dahdi_pvt *p = c->tech_pvt;
15164    struct pollfd fds[1];
15165    int size,res,fd,len,x;
15166    int bytes=0;
15167    /* Initial carrier (imaginary) */
15168    float cr = 1.0;
15169    float ci = 0.0;
15170    float scont = 0.0;
15171    int index;
15172 
15173    index = dahdi_get_index(c, p, 0);
15174    if (index < 0) {
15175       ast_log(LOG_WARNING, "Huh?  I don't exist?\n");
15176       return -1;
15177    }
15178    if (!text[0]) return(0); /* if nothing to send, dont */
15179    if ((!p->tdd) && (!p->mate)) return(0);  /* if not in TDD mode, just return */
15180    if (p->mate) 
15181       buf = ast_malloc(((strlen(text) + 1) * ASCII_BYTES_PER_CHAR) + END_SILENCE_LEN + HEADER_LEN);
15182    else
15183       buf = ast_malloc(((strlen(text) + 1) * TDD_BYTES_PER_CHAR) + END_SILENCE_LEN);
15184    if (!buf)
15185       return -1;
15186    mybuf = buf;
15187    if (p->mate) {
15188       int codec = AST_LAW(p);
15189       for (x = 0; x < HEADER_MS; x++) {   /* 50 ms of Mark */
15190          PUT_CLID_MARKMS;
15191       }
15192       /* Put actual message */
15193       for (x = 0; text[x]; x++) {
15194          PUT_CLID(text[x]);
15195       }
15196       for (x = 0; x < TRAILER_MS; x++) {  /* 5 ms of Mark */
15197          PUT_CLID_MARKMS;
15198       }
15199       len = bytes;
15200       buf = mybuf;
15201    } else {
15202       len = tdd_generate(p->tdd, buf, text);
15203       if (len < 1) {
15204          ast_log(LOG_ERROR, "TDD generate (len %d) failed!!\n", (int)strlen(text));
15205          free(mybuf);
15206          return -1;
15207       }
15208    }
15209    memset(buf + len, 0x7f, END_SILENCE_LEN);
15210    len += END_SILENCE_LEN;
15211    fd = p->subs[index].dfd;
15212    while (len) {
15213       if (ast_check_hangup(c)) {
15214          free(mybuf);
15215          return -1;
15216       }
15217       size = len;
15218       if (size > READ_SIZE)
15219          size = READ_SIZE;
15220       fds[0].fd = fd;
15221       fds[0].events = POLLOUT | POLLPRI;
15222       fds[0].revents = 0;
15223       res = poll(fds, 1, -1);
15224       if (!res) {
15225          ast_log(LOG_DEBUG, "poll (for write) ret. 0 on channel %d\n", p->channel);
15226          continue;
15227       }
15228         /* if got exception */
15229       if (fds[0].revents & POLLPRI) {
15230          ast_free(mybuf);
15231          return -1;
15232       }
15233       if (!(fds[0].revents & POLLOUT)) {
15234          ast_log(LOG_DEBUG, "write fd not ready on channel %d\n", p->channel);
15235          continue;
15236       }
15237       res = write(fd, buf, size);
15238       if (res != size) {
15239          if (res == -1) {
15240             free(mybuf);
15241             return -1;
15242          }
15243          if (option_debug)
15244             ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
15245          break;
15246       }
15247       len -= size;
15248       buf += size;
15249    }
15250    free(mybuf);
15251    return(0);
15252 }
15253 
15254 
15255 static int reload(void)
15256 {
15257    int res = 0;
15258 
15259    res = setup_dahdi(1);
15260    if (res) {
15261       ast_log(LOG_WARNING, "Reload of chan_dahdi.so is unsuccessful!\n");
15262       return -1;
15263    }
15264    return 0;
15265 }
15266 
15267 /* This is a workaround so that menuselect displays a proper description
15268  * AST_MODULE_INFO(, , "DAHDI Telephony"
15269  */
15270 
15271 #ifdef HAVE_PRI
15272 #define tdesc "DAHDI Telephony w/PRI"
15273 #else
15274 #define tdesc "DAHDI Telephony"
15275 #endif
15276 
15277 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, tdesc,
15278       .load = load_module,
15279       .unload = unload_module,
15280       .reload = reload,
15281           );
15282 
15283 

Generated on Sat Aug 6 00:39:24 2011 for Asterisk - the Open Source PBX by  doxygen 1.4.7