Thu Jun 7 02:14:36 2012

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, belonging to same group that original channel
09964  *
09965  * \param pri PRI span control structure.
09966  * \param backwards TRUE if the search starts from higher channels.
09967  * \param orig original channel number (principle) in PRI structure
09968  *
09969  * \note Assumes the pri->lock is already obtained.
09970  *
09971  * \retval array-index into private pointer array on success.
09972  * \retval -1 on error.
09973  */
09974 static int pri_find_empty_chan(struct dahdi_pri *pri, int backwards, int orig)
09975 {
09976    int x;
09977    if (backwards)
09978       x = pri->numchans;
09979    else
09980       x = 0;
09981    for (;;) {
09982       if (backwards && (x < 0))
09983          break;
09984       if (!backwards && (x >= pri->numchans))
09985          break;
09986       if (pri->pvts[x]
09987          && sig_pri_is_chan_available(pri->pvts[x])) {
09988          if (orig < 0) {
09989             ast_log(LOG_NOTICE, "Found empty available channel %d/%d\n", 
09990                         pri->pvts[x]->logicalspan, pri->pvts[x]->prioffset);
09991             return x;
09992          } else {
09993             if (pri->pvts[x]->group & pri->pvts[orig]->group) {
09994                ast_log(LOG_NOTICE, "Found empty channel %d/%d available belonging to same group that %d/%d\n", pri->pvts[x]->logicalspan, pri->pvts[x]->prioffset,
09995                            pri->pvts[x]->logicalspan, pri->pvts[orig]->prioffset, x);
09996                return x;
09997             } else {
09998                ast_log(LOG_DEBUG, "Empty channel %d/%d available but not belongs to same group that %d/%d (x: %d)\n", pri->pvts[x]->logicalspan, pri->pvts[x]->prioffset, 
09999                            pri->pvts[x]->logicalspan, pri->pvts[orig]->prioffset, x);
10000             }
10001          }
10002       }
10003       if (backwards)
10004          x--;
10005       else
10006          x++;
10007    }
10008    return -1;
10009 }
10010 #endif
10011 
10012 static struct ast_channel *dahdi_request(const char *type, int format, void *data, int *cause)
10013 {
10014    ast_group_t groupmatch = 0;
10015    int channelmatch = -1;
10016    int roundrobin = 0;
10017    int callwait = 0;
10018    int busy = 0;
10019    struct dahdi_pvt *p;
10020    struct ast_channel *tmp = NULL;
10021    char *dest=NULL;
10022    int x;
10023    char *s;
10024    char opt=0;
10025    int res=0, y=0;
10026    int backwards = 0;
10027 #ifdef HAVE_PRI
10028    int crv;
10029    int bearer = -1;
10030    int trunkgroup;
10031    struct dahdi_pri *pri=NULL;
10032 #endif   
10033    struct dahdi_pvt *exit, *start, *end;
10034    ast_mutex_t *lock;
10035    int channelmatched = 0;
10036    int groupmatched = 0;
10037    
10038    /*
10039     * data is ---v
10040     * Dial(DAHDI/pseudo[/extension])
10041     * Dial(DAHDI/<channel#>[c|r<cadance#>|d][/extension])
10042     * Dial(DAHDI/<trunk_group#>:<crv#>[c|r<cadance#>|d][/extension])
10043     * Dial(DAHDI/(g|G|r|R)<group#(0-63)>[c|r<cadance#>|d][/extension])
10044     *
10045     * g - channel group allocation search forward
10046     * G - channel group allocation search backward
10047     * r - channel group allocation round robin search forward
10048     * R - channel group allocation round robin search backward
10049     *
10050     * c - Wait for DTMF digit to confirm answer
10051     * r<cadance#> - Set distintive ring cadance number
10052     * d - Force bearer capability for ISDN call to digital.
10053     */
10054 
10055    /* Assume we're locking the iflock */
10056    lock = &iflock;
10057    start = iflist;
10058    end = ifend;
10059    if (data) {
10060       dest = ast_strdupa((char *)data);
10061    } else {
10062       ast_log(LOG_WARNING, "Channel requested with no data\n");
10063       return NULL;
10064    }
10065    if (toupper(dest[0]) == 'G' || toupper(dest[0])=='R') {
10066       /* Retrieve the group number */
10067       char *stringp;
10068 
10069       stringp = dest + 1;
10070       s = strsep(&stringp, "/");
10071       if ((res = sscanf(s, "%30d%1c%30d", &x, &opt, &y)) < 1) {
10072          ast_log(LOG_WARNING, "Unable to determine group for data %s\n", (char *)data);
10073          return NULL;
10074       }
10075       groupmatch = ((ast_group_t) 1 << x);
10076       if (toupper(dest[0]) == 'G') {
10077          if (dest[0] == 'G') {
10078             backwards = 1;
10079             p = ifend;
10080          } else
10081             p = iflist;
10082       } else {
10083          if (dest[0] == 'R') {
10084             backwards = 1;
10085             p = round_robin[x]?round_robin[x]->prev:ifend;
10086             if (!p)
10087                p = ifend;
10088          } else {
10089             p = round_robin[x]?round_robin[x]->next:iflist;
10090             if (!p)
10091                p = iflist;
10092          }
10093          roundrobin = 1;
10094       }
10095    } else {
10096       char *stringp;
10097 
10098       stringp = dest;
10099       s = strsep(&stringp, "/");
10100       p = iflist;
10101       if (!strcasecmp(s, "pseudo")) {
10102          /* Special case for pseudo */
10103          x = CHAN_PSEUDO;
10104          channelmatch = x;
10105       } 
10106 #ifdef HAVE_PRI
10107       else if ((res = sscanf(s, "%30d:%30d%c%30d", &trunkgroup, &crv, &opt, &y)) > 1) {
10108          if ((trunkgroup < 1) || (crv < 1)) {
10109             ast_log(LOG_WARNING, "Unable to determine trunk group and CRV for data %s\n", (char *)data);
10110             return NULL;
10111          }
10112          res--;
10113          for (x = 0; x < NUM_SPANS; x++) {
10114             if (pris[x].trunkgroup == trunkgroup) {
10115                pri = pris + x;
10116                lock = &pri->lock;
10117                start = pri->crvs;
10118                end = pri->crvend;
10119                break;
10120             }
10121          }
10122          if (!pri) {
10123             ast_log(LOG_WARNING, "Unable to find trunk group %d\n", trunkgroup);
10124             return NULL;
10125          }
10126          channelmatch = crv;
10127          p = pris[x].crvs;
10128       }
10129 #endif   
10130       else if ((res = sscanf(s, "%30d%1c%30d", &x, &opt, &y)) < 1) {
10131          ast_log(LOG_WARNING, "Unable to determine channel for data %s\n", (char *)data);
10132          return NULL;
10133       } else {
10134          channelmatch = x;
10135       }
10136    }
10137    /* Search for an unowned channel */
10138    ast_mutex_lock(lock);
10139    exit = p;
10140    while (p && !tmp) {
10141       if (roundrobin)
10142          round_robin[x] = p;
10143 #if 0
10144       ast_verbose("name = %s, %d, %d, %llu\n",p->owner ? p->owner->name : "<none>", p->channel, channelmatch, groupmatch);
10145 #endif
10146 
10147       if (p && available(p, channelmatch, groupmatch, &busy, &channelmatched, &groupmatched)) {
10148          if (option_debug)
10149             ast_log(LOG_DEBUG, "Using channel %d\n", p->channel);
10150             if (p->inalarm) 
10151                goto next;
10152 
10153          callwait = (p->owner != NULL);
10154 #ifdef HAVE_PRI
10155          if (pri && (p->subs[SUB_REAL].dfd < 0)) {
10156             if (p->sig != SIG_FXSKS) {
10157                /* Gotta find an actual channel to use for this
10158                   CRV if this isn't a callwait */
10159                bearer = pri_find_empty_chan(pri, 0, -1);
10160                if (bearer < 0) {
10161                   ast_log(LOG_NOTICE, "Out of bearer channels on span %d for call to CRV %d:%d\n", pri->span, trunkgroup, crv);
10162                   p = NULL;
10163                   break;
10164                }
10165                pri_assign_bearer(p, pri, pri->pvts[bearer]);
10166             } else {
10167                if (alloc_sub(p, 0)) {
10168                   ast_log(LOG_NOTICE, "Failed to allocate place holder pseudo channel!\n");
10169                   p = NULL;
10170                   break;
10171                } else
10172                   ast_log(LOG_DEBUG, "Allocated placeholder pseudo channel\n");
10173                p->pri = pri;
10174             }
10175          }
10176 #endif
10177 
10178 #ifdef HAVE_OPENR2
10179          if (p->mfcr2) {
10180             ast_mutex_lock(&p->lock);
10181             if (p->mfcr2call) {
10182                ast_mutex_unlock(&p->lock);
10183                ast_log(LOG_NOTICE, "Yay!, someone just beat us in the race for channel %d.\n", p->channel);
10184                goto next;
10185             }
10186             if (p->mfcr2block) {
10187                ast_mutex_unlock(&p->lock);
10188                ast_log(LOG_NOTICE, "Yay!, channel %d just got blocked (%d).\n", p->channel, p->mfcr2block);
10189                goto next;
10190             }
10191             p->mfcr2call = 1;
10192             ast_mutex_unlock(&p->lock);
10193          }
10194 #endif
10195 
10196          if (p->channel == CHAN_PSEUDO) {
10197             p = chandup(p);
10198             if (!p) {
10199                break;
10200             }
10201          }
10202          if (p->owner) {
10203             if (alloc_sub(p, SUB_CALLWAIT)) {
10204                p = NULL;
10205                break;
10206             }
10207          }
10208 #if defined(HAVE_PRI)
10209          switch (p->sig) {
10210          case SIG_GR303FXOKS:
10211          case SIG_GR303FXSKS:
10212          case SIG_PRI_LIB_HANDLE_CASES:
10213             /*
10214              * We already have the B channel reserved for this call.  We
10215              * just need to make sure that dahdi_hangup() has completed
10216              * cleaning up before continuing.
10217              */
10218             ast_mutex_lock(&p->lock);
10219             ast_mutex_unlock(&p->lock);
10220             break;
10221          default:
10222             break;
10223          }
10224 #endif   /* defined(HAVE_PRI) */
10225          p->outgoing = 1;
10226          tmp = dahdi_new(p, AST_STATE_RESERVED, 0, p->owner ? SUB_CALLWAIT : SUB_REAL, 0, 0);
10227          if (!tmp) {
10228             p->outgoing = 0;
10229 #if defined(HAVE_PRI)
10230             /*
10231              * This should be the last thing to clear when we are done with
10232              * the channel.
10233              */
10234             p->allocated = 0;
10235 #endif   /* defined(HAVE_PRI) */
10236          }
10237 #ifdef HAVE_PRI
10238          if (p->bearer) {
10239             /* Log owner to bearer channel, too */
10240             p->bearer->owner = tmp;
10241          }
10242 #endif         
10243          /* Make special notes */
10244          if (res > 1) {
10245             if (opt == 'c') {
10246                /* Confirm answer */
10247                p->confirmanswer = 1;
10248             } else if (opt == 'r') {
10249                /* Distinctive ring */
10250                if (res < 3)
10251                   ast_log(LOG_WARNING, "Distinctive ring missing identifier in '%s'\n", (char *)data);
10252                else
10253                   p->distinctivering = y;
10254             } else if (opt == 'd') {
10255                /* If this is an ISDN call, make it digital */
10256                p->digital = 1;
10257                if (tmp)
10258                   tmp->transfercapability = AST_TRANS_CAP_DIGITAL;
10259             } else {
10260                ast_log(LOG_WARNING, "Unknown option '%c' in '%s'\n", opt, (char *)data);
10261             }
10262          }
10263          /* Note if the call is a call waiting call */
10264          if (tmp && callwait)
10265             tmp->cdrflags |= AST_CDR_CALLWAIT;
10266          break;
10267       }
10268 next:
10269       if (backwards) {
10270          p = p->prev;
10271          if (!p)
10272             p = end;
10273       } else {
10274          p = p->next;
10275          if (!p)
10276             p = start;
10277       }
10278       /* stop when you roll to the one that we started from */
10279       if (p == exit)
10280          break;
10281    }
10282    ast_mutex_unlock(lock);
10283    restart_monitor();
10284    if (callwait)
10285       *cause = AST_CAUSE_BUSY;
10286    else if (!tmp) {
10287       if (channelmatched) {
10288          if (busy)
10289             *cause = AST_CAUSE_BUSY;
10290       } else if (groupmatched) {
10291          *cause = AST_CAUSE_CONGESTION;
10292       }
10293    }
10294       
10295    return tmp;
10296 }
10297 
10298 #ifdef HAVE_OPENR2
10299 static void *mfcr2_monitor(void *data)
10300 {
10301    struct dahdi_pvt *p;
10302    struct dahdi_mfcr2 *mfcr2 = data;
10303    /* we should be using pthread_key_create
10304       and allocate pollers dynamically.
10305       I think do_monitor() could be leaking, since it
10306       could be cancelled at any time and is not
10307       using thread keys, why?, */
10308    struct pollfd pollers[mfcr2->numchans];
10309    int maxsleep = 20;
10310    int res = 0;
10311    int i = 0;
10312    int pollsize = 0;
10313    int oldstate = 0;
10314    int was_idle = 0;
10315    int quit_loop = 0;
10316    /* now that we're ready to get calls, unblock our side and
10317       get current line state */
10318    for (i = 0; i < mfcr2->numchans; i++) {
10319       p = mfcr2->pvts[i];
10320       pollers[i].fd = mfcr2->pvts[i]->subs[SUB_REAL].dfd;
10321       if (openr2_chan_set_idle(p->r2chan)) {
10322          ast_log(LOG_ERROR, "Failed to set channel %d in IDLE\n", p->channel);
10323       } else {
10324          ast_mutex_lock(&p->lock);
10325          mfcr2->pvts[i]->mfcr2block &= ~DAHDI_R2_LOCAL_BLOCK;
10326          mfcr2->pvts[i]->mfcr2call = 0;
10327          ast_mutex_unlock(&p->lock);
10328       }
10329       openr2_chan_handle_cas(mfcr2->pvts[i]->r2chan);
10330    }
10331    while(1) {
10332       /* we trust here that the mfcr2 channel list will not ever change once
10333          the module is loaded */
10334       pollsize = 0;
10335       for (i = 0; i < mfcr2->numchans; i++) {
10336          pollers[i].events = 0;
10337          pollers[i].revents = 0;
10338          if (mfcr2->pvts[i]->owner) {
10339             continue;
10340          }
10341          if (!mfcr2->pvts[i]->r2chan) {
10342             ast_log(LOG_DEBUG, "Wow, no r2chan on channel %d\n", mfcr2->pvts[i]->channel);
10343             quit_loop = 1;
10344             break;
10345          }
10346          openr2_chan_enable_read(mfcr2->pvts[i]->r2chan);
10347          pollers[i].events = POLLIN | POLLPRI;
10348          pollsize++;
10349       }
10350       if (quit_loop) {
10351          break;
10352       }
10353 
10354       if (pollsize == 0) {
10355          if (!was_idle) {
10356             ast_log(LOG_NOTICE, "Monitor thread going idle since everybody has an owner\n");
10357             was_idle = 1;
10358          }
10359          poll(NULL, 0, maxsleep);
10360          continue;
10361       }
10362       was_idle = 0;
10363 
10364       /* probably poll() is a valid cancel point, lets just be on the safe side
10365          by calling pthread_testcancel */
10366       pthread_testcancel();
10367       res = poll(pollers, mfcr2->numchans, maxsleep);
10368       pthread_testcancel();
10369       if ((res < 0) && (errno != EINTR)) {
10370          ast_log(LOG_ERROR, "going out, poll failed: %s\n", strerror(errno));
10371          break;
10372       } 
10373       /* do we want to allow to cancel while processing events? */
10374       pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate);
10375       for (i = 0; i < mfcr2->numchans; i++) {
10376          if ((pollers[i].revents & POLLPRI) || (pollers[i].revents & POLLIN)) {
10377             openr2_chan_process_event(mfcr2->pvts[i]->r2chan);
10378          }
10379       }
10380       pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
10381    }
10382    ast_log(LOG_NOTICE, "Quitting MFC/R2 monitor thread\n");
10383    return 0;
10384 }
10385 #endif
10386 
10387 #if defined(HAVE_PRI)
10388 static struct dahdi_pvt *pri_find_crv(struct dahdi_pri *pri, int crv)
10389 {
10390    struct dahdi_pvt *p;
10391    p = pri->crvs;
10392    while (p) {
10393       if (p->channel == crv)
10394          return p;
10395       p = p->next;
10396    }
10397    return NULL;
10398 }
10399 #endif   /* defined(HAVE_PRI) */
10400 
10401 #if defined(HAVE_PRI)
10402 /*!
10403  * \internal
10404  * \brief Obtain the DAHDI owner channel lock if the owner exists.
10405  * \since 1.8
10406  *
10407  * \param pri PRI span control structure.
10408  * \param chanpos Channel position in the span.
10409  *
10410  * \note Assumes the pri->lock is already obtained.
10411  * \note Assumes the pri->pvts[chanpos]->lock is already obtained.
10412  *
10413  * \return Nothing
10414  */
10415 static void sig_pri_lock_owner(struct dahdi_pri *pri, int chanpos)
10416 {
10417    for (;;) {
10418       if (!pri->pvts[chanpos]->owner) {
10419          /* There is no owner lock to get. */
10420          break;
10421       }
10422       if (!ast_channel_trylock(pri->pvts[chanpos]->owner)) {
10423          /* We got the lock */
10424          break;
10425       }
10426       /* We must unlock the PRI to avoid the possibility of a deadlock */
10427       ast_mutex_unlock(&pri->lock);
10428       DEADLOCK_AVOIDANCE(&pri->pvts[chanpos]->lock);
10429       ast_mutex_lock(&pri->lock);
10430    }
10431 }
10432 #endif   /* defined(HAVE_PRI) */
10433 
10434 #if defined(HAVE_PRI)
10435 /*!
10436  * \internal
10437  * \brief Queue the given frame onto the owner channel.
10438  * \since 1.8
10439  *
10440  * \param pri PRI span control structure.
10441  * \param chanpos Channel position in the span.
10442  * \param frame Frame to queue onto the owner channel.
10443  *
10444  * \note Assumes the pri->lock is already obtained.
10445  * \note Assumes the sig_pri_lock_private(pri->pvts[chanpos]) is already obtained.
10446  *
10447  * \return Nothing
10448  */
10449 static void pri_queue_frame(struct dahdi_pri *pri, int chanpos, struct ast_frame *frame)
10450 {
10451    sig_pri_lock_owner(pri, chanpos);
10452    if (pri->pvts[chanpos]->owner) {
10453       ast_queue_frame(pri->pvts[chanpos]->owner, frame);
10454       ast_channel_unlock(pri->pvts[chanpos]->owner);
10455    }
10456 }
10457 #endif   /* defined(HAVE_PRI) */
10458 
10459 #if defined(HAVE_PRI)
10460 /*!
10461  * \internal
10462  * \brief Queue a control frame of the specified subclass onto the owner channel.
10463  * \since 1.8
10464  *
10465  * \param pri PRI span control structure.
10466  * \param chanpos Channel position in the span.
10467  * \param subclass Control frame subclass to queue onto the owner channel.
10468  *
10469  * \note Assumes the pri->lock is already obtained.
10470  * \note Assumes the sig_pri_lock_private(pri->pvts[chanpos]) is already obtained.
10471  *
10472  * \return Nothing
10473  */
10474 static void pri_queue_control(struct dahdi_pri *pri, int chanpos, int subclass)
10475 {
10476    struct ast_frame f = {AST_FRAME_CONTROL, };
10477 
10478    f.subclass = subclass;
10479    pri_queue_frame(pri, chanpos, &f);
10480 }
10481 #endif   /* defined(HAVE_PRI) */
10482 
10483 #if defined(HAVE_PRI)
10484 /*!
10485  * \internal
10486  * \brief Find the channel associated with the libpri call.
10487  * \since 1.10
10488  *
10489  * \param pri PRI span control structure.
10490  * \param call LibPRI opaque call pointer to find.
10491  *
10492  * \note Assumes the pri->lock is already obtained.
10493  *
10494  * \retval array-index into private pointer array on success.
10495  * \retval -1 on error.
10496  */
10497 static int pri_find_principle_by_call(struct dahdi_pri *pri, q931_call *call)
10498 {
10499    int idx;
10500 
10501    if (!call) {
10502       /* Cannot find a call without a call. */
10503       return -1;
10504    }
10505    for (idx = 0; idx < pri->numchans; ++idx) {
10506       if (pri->pvts[idx] && pri->pvts[idx]->call == call) {
10507          /* Found the principle */
10508          return idx;
10509       }
10510    }
10511    return -1;
10512 }
10513 #endif   /* defined(HAVE_PRI) */
10514 
10515 #if defined(HAVE_PRI)
10516 /*!
10517  * \internal
10518  * \brief Kill the call.
10519  * \since 1.10
10520  *
10521  * \param pri PRI span control structure.
10522  * \param call LibPRI opaque call pointer to find.
10523  * \param cause Reason call was killed.
10524  *
10525  * \note Assumes the pvt->pri->lock is already obtained.
10526  *
10527  * \return Nothing
10528  */
10529 static void sig_pri_kill_call(struct dahdi_pri *pri, q931_call *call, int cause)
10530 {
10531    int chanpos;
10532 
10533    chanpos = pri_find_principle_by_call(pri, call);
10534    if (chanpos < 0) {
10535       pri_hangup(pri->pri, call, cause);
10536       return;
10537    }
10538    ast_mutex_lock(&pri->pvts[chanpos]->lock);
10539    if (!pri->pvts[chanpos]->owner) {
10540       pri_hangup(pri->pri, call, cause);
10541       pri->pvts[chanpos]->call = NULL;
10542       ast_mutex_unlock(&pri->pvts[chanpos]->lock);
10543       return;
10544    }
10545    pri->pvts[chanpos]->owner->hangupcause = cause;
10546    pri_queue_control(pri, chanpos, AST_CONTROL_HANGUP);
10547    ast_mutex_unlock(&pri->pvts[chanpos]->lock);
10548 }
10549 #endif   /* defined(HAVE_PRI) */
10550 
10551 #if defined(HAVE_PRI)
10552 /*!
10553  * \internal
10554  * \brief Find the private structure for the libpri call.
10555  *
10556  * \param pri PRI span control structure.
10557  * \param channel LibPRI encoded channel ID.
10558  *
10559  * \note Assumes the pri->lock is already obtained.
10560  *
10561  * \retval array-index into private pointer array on success.
10562  * \retval -1 on error.
10563  */
10564 static int pri_find_principle(struct dahdi_pri *pri, int channel)
10565 {
10566    int x;
10567    int span = PRI_SPAN(channel);
10568    int spanfd;
10569    struct dahdi_params param;
10570    int principle = -1;
10571    int explicit = PRI_EXPLICIT(channel);
10572    channel = PRI_CHANNEL(channel);
10573 
10574    if (!explicit) {
10575       spanfd = pri_active_dchan_fd(pri);
10576       memset(&param, 0, sizeof(param));
10577       if (ioctl(spanfd, DAHDI_GET_PARAMS, &param))
10578          return -1;
10579       span = pris[param.spanno - 1].prilogicalspan;
10580    }
10581 
10582    for (x = 0; x < pri->numchans; x++) {
10583       if (pri->pvts[x] && (pri->pvts[x]->prioffset == channel) && (pri->pvts[x]->logicalspan == span)) {
10584          principle = x;
10585          break;
10586       }
10587    }
10588    
10589    return principle;
10590 }
10591 #endif   /* defined(HAVE_PRI) */
10592 
10593 #if defined(HAVE_PRI)
10594 /*!
10595  * \internal
10596  * \brief Fixup the private structure associated with the libpri call.
10597  *
10598  * \param pri PRI span control structure.
10599  * \param principle Array-index into private array to move call to if not already there.
10600  * \param c LibPRI opaque call pointer to find if need to move call.
10601  *
10602  * \note Assumes the pri->lock is already obtained.
10603  *
10604  * \retval principle on success.
10605  * \retval -1 on error.
10606  */
10607 static int pri_fixup_principle(struct dahdi_pri *pri, int principle, q931_call *c)
10608 {
10609    int x;
10610    struct dahdi_pvt *crv;
10611    if (!c) {
10612       if (principle < 0)
10613          return -1;
10614       return principle;
10615    }
10616    if ((principle > -1) && 
10617       (principle < pri->numchans) && 
10618       (pri->pvts[principle]) && 
10619       (pri->pvts[principle]->call == c))
10620       return principle;
10621    /* First, check for other bearers */
10622    for (x = 0; x < pri->numchans; x++) {
10623       if (!pri->pvts[x])
10624          continue;
10625       if (pri->pvts[x]->call == c) {
10626          /* Found our call */
10627          if (principle != x) {
10628             struct dahdi_pvt *new = pri->pvts[principle], *old = pri->pvts[x];
10629 
10630             /* Get locks to safely move to the new private structure. */
10631             ast_mutex_lock(&old->lock);
10632             sig_pri_lock_owner(pri, x);
10633             ast_mutex_lock(&new->lock);
10634 
10635             if (option_verbose > 2) {
10636                ast_verbose(VERBOSE_PREFIX_3
10637                   "Moving call (%s) from channel %d to %d.\n",
10638                   old->owner ? old->owner->name : "",
10639                   old->channel, new->channel);
10640             }
10641             if (!sig_pri_is_chan_available(new)) {
10642                ast_log(LOG_WARNING,
10643                   "Can't move call (%s) from channel %d to %d.  It is already in use.\n",
10644                   old->owner ? old->owner->name : "",
10645                   old->channel, new->channel);
10646                ast_mutex_unlock(&new->lock);
10647                if (old->owner) {
10648                   ast_mutex_unlock(&old->owner->lock);
10649                }
10650                ast_mutex_unlock(&old->lock);
10651                return -1;
10652             }
10653 
10654             /* Fix it all up now */
10655             new->owner = old->owner;
10656             old->owner = NULL;
10657             if (new->owner) {
10658                ast_string_field_build(new->owner, name, "%s/%d:%d-%d", dahdi_chan_name, pri->trunkgroup, new->channel, 1);
10659                new->owner->tech_pvt = new;
10660                new->owner->fds[0] = new->subs[SUB_REAL].dfd;
10661                new->subs[SUB_REAL].owner = old->subs[SUB_REAL].owner;
10662                old->subs[SUB_REAL].owner = NULL;
10663             } else
10664                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);
10665             new->call = old->call;
10666             old->call = NULL;
10667 
10668             /* Copy any DSP that may be present */
10669             new->dsp = old->dsp;
10670             new->dsp_features = old->dsp_features;
10671             old->dsp = NULL;
10672             old->dsp_features = 0;
10673 
10674             /* Transfer flags from the old channel. */
10675             new->alreadyhungup = old->alreadyhungup;
10676             new->isidlecall = old->isidlecall;
10677             new->progress = old->progress;
10678             new->allocated = old->allocated;
10679             new->outgoing = old->outgoing;
10680             new->digital = old->digital;
10681             old->alreadyhungup = 0;
10682             old->isidlecall = 0;
10683             old->progress = 0;
10684             old->allocated = 0;
10685             old->outgoing = 0;
10686             old->digital = 0;
10687 
10688             /* More stuff to transfer to the new channel. */
10689             new->call_level = old->call_level;
10690             old->call_level = DAHDI_CALL_LEVEL_IDLE;
10691  
10692             ast_mutex_unlock(&old->lock);
10693             if (new->owner) {
10694                ast_mutex_unlock(&new->owner->lock);
10695             }
10696             ast_mutex_unlock(&new->lock);
10697          }
10698          return principle;
10699       }
10700    }
10701    /* Now check for a CRV with no bearer */
10702    crv = pri->crvs;
10703    while (crv) {
10704       if (crv->call == c) {
10705          /* This is our match...  Perform some basic checks */
10706          if (crv->bearer)
10707             ast_log(LOG_WARNING, "Trying to fix up call which already has a bearer which isn't the one we think it is\n");
10708          else if (pri->pvts[principle]->owner) 
10709             ast_log(LOG_WARNING, "Tring to fix up a call to a bearer which already has an owner!\n");
10710          else {
10711             /* Looks good.  Drop the pseudo channel now, clear up the assignment, and
10712                wakeup the potential sleeper */
10713             dahdi_close_sub(crv, SUB_REAL);
10714             pri->pvts[principle]->call = crv->call;
10715             pri_assign_bearer(crv, pri, pri->pvts[principle]);
10716             ast_log(LOG_DEBUG, "Assigning bearer %d/%d to CRV %d:%d\n",
10717                            pri->pvts[principle]->logicalspan, pri->pvts[principle]->prioffset,
10718                            pri->trunkgroup, crv->channel);
10719             wakeup_sub(crv, SUB_REAL, pri);
10720          }
10721          return principle;
10722       }
10723       crv = crv->next;
10724    }
10725    ast_log(LOG_WARNING, "Call specified, but not found?\n");
10726    return -1;
10727 }
10728 #endif   /* defined(HAVE_PRI) */
10729 
10730 #if defined(HAVE_PRI)
10731 /*!
10732  * \internal
10733  * \brief Find and fixup the private structure associated with the libpri call.
10734  *
10735  * \param pri PRI span control structure.
10736  * \param channel LibPRI encoded channel ID.
10737  * \param call LibPRI opaque call pointer.
10738  *
10739  * \details
10740  * This is a combination of pri_find_principle() and pri_fixup_principle()
10741  * to reduce code redundancy and to make handling several PRI_EVENT_xxx's
10742  * consistent for the current architecture.
10743  *
10744  * \note Assumes the pri->lock is already obtained.
10745  *
10746  * \retval array-index into private pointer array on success.
10747  * \retval -1 on error.
10748  */
10749 static int pri_find_fixup_principle(struct dahdi_pri *pri, int channel, q931_call *call)
10750 {
10751    int chanpos;
10752 
10753    chanpos = pri_find_principle(pri, channel);
10754    if (chanpos < 0) {
10755       ast_log(LOG_WARNING, "Span %d: PRI requested channel %d/%d is unconfigured.\n",
10756          pri->span, PRI_SPAN(channel), PRI_CHANNEL(channel));
10757       sig_pri_kill_call(pri, call, PRI_CAUSE_IDENTIFIED_CHANNEL_NOTEXIST);
10758       return -1;
10759    }
10760    chanpos = pri_fixup_principle(pri, chanpos, call);
10761    if (chanpos < 0) {
10762       ast_log(LOG_WARNING, "Span %d: PRI requested channel %d/%d is not available.\n",
10763          pri->span, PRI_SPAN(channel), PRI_CHANNEL(channel));
10764       /*
10765        * Using Q.931 section 5.2.3.1 b) as the reason for picking
10766        * PRI_CAUSE_CHANNEL_UNACCEPTABLE.  Receiving a
10767        * PRI_CAUSE_REQUESTED_CHAN_UNAVAIL would cause us to restart
10768        * that channel (which is not specified by Q.931) and kill some
10769        * other call which would be bad.
10770        */
10771       sig_pri_kill_call(pri, call, PRI_CAUSE_CHANNEL_UNACCEPTABLE);
10772       return -1;
10773    }
10774    return chanpos;
10775 }
10776 #endif   /* defined(HAVE_PRI) */
10777 
10778 #if defined(HAVE_PRI)
10779 static void *do_idle_thread(void *vchan)
10780 {
10781    struct ast_channel *chan = vchan;
10782    struct dahdi_pvt *pvt = chan->tech_pvt;
10783    struct ast_frame *f;
10784    char ex[80];
10785    /* Wait up to 30 seconds for an answer */
10786    int newms, ms = 30000;
10787    if (option_verbose > 2) 
10788       ast_verbose(VERBOSE_PREFIX_3 "Initiating idle call on channel %s\n", chan->name);
10789    snprintf(ex, sizeof(ex), "%d/%s", pvt->channel, pvt->pri->idledial);
10790    if (ast_call(chan, ex, 0)) {
10791       ast_log(LOG_WARNING, "Idle dial failed on '%s' to '%s'\n", chan->name, ex);
10792       ast_hangup(chan);
10793       return NULL;
10794    }
10795    while ((newms = ast_waitfor(chan, ms)) > 0) {
10796       f = ast_read(chan);
10797       if (!f) {
10798          /* Got hangup */
10799          break;
10800       }
10801       if (f->frametype == AST_FRAME_CONTROL) {
10802          switch (f->subclass) {
10803          case AST_CONTROL_ANSWER:
10804             /* Launch the PBX */
10805             ast_copy_string(chan->exten, pvt->pri->idleext, sizeof(chan->exten));
10806             ast_copy_string(chan->context, pvt->pri->idlecontext, sizeof(chan->context));
10807             chan->priority = 1;
10808             if (option_verbose > 3) 
10809                ast_verbose(VERBOSE_PREFIX_3 "Idle channel '%s' answered, sending to %s@%s\n", chan->name, chan->exten, chan->context);
10810             ast_pbx_run(chan);
10811             /* It's already hungup, return immediately */
10812             return NULL;
10813          case AST_CONTROL_BUSY:
10814             if (option_verbose > 3) 
10815                ast_verbose(VERBOSE_PREFIX_3 "Idle channel '%s' busy, waiting...\n", chan->name);
10816             break;
10817          case AST_CONTROL_CONGESTION:
10818             if (option_verbose > 3) 
10819                ast_verbose(VERBOSE_PREFIX_3 "Idle channel '%s' congested, waiting...\n", chan->name);
10820             break;
10821          };
10822       }
10823       ast_frfree(f);
10824       ms = newms;
10825    }
10826    /* Hangup the channel since nothing happend */
10827    ast_hangup(chan);
10828    return NULL;
10829 }
10830 
10831 #ifndef PRI_RESTART
10832 #error "Upgrade your libpri"
10833 #endif
10834 static void dahdi_pri_message(struct pri *pri, char *s)
10835 {
10836    int x, y;
10837    int dchan = -1, span = -1;
10838    int dchancount = 0;
10839 
10840    if (pri) {
10841       for (x = 0; x < NUM_SPANS; x++) {
10842          for (y = 0; y < NUM_DCHANS; y++) {
10843             if (pris[x].dchans[y])
10844                dchancount++;
10845 
10846             if (pris[x].dchans[y] == pri)
10847                dchan = y;
10848          }
10849          if (dchan >= 0) {
10850             span = x;
10851             break;
10852          }
10853          dchancount = 0;
10854       }
10855       if ((dchan >= 0) && (span >= 0)) {
10856          if (dchancount > 1)
10857             ast_verbose("[Span %d D-Channel %d]%s", span, dchan, s);
10858          else
10859             ast_verbose("%s", s);
10860       } else
10861          ast_log(LOG_ERROR, "PRI debug error: could not find pri associated it with debug message output\n");
10862    } else
10863       ast_verbose("%s", s);
10864 
10865    ast_mutex_lock(&pridebugfdlock);
10866 
10867    if (pridebugfd >= 0) {
10868       if (write(pridebugfd, s, strlen(s)) < 0) {
10869          ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
10870       }
10871    }
10872 
10873    ast_mutex_unlock(&pridebugfdlock);
10874 }
10875 
10876 static void dahdi_pri_error(struct pri *pri, char *s)
10877 {
10878    int x, y;
10879    int dchan = -1, span = -1;
10880    int dchancount = 0;
10881 
10882    if (pri) {
10883       for (x = 0; x < NUM_SPANS; x++) {
10884          for (y = 0; y < NUM_DCHANS; y++) {
10885             if (pris[x].dchans[y])
10886                dchancount++;
10887 
10888             if (pris[x].dchans[y] == pri)
10889                dchan = y;
10890          }
10891          if (dchan >= 0) {
10892             span = x;
10893             break;
10894          }
10895          dchancount = 0;
10896       }
10897       if ((dchan >= 0) && (span >= 0)) {
10898          if (dchancount > 1)
10899             ast_log(LOG_ERROR, "[Span %d D-Channel %d] PRI: %s", span, dchan, s);
10900          else
10901             ast_log(LOG_ERROR, "%s", s);
10902       } else
10903          ast_log(LOG_ERROR, "PRI debug error: could not find pri associated it with debug message output\n");
10904    } else
10905       ast_log(LOG_ERROR, "%s", s);
10906 
10907    ast_mutex_lock(&pridebugfdlock);
10908 
10909    if (pridebugfd >= 0) {
10910       if (write(pridebugfd, s, strlen(s)) < 0) {
10911          ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
10912       }
10913    }
10914 
10915    ast_mutex_unlock(&pridebugfdlock);
10916 }
10917 
10918 /*!
10919  * \internal
10920  * \brief Restart the next channel we think is idle on the span.
10921  *
10922  * \param pri PRI span control structure.
10923  *
10924  * \note Assumes the pri->lock is already obtained.
10925  *
10926  * \return Nothing
10927  */
10928 static void pri_check_restart(struct dahdi_pri *pri)
10929 {
10930    for (++pri->resetpos; pri->resetpos < pri->numchans; ++pri->resetpos) {
10931       if (!pri->pvts[pri->resetpos]
10932          || sig_pri_is_chan_in_use(pri->pvts[pri->resetpos])) {
10933          continue;
10934       }
10935       break;
10936    }
10937    if (pri->resetpos < pri->numchans) {
10938       /* Mark the channel as resetting and restart it */
10939       pri->pvts[pri->resetpos]->resetting = 1;
10940       pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[pri->resetpos]));
10941    } else {
10942       pri->resetting = 0;
10943       time(&pri->lastreset);
10944    }
10945 }
10946 
10947 static int pri_hangup_all(struct dahdi_pvt *p, struct dahdi_pri *pri)
10948 {
10949    int x;
10950    int redo;
10951    ast_mutex_unlock(&pri->lock);
10952    ast_mutex_lock(&p->lock);
10953    do {
10954       redo = 0;
10955       for (x = 0; x < 3; x++) {
10956          while (p->subs[x].owner && ast_mutex_trylock(&p->subs[x].owner->lock)) {
10957             redo++;
10958             DEADLOCK_AVOIDANCE(&p->lock);
10959          }
10960          if (p->subs[x].owner) {
10961             ast_queue_hangup(p->subs[x].owner);
10962             ast_mutex_unlock(&p->subs[x].owner->lock);
10963          }
10964       }
10965    } while (redo);
10966    ast_mutex_unlock(&p->lock);
10967    ast_mutex_lock(&pri->lock);
10968    return 0;
10969 }
10970 
10971 static char * redirectingreason2str(int redirectingreason)
10972 {
10973    switch (redirectingreason) {
10974    case 0:
10975       return "UNKNOWN";
10976    case 1:
10977       return "BUSY";
10978    case 2:
10979       return "NO_REPLY";
10980    case 0xF:
10981       return "UNCONDITIONAL";
10982    default:
10983       return "NOREDIRECT";
10984    }
10985 }
10986 
10987 static void apply_plan_to_number(char *buf, size_t size, const struct dahdi_pri *pri, const char *number, const int plan)
10988 {
10989    if (ast_strlen_zero(number)) { /* make sure a number exists so prefix isn't placed on an empty string */
10990       if (size) {
10991          *buf = '\0';
10992       }
10993       return;
10994    }
10995 
10996    switch (plan) {
10997    case PRI_INTERNATIONAL_ISDN:     /* Q.931 dialplan == 0x11 international dialplan => prepend international prefix digits */
10998       snprintf(buf, size, "%s%s", pri->internationalprefix, number);
10999       break;
11000    case PRI_NATIONAL_ISDN:       /* Q.931 dialplan == 0x21 national dialplan => prepend national prefix digits */
11001       snprintf(buf, size, "%s%s", pri->nationalprefix, number);
11002       break;
11003    case PRI_LOCAL_ISDN:       /* Q.931 dialplan == 0x41 local dialplan => prepend local prefix digits */
11004       snprintf(buf, size, "%s%s", pri->localprefix, number);
11005       break;
11006    case PRI_PRIVATE:       /* Q.931 dialplan == 0x49 private dialplan => prepend private prefix digits */
11007       snprintf(buf, size, "%s%s", pri->privateprefix, number);
11008       break;
11009    case PRI_UNKNOWN:       /* Q.931 dialplan == 0x00 unknown dialplan => prepend unknown prefix digits */
11010       snprintf(buf, size, "%s%s", pri->unknownprefix, number);
11011       break;
11012    default:          /* other Q.931 dialplan => don't twiddle with callingnum */
11013       snprintf(buf, size, "%s", number);
11014       break;
11015    }
11016 }
11017 
11018 static int dahdi_setlaw(int dfd, int law)
11019 {
11020    int res;
11021    res = ioctl(dfd, DAHDI_SETLAW, &law);
11022    if (res)
11023       return res;
11024    return 0;
11025 }
11026 
11027 static void *pri_dchannel(void *vpri)
11028 {
11029    struct dahdi_pri *pri = vpri;
11030    pri_event *e;
11031    struct pollfd fds[NUM_DCHANS];
11032    int res;
11033    int chanpos = 0, origchanpos = 0;
11034    int x;
11035    int haveidles;
11036    int activeidles;
11037    int nextidle = -1;
11038    struct ast_channel *c;
11039    struct timeval tv, lowest, *next;
11040    struct timeval lastidle = { 0, 0 };
11041    int doidling=0;
11042    char *cc;
11043    char idlen[80];
11044    struct ast_channel *idle;
11045    pthread_t p;
11046    time_t t;
11047    int i, which=-1;
11048    int numdchans;
11049    int cause=0;
11050    struct dahdi_pvt *crv;
11051    pthread_t threadid;
11052    pthread_attr_t attr;
11053    char ani2str[6];
11054    char plancallingnum[256];
11055    char plancallingani[256];
11056    char calledtonstr[10];
11057    unsigned int len;
11058 
11059    pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
11060 
11061    gettimeofday(&lastidle, NULL);
11062    if (!ast_strlen_zero(pri->idledial) && !ast_strlen_zero(pri->idleext)) {
11063       /* Need to do idle dialing, check to be sure though */
11064       cc = strchr(pri->idleext, '@');
11065       if (cc) {
11066          *cc = '\0';
11067          cc++;
11068          ast_copy_string(pri->idlecontext, cc, sizeof(pri->idlecontext));
11069 #if 0
11070          /* Extensions may not be loaded yet */
11071          if (!ast_exists_extension(NULL, pri->idlecontext, pri->idleext, 1, NULL))
11072             ast_log(LOG_WARNING, "Extension '%s @ %s' does not exist\n", pri->idleext, pri->idlecontext);
11073          else
11074 #endif
11075             doidling = 1;
11076       } else
11077          ast_log(LOG_WARNING, "Idle dial string '%s' lacks '@context'\n", pri->idleext);
11078    }
11079    for (;;) {
11080       for (i = 0; i < NUM_DCHANS; i++) {
11081          if (!pri->dchannels[i])
11082             break;
11083          fds[i].fd = pri->fds[i];
11084          fds[i].events = POLLIN | POLLPRI;
11085          fds[i].revents = 0;
11086       }
11087       numdchans = i;
11088       time(&t);
11089       ast_mutex_lock(&pri->lock);
11090       if (pri->switchtype != PRI_SWITCH_GR303_TMC && (pri->resetinterval > 0)) {
11091          if (pri->resetting && pri_is_up(pri)) {
11092             if (pri->resetpos < 0) {
11093                pri_check_restart(pri);
11094             }
11095          } else {
11096             if (!pri->resetting  && (t - pri->lastreset) >= pri->resetinterval) {
11097                pri->resetting = 1;
11098                pri->resetpos = -1;
11099             }
11100          }
11101       }
11102       /* Look for any idle channels if appropriate */
11103       if (doidling && pri_is_up(pri)) {
11104          nextidle = -1;
11105          haveidles = 0;
11106          activeidles = 0;
11107          for (x = pri->numchans; x >= 0; x--) {
11108             if (pri->pvts[x]) {
11109                if (sig_pri_is_chan_available(pri->pvts[x])) {
11110                   if (haveidles < pri->minunused) {
11111                      haveidles++;
11112                   } else {
11113                      nextidle = x;
11114                      break;
11115                   }
11116                } else if (pri->pvts[x]->owner && pri->pvts[x]->isidlecall) {
11117                   activeidles++;
11118                }
11119             }
11120          }
11121          if (nextidle > -1) {
11122             if (ast_tvdiff_ms(ast_tvnow(), lastidle) > 1000) {
11123                /* Don't create a new idle call more than once per second */
11124                snprintf(idlen, sizeof(idlen), "%d/%s", pri->pvts[nextidle]->channel, pri->idledial);
11125                /*
11126                 * Release the PRI lock while we create the channel so other
11127                 * threads can send D channel messages.
11128                 */
11129                ast_mutex_unlock(&pri->lock);
11130                idle = dahdi_request(dahdi_chan_name, AST_FORMAT_ULAW, idlen, &cause);
11131                ast_mutex_lock(&pri->lock);
11132                if (idle) {
11133                   pri->pvts[nextidle]->isidlecall = 1;
11134                   if (ast_pthread_create_background(&p, NULL, do_idle_thread, idle)) {
11135                      ast_log(LOG_WARNING, "Unable to start new thread for idle channel '%s'\n", idle->name);
11136                      ast_mutex_unlock(&pri->lock);
11137                      ast_hangup(idle);
11138                      ast_mutex_lock(&pri->lock);
11139                   }
11140                } else {
11141                   ast_log(LOG_WARNING, "Unable to request channel 'DAHDI/%s' for idle call\n", idlen);
11142                }
11143                gettimeofday(&lastidle, NULL);
11144             }
11145          } else if ((haveidles < pri->minunused) &&
11146                (activeidles > pri->minidle)) {
11147             /* Mark something for hangup if there is something 
11148                that can be hungup */
11149             for (x = pri->numchans; x >= 0; x--) {
11150                /* find a candidate channel */
11151                if (pri->pvts[x] && pri->pvts[x]->owner && pri->pvts[x]->isidlecall) {
11152                   pri->pvts[x]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
11153                   haveidles++;
11154                   /* Stop if we have enough idle channels or
11155                     can't spare any more active idle ones */
11156                   if ((haveidles >= pri->minunused) ||
11157                       (activeidles <= pri->minidle))
11158                      break;
11159                } 
11160             }
11161          }
11162       }
11163       /* Start with reasonable max */
11164       lowest = ast_tv(60, 0);
11165       for (i = 0; i < NUM_DCHANS; i++) {
11166          /* Find lowest available d-channel */
11167          if (!pri->dchannels[i])
11168             break;
11169          if ((next = pri_schedule_next(pri->dchans[i]))) {
11170             /* We need relative time here */
11171             tv = ast_tvsub(*next, ast_tvnow());
11172             if (tv.tv_sec < 0) {
11173                tv = ast_tv(0,0);
11174             }
11175             if (doidling || pri->resetting) {
11176                if (tv.tv_sec > 1) {
11177                   tv = ast_tv(1, 0);
11178                }
11179             } else {
11180                if (tv.tv_sec > 60) {
11181                   tv = ast_tv(60, 0);
11182                }
11183             }
11184          } else if (doidling || pri->resetting) {
11185             /* Make sure we stop at least once per second if we're
11186                monitoring idle channels */
11187             tv = ast_tv(1,0);
11188          } else {
11189             /* Don't poll for more than 60 seconds */
11190             tv = ast_tv(60, 0);
11191          }
11192          if (!i || ast_tvcmp(tv, lowest) < 0) {
11193             lowest = tv;
11194          }
11195       }
11196       ast_mutex_unlock(&pri->lock);
11197 
11198       pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
11199       pthread_testcancel();
11200       e = NULL;
11201       res = poll(fds, numdchans, lowest.tv_sec * 1000 + lowest.tv_usec / 1000);
11202       pthread_testcancel();
11203       pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
11204 
11205       ast_mutex_lock(&pri->lock);
11206       if (!res) {
11207          for (which = 0; which < NUM_DCHANS; which++) {
11208             if (!pri->dchans[which])
11209                break;
11210             /* Just a timeout, run the scheduler */
11211             e = pri_schedule_run(pri->dchans[which]);
11212             if (e)
11213                break;
11214          }
11215       } else if (res > -1) {
11216          for (which = 0; which < NUM_DCHANS; which++) {
11217             if (!pri->dchans[which])
11218                break;
11219             if (fds[which].revents & POLLPRI) {
11220                /* Check for an event */
11221                x = 0;
11222                res = ioctl(pri->fds[which], DAHDI_GETEVENT, &x);
11223                if (x) 
11224                   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);
11225                /* Keep track of alarm state */  
11226                if (x == DAHDI_EVENT_ALARM) {
11227                   pri->dchanavail[which] &= ~(DCHAN_NOTINALARM | DCHAN_UP);
11228                   pri_find_dchan(pri);
11229                } else if (x == DAHDI_EVENT_NOALARM) {
11230                   pri->dchanavail[which] |= DCHAN_NOTINALARM;
11231                   pri_restart(pri->dchans[which]);
11232                }
11233             
11234                if (option_debug)
11235                   ast_log(LOG_DEBUG, "Got event %s (%d) on D-channel for span %d\n", event2str(x), x, pri->span);
11236             } else if (fds[which].revents & POLLIN) {
11237                e = pri_check_event(pri->dchans[which]);
11238             }
11239             if (e)
11240                break;
11241          }
11242       } else if (errno != EINTR)
11243          ast_log(LOG_WARNING, "pri_event returned error %d (%s)\n", errno, strerror(errno));
11244 
11245       if (e) {
11246          if (pri->debug)
11247             pri_dump_event(pri->dchans[which], e);
11248 
11249          if (e->e != PRI_EVENT_DCHAN_DOWN) {
11250             if (!(pri->dchanavail[which] & DCHAN_UP)) {
11251                if (option_verbose > 1) 
11252                   ast_verbose(VERBOSE_PREFIX_2 "%s D-Channel on span %d up\n", pri_order(which), pri->span);
11253             }
11254             pri->dchanavail[which] |= DCHAN_UP;
11255          } else {
11256             if (pri->dchanavail[which] & DCHAN_UP) {
11257                if (option_verbose > 1) 
11258                   ast_verbose(VERBOSE_PREFIX_2 "%s D-Channel on span %d down\n", pri_order(which), pri->span);
11259             }
11260             pri->dchanavail[which] &= ~DCHAN_UP;
11261          }
11262 
11263          if ((e->e != PRI_EVENT_DCHAN_UP) && (e->e != PRI_EVENT_DCHAN_DOWN) && (pri->pri != pri->dchans[which]))
11264             /* Must be an NFAS group that has the secondary dchan active */
11265             pri->pri = pri->dchans[which];
11266 
11267          switch (e->e) {
11268          case PRI_EVENT_DCHAN_UP:
11269             pri->no_d_channels = 0;
11270             if (!pri->pri) pri_find_dchan(pri);
11271 
11272             /* Note presense of D-channel */
11273             time(&pri->lastreset);
11274 
11275             /* Restart in 5 seconds */
11276             if (pri->resetinterval > -1) {
11277                pri->lastreset -= pri->resetinterval;
11278                pri->lastreset += 5;
11279             }
11280             /* Take the channels from inalarm condition */
11281             pri->resetting = 0;
11282             for (i = 0; i < pri->numchans; i++) {
11283                if (pri->pvts[i]) {
11284                   pri->pvts[i]->inalarm = 0;
11285                   pri->pvts[i]->resetting = 0;
11286                }
11287             }
11288             break;
11289          case PRI_EVENT_DCHAN_DOWN:
11290             pri_find_dchan(pri);
11291             if (!pri_is_up(pri)) {
11292                /* Hangup active channels and put them in alarm mode */
11293                pri->resetting = 0;
11294                for (i = 0; i < pri->numchans; i++) {
11295                   struct dahdi_pvt *p = pri->pvts[i];
11296                   if (p) {
11297                      if (!p->pri || !p->pri->pri || pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0) {
11298                         /* T309 is not enabled : destroy calls when alarm occurs */
11299                         if (p->call) {
11300                            if (p->pri && p->pri->pri) {
11301                               pri_destroycall(p->pri->pri, p->call);
11302                               p->call = NULL;
11303                            } else
11304                               ast_log(LOG_WARNING, "The PRI Call has not been destroyed\n");
11305                         }
11306                         if (p->realcall) {
11307                            pri_hangup_all(p->realcall, pri);
11308                         } else if (p->owner)
11309                            p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
11310                      }
11311                      p->inalarm = 1;
11312                      p->resetting = 0;
11313                   }
11314                }
11315             }
11316             break;
11317          case PRI_EVENT_RESTART:
11318             if (e->restart.channel > -1 && PRI_CHANNEL(e->ring.channel) != 0xFF) {
11319                chanpos = pri_find_principle(pri, e->restart.channel);
11320                if (chanpos < 0)
11321                   ast_log(LOG_WARNING,
11322                      "Span %d: Restart requested on odd/unavailable channel number %d/%d\n",
11323                      pri->span, PRI_SPAN(e->restart.channel),
11324                      PRI_CHANNEL(e->restart.channel));
11325                else {
11326                   if (option_verbose > 2)
11327                      ast_verbose(VERBOSE_PREFIX_3 "Span %d: Channel %d/%d restarted\n",
11328                         pri->span, PRI_SPAN(e->restart.channel),
11329                         PRI_CHANNEL(e->restart.channel));
11330                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
11331                   if (pri->pvts[chanpos]->call) {
11332                      pri_destroycall(pri->pri, pri->pvts[chanpos]->call);
11333                      pri->pvts[chanpos]->call = NULL;
11334                   }
11335                   /* Force soft hangup if appropriate */
11336                   if (pri->pvts[chanpos]->realcall) 
11337                      pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
11338                   else if (pri->pvts[chanpos]->owner)
11339                      pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
11340                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
11341                }
11342             } else {
11343                if (option_verbose > 2)
11344                   ast_verbose(VERBOSE_PREFIX_2 "Restart requested on entire span %d\n",
11345                      pri->span);
11346                for (x = 0; x < pri->numchans; x++)
11347                   if (pri->pvts[x]) {
11348                      ast_mutex_lock(&pri->pvts[x]->lock);
11349                      if (pri->pvts[x]->call) {
11350                         pri_destroycall(pri->pri, pri->pvts[x]->call);
11351                         pri->pvts[x]->call = NULL;
11352                      }
11353                      if (pri->pvts[x]->realcall) 
11354                         pri_hangup_all(pri->pvts[x]->realcall, pri);
11355                      else if (pri->pvts[x]->owner)
11356                         pri->pvts[x]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
11357                      ast_mutex_unlock(&pri->pvts[x]->lock);
11358                   }
11359             }
11360             break;
11361          case PRI_EVENT_KEYPAD_DIGIT:
11362             chanpos = pri_find_principle_by_call(pri, e->digit.call);
11363             if (chanpos < 0) {
11364                ast_log(LOG_WARNING,
11365                   "Span %d: Received keypad digits for unknown call.\n", pri->span);
11366                break;
11367             }
11368             ast_mutex_lock(&pri->pvts[chanpos]->lock);
11369             /* queue DTMF frame if the PBX for this call was already started (we're forwarding KEYPAD_DIGITs further on */
11370             if ((pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)
11371                && pri->pvts[chanpos]->owner) {
11372                /* how to do that */
11373                int digitlen = strlen(e->digit.digits);
11374                char digit;
11375                int i;
11376                for (i = 0; i < digitlen; i++) {
11377                   digit = e->digit.digits[i];
11378                   {
11379                      struct ast_frame f = { AST_FRAME_DTMF, digit, };
11380                      dahdi_queue_frame(pri->pvts[chanpos], &f, pri);
11381                   }
11382                }
11383             }
11384             ast_mutex_unlock(&pri->pvts[chanpos]->lock);
11385             break;
11386             
11387          case PRI_EVENT_INFO_RECEIVED:
11388             chanpos = pri_find_principle_by_call(pri, e->ring.call);
11389             if (chanpos < 0) {
11390                ast_log(LOG_WARNING,
11391                   "Span %d: Received INFORMATION for unknown call.\n", pri->span);
11392                break;
11393             }
11394             ast_mutex_lock(&pri->pvts[chanpos]->lock);
11395             /* queue DTMF frame if the PBX for this call was already started (we're forwarding INFORMATION further on */
11396             if ((pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)
11397                && pri->pvts[chanpos]->owner) {
11398                /* how to do that */
11399                int digitlen = strlen(e->ring.callednum);
11400                char digit;
11401                int i;
11402                for (i = 0; i < digitlen; i++) {
11403                   digit = e->ring.callednum[i];
11404                   {
11405                      struct ast_frame f = { AST_FRAME_DTMF, digit, };
11406                      dahdi_queue_frame(pri->pvts[chanpos], &f, pri);
11407                   }
11408                }
11409             }
11410             ast_mutex_unlock(&pri->pvts[chanpos]->lock);
11411             break;
11412          case PRI_EVENT_RING:
11413             crv = NULL;
11414             chanpos = pri_find_principle_by_call(pri, e->ring.call);
11415             if (-1 < chanpos) {
11416                /* Libpri has already filtered out duplicate SETUPs. */
11417                ast_log(LOG_WARNING,
11418                   "Span %d: Got SETUP with duplicate call ptr.  Dropping call.\n",
11419                   pri->span);
11420                pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_NORMAL_TEMPORARY_FAILURE);
11421                break;
11422             }
11423             if (e->ring.channel == -1 || PRI_CHANNEL(e->ring.channel) == 0xFF) {
11424                /* Any channel requested. */
11425                chanpos = pri_find_empty_chan(pri, 1, -1);
11426             } else if (PRI_CHANNEL(e->ring.channel) == 0x00) {
11427                /* No channel specified. */
11428                {
11429                   /* We will not accept incoming call waiting calls. */
11430                   pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_INCOMPATIBLE_DESTINATION);
11431                   break;
11432                }
11433             } else {
11434                /* A channel is specified. */
11435                chanpos = pri_find_principle(pri, e->ring.channel);
11436                ast_log(LOG_DEBUG, "chanpos %d channel %d\n", chanpos, PRI_CHANNEL(e->ring.channel));
11437                origchanpos = chanpos;
11438                if (chanpos < 0) {
11439                   ast_log(LOG_WARNING,
11440                      "Span %d: SETUP on unconfigured channel %d/%d\n",
11441                      pri->span, PRI_SPAN(e->ring.channel),
11442                      PRI_CHANNEL(e->ring.channel));
11443                } else if (!sig_pri_is_chan_available(pri->pvts[chanpos])) {
11444                   /* This is where we handle initial glare */
11445                   ast_log(LOG_NOTICE,
11446                      "Span %d: SETUP requested unavailable channel %d/%d.  Attempting to renegotiate.\n",
11447                      pri->span, PRI_SPAN(e->ring.channel),
11448                      PRI_CHANNEL(e->ring.channel));
11449                   chanpos = -1;
11450                } 
11451 #if defined(ALWAYS_PICK_CHANNEL)
11452                if (e->ring.flexible) {
11453                   chanpos = -1;
11454                }
11455 #endif   /* defined(ALWAYS_PICK_CHANNEL) */
11456                if (chanpos < 0 && e->ring.flexible) {
11457                   /* We can try to pick another channel. */
11458                   chanpos = pri_find_empty_chan(pri, 1, origchanpos);
11459                }
11460             }
11461             if (chanpos < 0) {
11462                if (e->ring.flexible) {
11463                   pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION);
11464                } else {
11465                   pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_REQUESTED_CHAN_UNAVAIL);
11466                }
11467                break;
11468             }
11469 
11470             ast_mutex_lock(&pri->pvts[chanpos]->lock);
11471             if (pri->switchtype == PRI_SWITCH_GR303_TMC) {
11472                /* Should be safe to lock CRV AFAIK while bearer is still locked */
11473                crv = pri_find_crv(pri, pri_get_crv(pri->pri, e->ring.call, NULL));
11474                if (crv)
11475                   ast_mutex_lock(&crv->lock);
11476                if (!crv || crv->owner) {
11477                   pri->pvts[chanpos]->call = NULL;
11478                   if (crv) {
11479                      if (crv->owner)
11480                         crv->owner->_softhangup |= AST_SOFTHANGUP_DEV;
11481                      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);
11482                   } else
11483                      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);
11484                   pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_INVALID_CALL_REFERENCE);
11485                   if (crv)
11486                      ast_mutex_unlock(&crv->lock);
11487                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
11488                   break;
11489                }
11490             }
11491 
11492             /* Mark channel as in use so noone else will steal it. */
11493             pri->pvts[chanpos]->call = e->ring.call;
11494 
11495             apply_plan_to_number(plancallingnum, sizeof(plancallingnum), pri, e->ring.callingnum, e->ring.callingplan);
11496             if (pri->pvts[chanpos]->use_callerid) {
11497                ast_shrink_phone_number(plancallingnum);
11498                ast_copy_string(pri->pvts[chanpos]->cid_num, plancallingnum, sizeof(pri->pvts[chanpos]->cid_num));
11499 #ifdef PRI_ANI
11500                if (!ast_strlen_zero(e->ring.callingani)) {
11501                   apply_plan_to_number(plancallingani, sizeof(plancallingani), pri, e->ring.callingani, e->ring.callingplanani);
11502                   ast_shrink_phone_number(plancallingani);
11503                   ast_copy_string(pri->pvts[chanpos]->cid_ani, plancallingani, sizeof(pri->pvts[chanpos]->cid_ani));
11504                } else {
11505                   pri->pvts[chanpos]->cid_ani[0] = '\0';
11506                }
11507 #endif
11508                ast_copy_string(pri->pvts[chanpos]->cid_name, e->ring.callingname, sizeof(pri->pvts[chanpos]->cid_name));
11509                pri->pvts[chanpos]->cid_ton = e->ring.callingplan; /* this is the callingplan (TON/NPI), e->ring.callingplan>>4 would be the TON */
11510             } else {
11511                pri->pvts[chanpos]->cid_num[0] = '\0';
11512                pri->pvts[chanpos]->cid_ani[0] = '\0';
11513                pri->pvts[chanpos]->cid_name[0] = '\0';
11514                pri->pvts[chanpos]->cid_ton = 0;
11515             }
11516             apply_plan_to_number(pri->pvts[chanpos]->rdnis, sizeof(pri->pvts[chanpos]->rdnis), pri,
11517                       e->ring.redirectingnum, e->ring.callingplanrdnis);
11518 
11519             /* Set DNID on all incoming calls -- even immediate */
11520             ast_copy_string(pri->pvts[chanpos]->dnid, e->ring.callednum, sizeof(pri->pvts[chanpos]->dnid));
11521 
11522             /* If immediate=yes go to s|1 */
11523             if (pri->pvts[chanpos]->immediate) {
11524                if (option_verbose > 2)
11525                   ast_verbose(VERBOSE_PREFIX_3 "Going to extension s|1 because of immediate=yes\n");
11526                pri->pvts[chanpos]->exten[0] = 's';
11527                pri->pvts[chanpos]->exten[1] = '\0';
11528             }
11529             /* Get called number */
11530             else if (!ast_strlen_zero(e->ring.callednum)) {
11531                ast_copy_string(pri->pvts[chanpos]->exten, e->ring.callednum, sizeof(pri->pvts[chanpos]->exten));
11532             } else if (pri->overlapdial)
11533                pri->pvts[chanpos]->exten[0] = '\0';
11534             else {
11535                /* Some PRI circuits are set up to send _no_ digits.  Handle them as 's'. */
11536                pri->pvts[chanpos]->exten[0] = 's';
11537                pri->pvts[chanpos]->exten[1] = '\0';
11538             }
11539             /* No number yet, but received "sending complete"? */
11540             if (e->ring.complete && (ast_strlen_zero(e->ring.callednum))) {
11541                if (option_verbose > 2)
11542                   ast_verbose(VERBOSE_PREFIX_3 "Going to extension s|1 because of Complete received\n");
11543                pri->pvts[chanpos]->exten[0] = 's';
11544                pri->pvts[chanpos]->exten[1] = '\0';
11545             }
11546 
11547             /* Make sure extension exists (or in overlap dial mode, can exist) */
11548             if (((pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING) && ast_canmatch_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) ||
11549                ast_exists_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) {
11550                /* Setup law */
11551                int law;
11552                if (pri->switchtype != PRI_SWITCH_GR303_TMC) {
11553                   /* Set to audio mode at this point */
11554                   law = 1;
11555                   if (ioctl(pri->pvts[chanpos]->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &law) == -1)
11556                      ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d: %s\n", pri->pvts[chanpos]->channel, law, strerror(errno));
11557                }
11558                if (e->ring.layer1 == PRI_LAYER_1_ALAW)
11559                   law = DAHDI_LAW_ALAW;
11560                else
11561                   law = DAHDI_LAW_MULAW;
11562                res = dahdi_setlaw(pri->pvts[chanpos]->subs[SUB_REAL].dfd, law);
11563                if (res < 0) 
11564                   ast_log(LOG_WARNING, "Unable to set law on channel %d\n", pri->pvts[chanpos]->channel);
11565                res = set_actual_gain(pri->pvts[chanpos]->subs[SUB_REAL].dfd, 0, pri->pvts[chanpos]->rxgain, pri->pvts[chanpos]->txgain, law);
11566                if (res < 0)
11567                   ast_log(LOG_WARNING, "Unable to set gains on channel %d\n", pri->pvts[chanpos]->channel);
11568                if (e->ring.complete || !(pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)) {
11569                   /* Just announce proceeding */
11570                   pri->pvts[chanpos]->call_level = DAHDI_CALL_LEVEL_PROCEEDING;
11571                   pri_proceeding(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 0);
11572                } else if (pri->switchtype == PRI_SWITCH_GR303_TMC) {
11573                   pri->pvts[chanpos]->call_level = DAHDI_CALL_LEVEL_CONNECT;
11574                   pri_answer(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 1);
11575                } else {
11576                   pri->pvts[chanpos]->call_level = DAHDI_CALL_LEVEL_OVERLAP;
11577                   pri_need_more_info(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 1);
11578                }
11579                /* Get the use_callingpres state */
11580                pri->pvts[chanpos]->callingpres = e->ring.callingpres;
11581             
11582                /* Start PBX */
11583                if (!e->ring.complete
11584                   && (pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)
11585                   && ast_matchmore_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) {
11586                   /*
11587                    * Release the PRI lock while we create the channel so other
11588                    * threads can send D channel messages.  We must also release
11589                    * the private lock to prevent deadlock while creating the
11590                    * channel.
11591                    */
11592                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
11593                   ast_mutex_unlock(&pri->lock);
11594                   if (crv) {
11595                      /* Set bearer and such */
11596                      pri_assign_bearer(crv, pri, pri->pvts[chanpos]);
11597                      c = dahdi_new(crv, AST_STATE_RESERVED, 0, SUB_REAL, law, e->ring.ctype);
11598                      pri->pvts[chanpos]->owner = &inuse;
11599                      ast_log(LOG_DEBUG, "Started up crv %d:%d on bearer channel %d\n", pri->trunkgroup, crv->channel, crv->bearer->channel);
11600                   } else {
11601                      c = dahdi_new(pri->pvts[chanpos], AST_STATE_RESERVED, 0, SUB_REAL, law, e->ring.ctype);
11602                   }
11603                   ast_mutex_lock(&pri->lock);
11604                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
11605                   if (c) {
11606                      if (!ast_strlen_zero(e->ring.callingsubaddr)) {
11607                         pbx_builtin_setvar_helper(c, "CALLINGSUBADDR", e->ring.callingsubaddr);
11608                      }
11609                      if (e->ring.ani2 >= 0) {
11610                         snprintf(ani2str, sizeof(ani2str), "%d", e->ring.ani2);
11611                         pbx_builtin_setvar_helper(c, "ANI2", ani2str);
11612                      }
11613 
11614 #ifdef SUPPORT_USERUSER
11615                      if (!ast_strlen_zero(e->ring.useruserinfo)) {
11616                         pbx_builtin_setvar_helper(c, "USERUSERINFO", e->ring.useruserinfo);
11617                      }
11618 #endif
11619 
11620                      snprintf(calledtonstr, sizeof(calledtonstr), "%d", e->ring.calledplan);
11621                      pbx_builtin_setvar_helper(c, "CALLEDTON", calledtonstr);
11622                      if (e->ring.redirectingreason >= 0)
11623                         pbx_builtin_setvar_helper(c, "PRIREDIRECTREASON", redirectingreason2str(e->ring.redirectingreason));
11624 
11625                      if (!pri->pvts[chanpos]->digital) {
11626                         /*
11627                          * Call has a channel.
11628                          * Indicate that we are providing dialtone.
11629                          */
11630                         pri->pvts[chanpos]->progress = 1;/* No need to send plain PROGRESS again. */
11631                         pri_progress(pri->pri, e->ring.call,
11632                            PVT_TO_CHANNEL(pri->pvts[chanpos]), 1);
11633                      }
11634                   }
11635 
11636                   pthread_attr_init(&attr);
11637                   pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
11638                   if (c && !ast_pthread_create(&threadid, &attr, ss_thread, c)) {
11639                      if (option_verbose > 2)
11640                         ast_verbose(VERBOSE_PREFIX_3 "Accepting overlap call from '%s' to '%s' on channel %d/%d, span %d\n",
11641                            plancallingnum, S_OR(pri->pvts[chanpos]->exten, "<unspecified>"),
11642                            pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
11643                   } else {
11644                      ast_log(LOG_WARNING, "Unable to start PBX on channel %d/%d, span %d\n",
11645                         pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
11646                      if (c) {
11647                         /* Avoid deadlock while destroying channel */
11648                         ast_mutex_unlock(&pri->pvts[chanpos]->lock);
11649                         ast_mutex_unlock(&pri->lock);
11650                         ast_hangup(c);
11651                         ast_mutex_lock(&pri->lock);
11652                         ast_mutex_lock(&pri->pvts[chanpos]->lock);
11653                      } else {
11654                         pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_SWITCH_CONGESTION);
11655                         pri->pvts[chanpos]->call = NULL;
11656                      }
11657                   }
11658                   pthread_attr_destroy(&attr);
11659                } else {
11660                   /*
11661                    * Release the PRI lock while we create the channel so other
11662                    * threads can send D channel messages.  We must also release
11663                    * the private lock to prevent deadlock while creating the
11664                    * channel.
11665                    */
11666                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
11667                   ast_mutex_unlock(&pri->lock);
11668                   c = dahdi_new(pri->pvts[chanpos], AST_STATE_RING, 0, SUB_REAL, law, e->ring.ctype);
11669                   ast_mutex_lock(&pri->lock);
11670                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
11671                   if (c) {
11672                      /*
11673                       * It is reasonably safe to set the following
11674                       * channel variables while the PRI and DAHDI private
11675                       * structures are locked.  The PBX has not been
11676                       * started yet and it is unlikely that any other task
11677                       * will do anything with the channel we have just
11678                       * created.
11679                       */
11680                      if (!ast_strlen_zero(e->ring.callingsubaddr)) {
11681                         pbx_builtin_setvar_helper(c, "CALLINGSUBADDR", e->ring.callingsubaddr);
11682                      }
11683                      if (e->ring.ani2 >= 0) {
11684                         snprintf(ani2str, sizeof(ani2str), "%d", e->ring.ani2);
11685                         pbx_builtin_setvar_helper(c, "ANI2", ani2str);
11686                      }
11687 
11688 #ifdef SUPPORT_USERUSER
11689                      if (!ast_strlen_zero(e->ring.useruserinfo)) {
11690                         pbx_builtin_setvar_helper(c, "USERUSERINFO", e->ring.useruserinfo);
11691                      }
11692 #endif
11693 
11694                      if (e->ring.redirectingreason >= 0)
11695                         pbx_builtin_setvar_helper(c, "PRIREDIRECTREASON", redirectingreason2str(e->ring.redirectingreason));
11696 
11697                      snprintf(calledtonstr, sizeof(calledtonstr), "%d", e->ring.calledplan);
11698                      pbx_builtin_setvar_helper(c, "CALLEDTON", calledtonstr);
11699                   }
11700                   if (c && !ast_pbx_start(c)) {
11701                      if (option_verbose > 2)
11702                         ast_verbose(VERBOSE_PREFIX_3 "Accepting call from '%s' to '%s' on channel %d/%d, span %d\n",
11703                            plancallingnum, pri->pvts[chanpos]->exten,
11704                            pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
11705 
11706                      dahdi_enable_ec(pri->pvts[chanpos]);
11707                   } else {
11708                      ast_log(LOG_WARNING, "Unable to start PBX on channel %d/%d, span %d\n",
11709                         pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
11710                      if (c) {
11711                         /* Avoid deadlock while destroying channel */
11712                         ast_mutex_unlock(&pri->pvts[chanpos]->lock);
11713                         ast_mutex_unlock(&pri->lock);
11714                         ast_hangup(c);
11715                         ast_mutex_lock(&pri->lock);
11716                         ast_mutex_lock(&pri->pvts[chanpos]->lock);
11717                      } else {
11718                         pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_SWITCH_CONGESTION);
11719                         pri->pvts[chanpos]->call = NULL;
11720                      }
11721                   }
11722                }
11723             } else {
11724                if (option_verbose > 2)
11725                   ast_verbose(VERBOSE_PREFIX_3 "Span %d: Extension %s@%s does not exist.  Rejecting call from '%s'.\n",
11726                      pri->span, pri->pvts[chanpos]->exten, pri->pvts[chanpos]->context,
11727                      pri->pvts[chanpos]->cid_num);
11728                pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_UNALLOCATED);
11729                pri->pvts[chanpos]->call = NULL;
11730                pri->pvts[chanpos]->exten[0] = '\0';
11731             }
11732             if (crv)
11733                ast_mutex_unlock(&crv->lock);
11734             ast_mutex_unlock(&pri->pvts[chanpos]->lock);
11735             break;
11736          case PRI_EVENT_RINGING:
11737             chanpos = pri_find_fixup_principle(pri, e->ringing.channel,
11738                e->ringing.call);
11739             if (chanpos < 0) {
11740                break;
11741             }
11742             ast_mutex_lock(&pri->pvts[chanpos]->lock);
11743             if (ast_strlen_zero(pri->pvts[chanpos]->dop.dialstr)) {
11744                dahdi_enable_ec(pri->pvts[chanpos]);
11745                pri->pvts[chanpos]->subs[SUB_REAL].needringing = 1;
11746                if (pri->pvts[chanpos]->call_level < DAHDI_CALL_LEVEL_ALERTING) {
11747                   pri->pvts[chanpos]->call_level = DAHDI_CALL_LEVEL_ALERTING;
11748                }
11749             } else
11750                ast_log(LOG_DEBUG, "Deferring ringing notification because of extra digits to dial...\n");
11751             if (
11752 #ifdef PRI_PROGRESS_MASK
11753                e->ringing.progressmask & PRI_PROG_INBAND_AVAILABLE
11754 #else
11755                e->ringing.progress == 8
11756 #endif
11757                ) {
11758                /* Now we can do call progress detection */
11759                if (pri->pvts[chanpos]->dsp && pri->pvts[chanpos]->dsp_features) {
11760                   /* RINGING detection isn't required because we got ALERTING signal */
11761                   ast_dsp_set_features(pri->pvts[chanpos]->dsp, pri->pvts[chanpos]->dsp_features & ~DSP_PROGRESS_RINGING);
11762                   pri->pvts[chanpos]->dsp_features = 0;
11763                }
11764             }
11765 
11766 #ifdef SUPPORT_USERUSER
11767             if (!ast_strlen_zero(e->ringing.useruserinfo)) {
11768                struct ast_channel *owner = pri->pvts[chanpos]->owner;
11769                ast_mutex_unlock(&pri->pvts[chanpos]->lock);
11770                pbx_builtin_setvar_helper(owner, "USERUSERINFO", e->ringing.useruserinfo);
11771                ast_mutex_lock(&pri->pvts[chanpos]->lock);
11772             }
11773 #endif
11774 
11775             ast_mutex_unlock(&pri->pvts[chanpos]->lock);
11776             break;
11777          case PRI_EVENT_PROGRESS:
11778             chanpos = pri_find_fixup_principle(pri, e->proceeding.channel,
11779                e->proceeding.call);
11780             if (chanpos < 0) {
11781                break;
11782             }
11783             if ((!pri->pvts[chanpos]->progress)
11784 #ifdef PRI_PROGRESS_MASK
11785                || (e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE)
11786 #else
11787                || (e->proceeding.progress == 8)
11788 #endif
11789                ) {
11790                struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, };
11791 
11792                if (e->proceeding.cause > -1) {
11793                   if (option_verbose > 2)
11794                      ast_verbose(VERBOSE_PREFIX_3 "PROGRESS with cause code %d received\n", e->proceeding.cause);
11795 
11796                   /* Work around broken, out of spec USER_BUSY cause in a progress message */
11797                   if (e->proceeding.cause == AST_CAUSE_USER_BUSY) {
11798                      if (pri->pvts[chanpos]->owner) {
11799                         if (option_verbose > 2)
11800                            ast_verbose(VERBOSE_PREFIX_3 "PROGRESS with 'user busy' received, signaling AST_CONTROL_BUSY instead of AST_CONTROL_PROGRESS\n");
11801 
11802                         pri->pvts[chanpos]->owner->hangupcause = e->proceeding.cause;
11803                         f.subclass = AST_CONTROL_BUSY;
11804                      }
11805                   }
11806                }
11807 
11808                ast_mutex_lock(&pri->pvts[chanpos]->lock);
11809                ast_log(LOG_DEBUG, "Queuing frame from PRI_EVENT_PROGRESS on channel %d/%d span %d\n",
11810                   pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset,pri->span);
11811                dahdi_queue_frame(pri->pvts[chanpos], &f, pri);
11812                if (
11813 #ifdef PRI_PROGRESS_MASK
11814                   e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE
11815 #else
11816                   e->proceeding.progress == 8
11817 #endif
11818                   ) {
11819                   /* Now we can do call progress detection */
11820                   if (pri->pvts[chanpos]->dsp && pri->pvts[chanpos]->dsp_features) {
11821                      ast_dsp_set_features(pri->pvts[chanpos]->dsp, pri->pvts[chanpos]->dsp_features);
11822                      pri->pvts[chanpos]->dsp_features = 0;
11823                   }
11824                   /* Bring voice path up */
11825                   f.subclass = AST_CONTROL_PROGRESS;
11826                   dahdi_queue_frame(pri->pvts[chanpos], &f, pri);
11827                }
11828                pri->pvts[chanpos]->progress = 1;
11829                pri->pvts[chanpos]->dialing = 0;
11830                ast_mutex_unlock(&pri->pvts[chanpos]->lock);
11831             }
11832             break;
11833          case PRI_EVENT_PROCEEDING:
11834             chanpos = pri_find_fixup_principle(pri, e->proceeding.channel,
11835                e->proceeding.call);
11836             if (chanpos < 0) {
11837                break;
11838             }
11839             ast_mutex_lock(&pri->pvts[chanpos]->lock);
11840             if (pri->pvts[chanpos]->call_level < DAHDI_CALL_LEVEL_PROCEEDING) {
11841                struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_PROCEEDING, };
11842 
11843                pri->pvts[chanpos]->call_level = DAHDI_CALL_LEVEL_PROCEEDING;
11844                ast_log(LOG_DEBUG, "Queuing frame from PRI_EVENT_PROCEEDING on channel %d/%d span %d\n",
11845                   pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset,pri->span);
11846                dahdi_queue_frame(pri->pvts[chanpos], &f, pri);
11847                if (
11848 #ifdef PRI_PROGRESS_MASK
11849                   e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE
11850 #else
11851                   e->proceeding.progress == 8
11852 #endif
11853                   ) {
11854                   /* Now we can do call progress detection */
11855                   if (pri->pvts[chanpos]->dsp && pri->pvts[chanpos]->dsp_features) {
11856                      ast_dsp_set_features(pri->pvts[chanpos]->dsp, pri->pvts[chanpos]->dsp_features);
11857                      pri->pvts[chanpos]->dsp_features = 0;
11858                   }
11859                   /* Bring voice path up */
11860                   f.subclass = AST_CONTROL_PROGRESS;
11861                   dahdi_queue_frame(pri->pvts[chanpos], &f, pri);
11862                }
11863                pri->pvts[chanpos]->dialing = 0;
11864             }
11865             ast_mutex_unlock(&pri->pvts[chanpos]->lock);
11866             break;
11867          case PRI_EVENT_FACNAME:
11868             chanpos = pri_find_principle_by_call(pri, e->facname.call);
11869             if (chanpos < 0) {
11870                ast_log(LOG_WARNING, "Span %d: Received facility for unknown call.\n",
11871                   pri->span);
11872                break;
11873             }
11874             if (pri->pvts[chanpos]->use_callerid) {
11875                /* Re-use *69 field for PRI */
11876                ast_mutex_lock(&pri->pvts[chanpos]->lock);
11877                ast_copy_string(pri->pvts[chanpos]->lastcid_num, e->facname.callingnum, sizeof(pri->pvts[chanpos]->lastcid_num));
11878                ast_copy_string(pri->pvts[chanpos]->lastcid_name, e->facname.callingname, sizeof(pri->pvts[chanpos]->lastcid_name));
11879                pri->pvts[chanpos]->subs[SUB_REAL].needcallerid = 1;
11880                dahdi_enable_ec(pri->pvts[chanpos]);
11881                ast_mutex_unlock(&pri->pvts[chanpos]->lock);
11882             }
11883             break;            
11884          case PRI_EVENT_ANSWER:
11885             chanpos = pri_find_fixup_principle(pri, e->answer.channel, e->answer.call);
11886             if (chanpos < 0) {
11887                break;
11888             }
11889             ast_mutex_lock(&pri->pvts[chanpos]->lock);
11890             /* Now we can do call progress detection */
11891 
11892             /* We changed this so it turns on the DSP no matter what... progress or no progress.
11893              * By this time, we need DTMF detection and other features that were previously disabled
11894              * -- Matt F */
11895             if (pri->pvts[chanpos]->dsp && pri->pvts[chanpos]->dsp_features) {
11896                ast_dsp_set_features(pri->pvts[chanpos]->dsp, pri->pvts[chanpos]->dsp_features);
11897                pri->pvts[chanpos]->dsp_features = 0;
11898             }
11899             if (pri->pvts[chanpos]->realcall && (pri->pvts[chanpos]->realcall->sig == SIG_FXSKS)) {
11900                ast_log(LOG_DEBUG, "Starting up GR-303 trunk now that we got CONNECT...\n");
11901                x = DAHDI_START;
11902                res = ioctl(pri->pvts[chanpos]->subs[SUB_REAL].dfd, DAHDI_HOOK, &x);
11903                if (res < 0) {
11904                   if (errno != EINPROGRESS) {
11905                      ast_log(LOG_WARNING, "Unable to start channel: %s\n", strerror(errno));
11906                   }
11907                }
11908             } else if (!ast_strlen_zero(pri->pvts[chanpos]->dop.dialstr)) {
11909                pri->pvts[chanpos]->dialing = 1;
11910                /* Send any "w" waited stuff */
11911                res = ioctl(pri->pvts[chanpos]->subs[SUB_REAL].dfd, DAHDI_DIAL, &pri->pvts[chanpos]->dop);
11912                if (res < 0) {
11913                   ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d: %s\n", pri->pvts[chanpos]->channel, strerror(errno));
11914                   pri->pvts[chanpos]->dop.dialstr[0] = '\0';
11915                } else
11916                   ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", pri->pvts[chanpos]->dop.dialstr);
11917                pri->pvts[chanpos]->dop.dialstr[0] = '\0';
11918             } else if (pri->pvts[chanpos]->confirmanswer) {
11919                ast_log(LOG_DEBUG, "Waiting on answer confirmation on channel %d!\n", pri->pvts[chanpos]->channel);
11920             } else {
11921                pri->pvts[chanpos]->dialing = 0;
11922                if (pri->pvts[chanpos]->call_level < DAHDI_CALL_LEVEL_CONNECT) {
11923                   pri->pvts[chanpos]->call_level = DAHDI_CALL_LEVEL_CONNECT;
11924                }
11925                pri->pvts[chanpos]->subs[SUB_REAL].needanswer =1;
11926                /* Enable echo cancellation if it's not on already */
11927                dahdi_enable_ec(pri->pvts[chanpos]);
11928             }
11929 
11930 #ifdef SUPPORT_USERUSER
11931             if (!ast_strlen_zero(e->answer.useruserinfo)) {
11932                struct ast_channel *owner = pri->pvts[chanpos]->owner;
11933                ast_mutex_unlock(&pri->pvts[chanpos]->lock);
11934                pbx_builtin_setvar_helper(owner, "USERUSERINFO", e->answer.useruserinfo);
11935                ast_mutex_lock(&pri->pvts[chanpos]->lock);
11936             }
11937 #endif
11938 
11939             ast_mutex_unlock(&pri->pvts[chanpos]->lock);
11940             break;            
11941          case PRI_EVENT_HANGUP:
11942             chanpos = pri_find_principle_by_call(pri, e->hangup.call);
11943             if (chanpos < 0) {
11944                /*
11945                 * Continue hanging up the call even though
11946                 * we do not remember it (if we ever did).
11947                 */
11948                pri_hangup(pri->pri, e->hangup.call, e->hangup.cause);
11949                break;
11950             }
11951             ast_mutex_lock(&pri->pvts[chanpos]->lock);
11952             switch (e->hangup.cause) {
11953             case PRI_CAUSE_INVALID_CALL_REFERENCE:
11954                /*
11955                 * The peer denies the existence of this call so we must
11956                 * continue hanging it up and forget about it.
11957                 */
11958                pri_hangup(pri->pri, e->hangup.call, e->hangup.cause);
11959                pri->pvts[chanpos]->call = NULL;
11960                break;
11961             default:
11962                break;
11963             }
11964             if (!pri->pvts[chanpos]->alreadyhungup) {
11965                /* we're calling here dahdi_hangup so once we get there we need to clear p->call after calling pri_hangup */
11966                pri->pvts[chanpos]->alreadyhungup = 1;
11967                if (pri->pvts[chanpos]->realcall)
11968                   pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
11969                else if (pri->pvts[chanpos]->owner) {
11970                   /* Queue a BUSY instead of a hangup if our cause is appropriate */
11971                   pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause;
11972                   switch (pri->pvts[chanpos]->owner->_state) {
11973                   case AST_STATE_BUSY:
11974                   case AST_STATE_UP:
11975                      pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
11976                      break;
11977                   default:
11978                      if (!pri->pvts[chanpos]->outgoing) {
11979                         /*
11980                          * The incoming call leg hung up before getting
11981                          * connected so just hangup the call.
11982                          */
11983                         pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
11984                         break;
11985                      }
11986                      switch (e->hangup.cause) {
11987                      case PRI_CAUSE_USER_BUSY:
11988                         pri->pvts[chanpos]->subs[SUB_REAL].needbusy =1;
11989                         break;
11990                      case PRI_CAUSE_CALL_REJECTED:
11991                      case PRI_CAUSE_NETWORK_OUT_OF_ORDER:
11992                      case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
11993                      case PRI_CAUSE_SWITCH_CONGESTION:
11994                      case PRI_CAUSE_DESTINATION_OUT_OF_ORDER:
11995                      case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE:
11996                         pri->pvts[chanpos]->subs[SUB_REAL].needcongestion =1;
11997                         break;
11998                      default:
11999                         pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
12000                         break;
12001                      }
12002                      break;
12003                   }
12004                } else {
12005                   /*
12006                    * Continue hanging up the call even though
12007                    * we do not have an owner.
12008                    */
12009                   pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause);
12010                   pri->pvts[chanpos]->call = NULL;
12011                }
12012                if (option_verbose > 2) 
12013                   ast_verbose(VERBOSE_PREFIX_3 "Span %d: Channel %d/%d got hangup, cause %d\n",
12014                      pri->span, pri->pvts[chanpos]->logicalspan,
12015                      pri->pvts[chanpos]->prioffset, e->hangup.cause);
12016             } else {
12017                /* Continue hanging up the call. */
12018                pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause);
12019                pri->pvts[chanpos]->call = NULL;
12020             }
12021 #if defined(FORCE_RESTART_UNAVAIL_CHANS)
12022             if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL
12023                && !pri->resetting && !pri->pvts[chanpos]->resetting) {
12024                if (option_verbose > 2)
12025                   ast_verbose(VERBOSE_PREFIX_3
12026                      "Span %d: Forcing restart of channel %d/%d since channel reported in use\n",
12027                      pri->span, pri->pvts[chanpos]->logicalspan,
12028                      pri->pvts[chanpos]->prioffset);
12029                pri->pvts[chanpos]->resetting = 1;
12030                pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos]));
12031             }
12032 #endif   /* defined(FORCE_RESTART_UNAVAIL_CHANS) */
12033             if (e->hangup.aoc_units > -1)
12034                if (option_verbose > 2)
12035                   ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d received AOC-E charging %d unit%s\n",
12036                      pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s");
12037 
12038 #ifdef SUPPORT_USERUSER
12039             if (pri->pvts[chanpos]->owner && !ast_strlen_zero(e->hangup.useruserinfo)) {
12040                struct ast_channel *owner = pri->pvts[chanpos]->owner;
12041                ast_mutex_unlock(&pri->pvts[chanpos]->lock);
12042                pbx_builtin_setvar_helper(owner, "USERUSERINFO", e->hangup.useruserinfo);
12043                ast_mutex_lock(&pri->pvts[chanpos]->lock);
12044             }
12045 #endif
12046 
12047             ast_mutex_unlock(&pri->pvts[chanpos]->lock);
12048             break;
12049 #ifndef PRI_EVENT_HANGUP_REQ
12050 #error please update libpri
12051 #endif
12052          case PRI_EVENT_HANGUP_REQ:
12053             chanpos = pri_find_principle_by_call(pri, e->hangup.call);
12054             if (chanpos < 0) {
12055                /*
12056                 * Continue hanging up the call even though
12057                 * we do not remember it (if we ever did).
12058                 */
12059                pri_hangup(pri->pri, e->hangup.call, e->hangup.cause);
12060                break;
12061             }
12062             ast_mutex_lock(&pri->pvts[chanpos]->lock);
12063             switch (e->hangup.cause) {
12064             case PRI_CAUSE_INVALID_CALL_REFERENCE:
12065                /*
12066                 * The peer denies the existence of this call so we must
12067                 * continue hanging it up and forget about it.  We should not
12068                 * get this cause here, but for completeness we will handle it
12069                 * anyway.
12070                 */
12071                pri_hangup(pri->pri, e->hangup.call, e->hangup.cause);
12072                pri->pvts[chanpos]->call = NULL;
12073                break;
12074             default:
12075                break;
12076             }
12077             if (pri->pvts[chanpos]->realcall)
12078                pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
12079             else if (pri->pvts[chanpos]->owner) {
12080                pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause;
12081                switch (pri->pvts[chanpos]->owner->_state) {
12082                case AST_STATE_BUSY:
12083                case AST_STATE_UP:
12084                   pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
12085                   break;
12086                default:
12087                   if (!pri->pvts[chanpos]->outgoing) {
12088                      /*
12089                       * The incoming call leg hung up before getting
12090                       * connected so just hangup the call.
12091                       */
12092                      pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
12093                      break;
12094                   }
12095                   switch (e->hangup.cause) {
12096                   case PRI_CAUSE_USER_BUSY:
12097                      pri->pvts[chanpos]->subs[SUB_REAL].needbusy =1;
12098                      break;
12099                   case PRI_CAUSE_CALL_REJECTED:
12100                   case PRI_CAUSE_NETWORK_OUT_OF_ORDER:
12101                   case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
12102                   case PRI_CAUSE_SWITCH_CONGESTION:
12103                   case PRI_CAUSE_DESTINATION_OUT_OF_ORDER:
12104                   case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE:
12105                      pri->pvts[chanpos]->subs[SUB_REAL].needcongestion =1;
12106                      break;
12107                   default:
12108                      pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
12109                      break;
12110                   }
12111                   break;
12112                }
12113                if (option_verbose > 2) 
12114                   ast_verbose(VERBOSE_PREFIX_3 "Span %d: Channel %d/%d got hangup request, cause %d\n",
12115                      pri->span, pri->pvts[chanpos]->logicalspan,
12116                      pri->pvts[chanpos]->prioffset, e->hangup.cause);
12117                if (e->hangup.aoc_units > -1)
12118                   if (option_verbose > 2)
12119                      ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d received AOC-E charging %d unit%s\n",
12120                         pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s");
12121             } else {
12122                /*
12123                 * Continue hanging up the call even though
12124                 * we do not have an owner.
12125                 */
12126                pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause);
12127                pri->pvts[chanpos]->call = NULL;
12128             }
12129 #if defined(FORCE_RESTART_UNAVAIL_CHANS)
12130             if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL
12131                && !pri->resetting && !pri->pvts[chanpos]->resetting) {
12132                if (option_verbose > 2)
12133                   ast_verbose(VERBOSE_PREFIX_3
12134                      "Span %d: Forcing restart of channel %d/%d since channel reported in use\n",
12135                      pri->span, pri->pvts[chanpos]->logicalspan,
12136                      pri->pvts[chanpos]->prioffset);
12137                pri->pvts[chanpos]->resetting = 1;
12138                pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos]));
12139             }
12140 #endif   /* defined(FORCE_RESTART_UNAVAIL_CHANS) */
12141 
12142 #ifdef SUPPORT_USERUSER
12143             if (!ast_strlen_zero(e->hangup.useruserinfo)) {
12144                struct ast_channel *owner = pri->pvts[chanpos]->owner;
12145                ast_mutex_unlock(&pri->pvts[chanpos]->lock);
12146                pbx_builtin_setvar_helper(owner, "USERUSERINFO", e->hangup.useruserinfo);
12147                ast_mutex_lock(&pri->pvts[chanpos]->lock);
12148             }
12149 #endif
12150 
12151             ast_mutex_unlock(&pri->pvts[chanpos]->lock);
12152             break;
12153          case PRI_EVENT_HANGUP_ACK:
12154             chanpos = pri_find_principle_by_call(pri, e->hangup.call);
12155             if (chanpos < 0) {
12156                break;
12157             }
12158             ast_mutex_lock(&pri->pvts[chanpos]->lock);
12159             pri->pvts[chanpos]->call = NULL;
12160             if (pri->pvts[chanpos]->owner) {
12161                if (option_verbose > 2) 
12162                   ast_verbose(VERBOSE_PREFIX_3 "Span %d: Channel %d/%d got hangup ACK\n",
12163                      pri->span, pri->pvts[chanpos]->logicalspan,
12164                      pri->pvts[chanpos]->prioffset);
12165             }
12166 #ifdef SUPPORT_USERUSER
12167             if (!ast_strlen_zero(e->hangup.useruserinfo)) {
12168                struct ast_channel *owner = pri->pvts[chanpos]->owner;
12169                ast_mutex_unlock(&pri->pvts[chanpos]->lock);
12170                pbx_builtin_setvar_helper(owner, "USERUSERINFO", e->hangup.useruserinfo);
12171                ast_mutex_lock(&pri->pvts[chanpos]->lock);
12172             }
12173 #endif
12174 
12175             ast_mutex_unlock(&pri->pvts[chanpos]->lock);
12176             break;
12177          case PRI_EVENT_CONFIG_ERR:
12178             ast_log(LOG_WARNING, "PRI Error on span %d: %s\n", pri->span, e->err.err);
12179             break;
12180          case PRI_EVENT_RESTART_ACK:
12181             chanpos = pri_find_principle(pri, e->restartack.channel);
12182             if (chanpos < 0) {
12183                /* Sometime switches (e.g. I421 / British Telecom) don't give us the
12184                   channel number, so we have to figure it out...  This must be why
12185                   everybody resets exactly a channel at a time. */
12186                for (x = 0; x < pri->numchans; x++) {
12187                   if (pri->pvts[x] && pri->pvts[x]->resetting) {
12188                      chanpos = x;
12189                      ast_mutex_lock(&pri->pvts[chanpos]->lock);
12190                      ast_log(LOG_DEBUG,
12191                         "Span %d: Assuming restart ack is for channel %d/%d\n",
12192                         pri->span, pri->pvts[chanpos]->logicalspan,
12193                         pri->pvts[chanpos]->prioffset);
12194                      if (pri->pvts[chanpos]->realcall)
12195                         pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
12196                      else if (pri->pvts[chanpos]->owner) {
12197                         ast_log(LOG_WARNING,
12198                            "Span %d: Got restart ack on channel %d/%d with owner\n",
12199                            pri->span, pri->pvts[chanpos]->logicalspan,
12200                            pri->pvts[chanpos]->prioffset);
12201                         pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
12202                      }
12203                      pri->pvts[chanpos]->resetting = 0;
12204                      if (option_verbose > 2)
12205                         ast_verbose(VERBOSE_PREFIX_3
12206                            "Span %d: Channel %d/%d successfully restarted\n",
12207                            pri->span, pri->pvts[chanpos]->logicalspan,
12208                            pri->pvts[chanpos]->prioffset);
12209                      ast_mutex_unlock(&pri->pvts[chanpos]->lock);
12210                      if (pri->resetting)
12211                         pri_check_restart(pri);
12212                      break;
12213                   }
12214                }
12215                if (chanpos < 0) {
12216                   ast_log(LOG_WARNING,
12217                      "Span %d: Restart ACK on strange channel %d/%d\n",
12218                      pri->span, PRI_SPAN(e->restartack.channel),
12219                      PRI_CHANNEL(e->restartack.channel));
12220                }
12221             } else {
12222                ast_mutex_lock(&pri->pvts[chanpos]->lock);
12223                if (pri->pvts[chanpos]->realcall) 
12224                   pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
12225                else if (pri->pvts[chanpos]->owner) {
12226                   ast_log(LOG_WARNING,
12227                      "Span %d: Got restart ack on channel %d/%d with owner\n",
12228                      pri->span, pri->pvts[chanpos]->logicalspan,
12229                      pri->pvts[chanpos]->prioffset);
12230                   pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
12231                }
12232                pri->pvts[chanpos]->resetting = 0;
12233                if (option_verbose > 2)
12234                   ast_verbose(VERBOSE_PREFIX_3
12235                      "Span %d: Channel %d/%d successfully restarted\n",
12236                      pri->span, pri->pvts[chanpos]->logicalspan,
12237                      pri->pvts[chanpos]->prioffset);
12238                ast_mutex_unlock(&pri->pvts[chanpos]->lock);
12239                if (pri->resetting)
12240                   pri_check_restart(pri);
12241             }
12242             break;
12243          case PRI_EVENT_SETUP_ACK:
12244             chanpos = pri_find_fixup_principle(pri, e->setup_ack.channel,
12245                e->setup_ack.call);
12246             if (chanpos < 0) {
12247                break;
12248             }
12249             ast_mutex_lock(&pri->pvts[chanpos]->lock);
12250             if (pri->pvts[chanpos]->call_level < DAHDI_CALL_LEVEL_OVERLAP) {
12251                pri->pvts[chanpos]->call_level = DAHDI_CALL_LEVEL_OVERLAP;
12252             }
12253 
12254             /* Send any queued digits */
12255             len = strlen(pri->pvts[chanpos]->dialdest);
12256             for (x = 0; x < len; ++x) {
12257                ast_log(LOG_DEBUG, "Sending pending digit '%c'\n", pri->pvts[chanpos]->dialdest[x]);
12258                pri_information(pri->pri, pri->pvts[chanpos]->call,
12259                   pri->pvts[chanpos]->dialdest[x]);
12260             }
12261 
12262             if (!pri->pvts[chanpos]->progress
12263                && (pri->overlapdial & DAHDI_OVERLAPDIAL_OUTGOING)
12264                && !pri->pvts[chanpos]->digital) {
12265                /*
12266                 * Call has a channel.
12267                 * Indicate for overlap dialing that dialtone may be present.
12268                 */
12269                struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, };
12270                dahdi_queue_frame(pri->pvts[chanpos], &f, pri);
12271                pri->pvts[chanpos]->progress = 1;/* Claim to have seen inband-information */
12272                pri->pvts[chanpos]->dialing = 0;
12273                if (pri->pvts[chanpos]->dsp && pri->pvts[chanpos]->dsp_features) {
12274                   ast_dsp_set_features(pri->pvts[chanpos]->dsp, pri->pvts[chanpos]->dsp_features);
12275                   pri->pvts[chanpos]->dsp_features = 0;
12276                }
12277             }
12278             ast_mutex_unlock(&pri->pvts[chanpos]->lock);
12279             break;
12280          case PRI_EVENT_NOTIFY:
12281 #if defined(HAVE_PRI_CALL_HOLD)
12282             chanpos = pri_find_principle_by_call(pri, e->notify.call);
12283             if (chanpos < 0) {
12284                ast_log(LOG_WARNING, "Span %d: Received NOTIFY for unknown call.\n",
12285                   pri->span);
12286                break;
12287             }
12288 #else
12289             /*
12290              * This version of libpri does not supply a call pointer for
12291              * this message.  We are just going to have to trust that the
12292              * correct principle is found.
12293              */
12294             chanpos = pri_find_principle(pri, e->notify.channel);
12295             if (chanpos < 0) {
12296                ast_log(LOG_WARNING, "Received NOTIFY on unconfigured channel %d/%d span %d\n",
12297                   PRI_SPAN(e->notify.channel), PRI_CHANNEL(e->notify.channel), pri->span);
12298                break;
12299             }
12300 #endif   /* !defined(HAVE_PRI_CALL_HOLD) */
12301             {
12302                struct ast_frame f = { AST_FRAME_CONTROL, };
12303                ast_mutex_lock(&pri->pvts[chanpos]->lock);
12304                switch (e->notify.info) {
12305                case PRI_NOTIFY_REMOTE_HOLD:
12306                   f.subclass = AST_CONTROL_HOLD;
12307                   dahdi_queue_frame(pri->pvts[chanpos], &f, pri);
12308                   break;
12309                case PRI_NOTIFY_REMOTE_RETRIEVAL:
12310                   f.subclass = AST_CONTROL_UNHOLD;
12311                   dahdi_queue_frame(pri->pvts[chanpos], &f, pri);
12312                   break;
12313                }
12314                ast_mutex_unlock(&pri->pvts[chanpos]->lock);
12315             }
12316             break;
12317          default:
12318             ast_log(LOG_DEBUG, "Event: %d\n", e->e);
12319          }
12320       }  
12321       ast_mutex_unlock(&pri->lock);
12322    }
12323    /* Never reached */
12324    return NULL;
12325 }
12326 
12327 static int start_pri(struct dahdi_pri *pri)
12328 {
12329    int res, x;
12330    struct dahdi_params p;
12331    struct dahdi_bufferinfo bi;
12332    struct dahdi_spaninfo si;
12333    int i;
12334    
12335    for (i = 0; i < NUM_DCHANS; i++) {
12336       if (!pri->dchannels[i])
12337          break;
12338       pri->fds[i] = open(DAHDI_FILE_CHANNEL, O_RDWR, 0600);
12339       x = pri->dchannels[i];
12340       if ((pri->fds[i] < 0) || (ioctl(pri->fds[i],DAHDI_SPECIFY,&x) == -1)) {
12341          ast_log(LOG_ERROR, "Unable to open D-channel %d (%s)\n", x, strerror(errno));
12342          return -1;
12343       }
12344       memset(&p, 0, sizeof(p));
12345       res = ioctl(pri->fds[i], DAHDI_GET_PARAMS, &p);
12346       if (res) {
12347          dahdi_close_pri_fd(pri, i);
12348          ast_log(LOG_ERROR, "Unable to get parameters for D-channel %d (%s)\n", x, strerror(errno));
12349          return -1;
12350       }
12351       if ((p.sigtype != DAHDI_SIG_HDLCFCS) && (p.sigtype != DAHDI_SIG_HARDHDLC)) {
12352          dahdi_close_pri_fd(pri, i);
12353          ast_log(LOG_ERROR, "D-channel %d is not in HDLC/FCS mode.  See /etc/dahdi/system.conf\n", x);
12354          return -1;
12355       }
12356       memset(&si, 0, sizeof(si));
12357       res = ioctl(pri->fds[i], DAHDI_SPANSTAT, &si);
12358       if (res) {
12359          dahdi_close_pri_fd(pri, i);
12360          ast_log(LOG_ERROR, "Unable to get span state for D-channel %d (%s)\n", x, strerror(errno));
12361       }
12362       if (!si.alarms)
12363          pri->dchanavail[i] |= DCHAN_NOTINALARM;
12364       else
12365          pri->dchanavail[i] &= ~DCHAN_NOTINALARM;
12366       memset(&bi, 0, sizeof(bi));
12367       bi.txbufpolicy = DAHDI_POLICY_IMMEDIATE;
12368       bi.rxbufpolicy = DAHDI_POLICY_IMMEDIATE;
12369       bi.numbufs = 32;
12370       bi.bufsize = 1024;
12371       if (ioctl(pri->fds[i], DAHDI_SET_BUFINFO, &bi)) {
12372          ast_log(LOG_ERROR, "Unable to set appropriate buffering on channel %d: %s\n", x, strerror(errno));
12373          dahdi_close_pri_fd(pri, i);
12374          return -1;
12375       }
12376       pri->dchans[i] = pri_new(pri->fds[i], pri->nodetype, pri->switchtype);
12377       /* Force overlap dial if we're doing GR-303! */
12378       if (pri->switchtype == PRI_SWITCH_GR303_TMC)
12379          pri->overlapdial |= DAHDI_OVERLAPDIAL_BOTH;
12380       pri_set_overlapdial(pri->dchans[i],(pri->overlapdial & DAHDI_OVERLAPDIAL_OUTGOING)?1:0);
12381 #ifdef HAVE_PRI_INBANDDISCONNECT
12382       pri_set_inbanddisconnect(pri->dchans[i], pri->inbanddisconnect);
12383 #endif
12384       /* Enslave to master if appropriate */
12385       if (i)
12386          pri_enslave(pri->dchans[0], pri->dchans[i]);
12387       if (!pri->dchans[i]) {
12388          dahdi_close_pri_fd(pri, i);
12389          ast_log(LOG_ERROR, "Unable to create PRI structure\n");
12390          return -1;
12391       }
12392       pri_set_debug(pri->dchans[i], DEFAULT_PRI_DEBUG);
12393       pri_set_nsf(pri->dchans[i], pri->nsf);
12394 #ifdef PRI_GETSET_TIMERS
12395       for (x = 0; x < PRI_MAX_TIMERS; x++) {
12396          if (pritimers[x] != 0)
12397             pri_set_timer(pri->dchans[i], x, pritimers[x]);
12398       }
12399 #endif
12400    }
12401    /* Assume primary is the one we use */
12402    pri->pri = pri->dchans[0];
12403    pri->resetpos = -1;
12404    if (ast_pthread_create_background(&pri->master, NULL, pri_dchannel, pri)) {
12405       for (i = 0; i < NUM_DCHANS; i++) {
12406          if (!pri->dchannels[i])
12407             break;
12408          dahdi_close_pri_fd(pri, i);
12409       }
12410       ast_log(LOG_ERROR, "Unable to spawn D-channel: %s\n", strerror(errno));
12411       return -1;
12412    }
12413    return 0;
12414 }
12415 
12416 static char *complete_span_helper(const char *line, const char *word, int pos, int state, int rpos)
12417 {
12418    int which, span;
12419    char *ret = NULL;
12420 
12421    if (pos != rpos)
12422       return ret;
12423 
12424    for (which = span = 0; span < NUM_SPANS; span++) {
12425       if (pris[span].pri && ++which > state) {
12426          if (asprintf(&ret, "%d", span + 1) < 0) { /* user indexes start from 1 */
12427             ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
12428          }
12429          break;
12430       }
12431    }
12432    return ret;
12433 }
12434 
12435 static char *complete_span_4(const char *line, const char *word, int pos, int state)
12436 {
12437    return complete_span_helper(line,word,pos,state,3);
12438 }
12439 
12440 static char *complete_span_5(const char *line, const char *word, int pos, int state)
12441 {
12442    return complete_span_helper(line,word,pos,state,4);
12443 }
12444 
12445 static int handle_pri_set_debug_file(int fd, int argc, char **argv)
12446 {
12447    int myfd;
12448 
12449    if (!strncasecmp(argv[1], "set", 3)) {
12450       if (argc < 5) 
12451          return RESULT_SHOWUSAGE;
12452 
12453       if (ast_strlen_zero(argv[4]))
12454          return RESULT_SHOWUSAGE;
12455 
12456       myfd = open(argv[4], O_CREAT|O_WRONLY, 0600);
12457       if (myfd < 0) {
12458          ast_cli(fd, "Unable to open '%s' for writing\n", argv[4]);
12459          return RESULT_SUCCESS;
12460       }
12461 
12462       ast_mutex_lock(&pridebugfdlock);
12463 
12464       if (pridebugfd >= 0)
12465          close(pridebugfd);
12466 
12467       pridebugfd = myfd;
12468       ast_copy_string(pridebugfilename,argv[4],sizeof(pridebugfilename));
12469       
12470       ast_mutex_unlock(&pridebugfdlock);
12471 
12472       ast_cli(fd, "PRI debug output will be sent to '%s'\n", argv[4]);
12473    } else {
12474       /* Assume it is unset */
12475       ast_mutex_lock(&pridebugfdlock);
12476       close(pridebugfd);
12477       pridebugfd = -1;
12478       ast_cli(fd, "PRI debug output to file disabled\n");
12479       ast_mutex_unlock(&pridebugfdlock);
12480    }
12481 
12482    return RESULT_SUCCESS;
12483 }
12484 
12485 #ifdef HAVE_PRI_VERSION
12486 static int handle_pri_version(int fd, int agc, char *argv[]) {
12487    ast_cli(fd, "libpri version: %s\n", pri_get_version());
12488    return RESULT_SUCCESS;
12489 }
12490 #endif
12491 
12492 static int handle_pri_debug(int fd, int argc, char *argv[])
12493 {
12494    int span;
12495    int x;
12496    if (argc < 4) {
12497       return RESULT_SHOWUSAGE;
12498    }
12499    span = atoi(argv[3]);
12500    if ((span < 1) || (span > NUM_SPANS)) {
12501       ast_cli(fd, "Invalid span %s.  Should be a number %d to %d\n", argv[3], 1, NUM_SPANS);
12502       return RESULT_SUCCESS;
12503    }
12504    if (!pris[span-1].pri) {
12505       ast_cli(fd, "No PRI running on span %d\n", span);
12506       return RESULT_SUCCESS;
12507    }
12508    for (x = 0; x < NUM_DCHANS; x++) {
12509       if (pris[span-1].dchans[x])
12510          pri_set_debug(pris[span-1].dchans[x], PRI_DEBUG_APDU |
12511                                                PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q931_STATE |
12512                                                PRI_DEBUG_Q921_STATE);
12513    }
12514    ast_cli(fd, "Enabled debugging on span %d\n", span);
12515    return RESULT_SUCCESS;
12516 }
12517 
12518 
12519 
12520 static int handle_pri_no_debug(int fd, int argc, char *argv[])
12521 {
12522    int span;
12523    int x;
12524    if (argc < 5)
12525       return RESULT_SHOWUSAGE;
12526    span = atoi(argv[4]);
12527    if ((span < 1) || (span > NUM_SPANS)) {
12528       ast_cli(fd, "Invalid span %s.  Should be a number %d to %d\n", argv[4], 1, NUM_SPANS);
12529       return RESULT_SUCCESS;
12530    }
12531    if (!pris[span-1].pri) {
12532       ast_cli(fd, "No PRI running on span %d\n", span);
12533       return RESULT_SUCCESS;
12534    }
12535    for (x = 0; x < NUM_DCHANS; x++) {
12536       if (pris[span-1].dchans[x])
12537          pri_set_debug(pris[span-1].dchans[x], 0);
12538    }
12539    ast_cli(fd, "Disabled debugging on span %d\n", span);
12540    return RESULT_SUCCESS;
12541 }
12542 
12543 static int handle_pri_really_debug(int fd, int argc, char *argv[])
12544 {
12545    int span;
12546    int x;
12547    if (argc < 5)
12548       return RESULT_SHOWUSAGE;
12549    span = atoi(argv[4]);
12550    if ((span < 1) || (span > NUM_SPANS)) {
12551       ast_cli(fd, "Invalid span %s.  Should be a number %d to %d\n", argv[4], 1, NUM_SPANS);
12552       return RESULT_SUCCESS;
12553    }
12554    if (!pris[span-1].pri) {
12555       ast_cli(fd, "No PRI running on span %d\n", span);
12556       return RESULT_SUCCESS;
12557    }
12558    for (x = 0; x < NUM_DCHANS; x++) {
12559       if (pris[span-1].dchans[x])
12560          pri_set_debug(pris[span-1].dchans[x], PRI_DEBUG_APDU |
12561                                                PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q931_STATE |
12562                                                PRI_DEBUG_Q921_RAW | PRI_DEBUG_Q921_DUMP | PRI_DEBUG_Q921_STATE);
12563    }
12564    ast_cli(fd, "Enabled EXTENSIVE debugging on span %d\n", span);
12565    return RESULT_SUCCESS;
12566 }
12567 
12568 static void build_status(char *s, size_t len, int status, int active)
12569 {
12570    if (!s || len < 1) {
12571       return;
12572    }
12573    s[0] = '\0';
12574    if (status & DCHAN_PROVISIONED)
12575       strncat(s, "Provisioned, ", len - strlen(s) - 1);
12576    if (!(status & DCHAN_NOTINALARM))
12577       strncat(s, "In Alarm, ", len - strlen(s) - 1);
12578    if (status & DCHAN_UP)
12579       strncat(s, "Up", len - strlen(s) - 1);
12580    else
12581       strncat(s, "Down", len - strlen(s) - 1);
12582    if (active)
12583       strncat(s, ", Active", len - strlen(s) - 1);
12584    else
12585       strncat(s, ", Standby", len - strlen(s) - 1);
12586    s[len - 1] = '\0';
12587 }
12588 
12589 static int handle_pri_show_spans(int fd, int argc, char *argv[])
12590 {
12591    int span;
12592    int x;
12593    char status[256];
12594    if (argc != 3)
12595       return RESULT_SHOWUSAGE;
12596 
12597    for (span = 0; span < NUM_SPANS; span++) {
12598       if (pris[span].pri) {
12599          for (x = 0; x < NUM_DCHANS; x++) {
12600             if (pris[span].dchannels[x]) {
12601                build_status(status, sizeof(status), pris[span].dchanavail[x], pris[span].dchans[x] == pris[span].pri);
12602                ast_cli(fd, "PRI span %d/%d: %s\n", span + 1, x, status);
12603             }
12604          }
12605       }
12606    }
12607    return RESULT_SUCCESS;
12608 }
12609 
12610 static int handle_pri_show_span(int fd, int argc, char *argv[])
12611 {
12612    int span;
12613    int x;
12614    char status[256];
12615    if (argc < 4)
12616       return RESULT_SHOWUSAGE;
12617    span = atoi(argv[3]);
12618    if ((span < 1) || (span > NUM_SPANS)) {
12619       ast_cli(fd, "Invalid span '%s'.  Should be a number from %d to %d\n", argv[3], 1, NUM_SPANS);
12620       return RESULT_SUCCESS;
12621    }
12622    if (!pris[span-1].pri) {
12623       ast_cli(fd, "No PRI running on span %d\n", span);
12624       return RESULT_SUCCESS;
12625    }
12626    for (x = 0; x < NUM_DCHANS; x++) {
12627       if (pris[span-1].dchannels[x]) {
12628 #ifdef PRI_DUMP_INFO_STR
12629          char *info_str = NULL;
12630 #endif
12631          ast_cli(fd, "%s D-channel: %d\n", pri_order(x), pris[span-1].dchannels[x]);
12632          build_status(status, sizeof(status), pris[span-1].dchanavail[x], pris[span-1].dchans[x] == pris[span-1].pri);
12633          ast_cli(fd, "Status: %s\n", status);
12634          ast_mutex_lock(&pris[span - 1].lock);
12635 #ifdef PRI_DUMP_INFO_STR
12636          info_str = pri_dump_info_str(pris[span-1].pri);
12637          if (info_str) {
12638             ast_cli(fd, "%s", info_str);
12639             free(info_str);
12640          }
12641 #else
12642          pri_dump_info(pris[span-1].pri);
12643 #endif
12644          ast_mutex_unlock(&pris[span - 1].lock);
12645          ast_cli(fd, "Overlap Recv: %s\n\n", (pris[span-1].overlapdial & DAHDI_OVERLAPDIAL_INCOMING)?"Yes":"No");
12646       }
12647    }
12648    return RESULT_SUCCESS;
12649 }
12650 
12651 static int handle_pri_show_debug(int fd, int argc, char *argv[])
12652 {
12653    int x;
12654    int span;
12655    int count=0;
12656    int debug=0;
12657 
12658    for (span = 0; span < NUM_SPANS; span++) {
12659            if (pris[span].pri) {
12660          for (x = 0; x < NUM_DCHANS; x++) {
12661             debug = 0;
12662                if (pris[span].dchans[x]) {
12663                   debug = pri_get_debug(pris[span].dchans[x]);
12664                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" );
12665                count++;
12666             }
12667          }
12668       }
12669 
12670    }
12671    ast_mutex_lock(&pridebugfdlock);
12672    if (pridebugfd >= 0) 
12673       ast_cli(fd, "Logging PRI debug to file %s\n", pridebugfilename);
12674    ast_mutex_unlock(&pridebugfdlock);
12675        
12676    if (!count) 
12677       ast_cli(fd, "No debug set or no PRI running\n");
12678    return RESULT_SUCCESS;
12679 }
12680 
12681 static const char pri_debug_help[] = 
12682    "Usage: pri debug span <span>\n"
12683    "       Enables debugging on a given PRI span\n";
12684    
12685 static const char pri_no_debug_help[] = 
12686    "Usage: pri no debug span <span>\n"
12687    "       Disables debugging on a given PRI span\n";
12688 
12689 static const char pri_really_debug_help[] = 
12690    "Usage: pri intensive debug span <span>\n"
12691    "       Enables debugging down to the Q.921 level\n";
12692 
12693 static const char pri_show_span_help[] = 
12694    "Usage: pri show span <span>\n"
12695    "       Displays PRI Information on a given PRI span\n";
12696 
12697 static const char pri_show_spans_help[] = 
12698    "Usage: pri show spans\n"
12699    "       Displays PRI Information\n";
12700 
12701 static struct ast_cli_entry dahdi_pri_cli[] = {
12702    { { "pri", "debug", "span", NULL },
12703    handle_pri_debug, "Enables PRI debugging on a span",
12704    pri_debug_help, complete_span_4 },
12705 
12706    { { "pri", "no", "debug", "span", NULL },
12707    handle_pri_no_debug, "Disables PRI debugging on a span",
12708    pri_no_debug_help, complete_span_5 },
12709 
12710    { { "pri", "intense", "debug", "span", NULL },
12711    handle_pri_really_debug, "Enables REALLY INTENSE PRI debugging",
12712    pri_really_debug_help, complete_span_5 },
12713 
12714    { { "pri", "show", "spans", NULL },
12715    handle_pri_show_spans, "Displays PRI Information",
12716    pri_show_spans_help },
12717 
12718    { { "pri", "show", "span", NULL },
12719    handle_pri_show_span, "Displays PRI Information",
12720    pri_show_span_help, complete_span_4 },
12721 
12722    { { "pri", "show", "debug", NULL },
12723    handle_pri_show_debug, "Displays current PRI debug settings" },
12724 
12725    { { "pri", "set", "debug", "file", NULL },
12726    handle_pri_set_debug_file, "Sends PRI debug output to the specified file" },
12727 
12728    { { "pri", "unset", "debug", "file", NULL },
12729    handle_pri_set_debug_file, "Ends PRI debug output to file" },
12730 
12731 #ifdef HAVE_PRI_VERSION
12732    { { "pri", "show", "version", NULL },
12733    handle_pri_version, "Displays version of libpri" },
12734 #endif
12735 };
12736 
12737 #endif /* HAVE_PRI */
12738 
12739 #ifdef HAVE_OPENR2
12740 
12741 static int handle_mfcr2_version(int fd, int argc, char *argv[])
12742 {
12743    ast_cli(fd, "OpenR2 version: %s, revision: %s\n", openr2_get_version(), openr2_get_revision());
12744    return RESULT_SUCCESS;
12745 }
12746 
12747 static int handle_mfcr2_show_variants(int fd, int argc, char *argv[]) 
12748 {
12749 #define FORMAT "%4s %40s\n"
12750    int numvariants = 0;
12751    int i;
12752    const openr2_variant_entry_t *variants;
12753    if (!(variants = openr2_proto_get_variant_list(&numvariants))) {
12754       ast_cli(fd, "Failed to get list of variants.\n");
12755       return RESULT_FAILURE;
12756    }
12757    ast_cli(fd, FORMAT, "Variant Code", "Country");
12758    for (i = 0; i < numvariants; i++) {
12759       ast_cli(fd, FORMAT, variants[i].name, variants[i].country);
12760    }
12761    return RESULT_SUCCESS;
12762 #undef FORMAT
12763 }  
12764 
12765 static int handle_mfcr2_show_channels(int fd, int argc, char *argv[])
12766 {
12767 #define FORMAT "%4s %-7.7s %-7.7s %-8.8s %-9.9s %-16.16s %-8.8s %-8.8s\n"
12768    int filtertype = 0;
12769    int targetnum = 0;
12770    char channo[5];
12771    char anino[5];
12772    char dnisno[5];
12773    struct dahdi_pvt *p;
12774    openr2_context_t *r2context;
12775    openr2_variant_t r2variant;
12776    if (!((argc == 3) || (argc == 5))) {
12777       return RESULT_SHOWUSAGE;
12778    }
12779    if (argc == 5) {
12780       if (!strcasecmp(argv[3], "group")) {
12781          targetnum = atoi(argv[4]);
12782          if ((targetnum < 0) || (targetnum > 63))
12783             return RESULT_SHOWUSAGE;
12784          targetnum = 1 << targetnum;
12785          filtertype = 1;
12786       } else if (!strcasecmp(argv[3], "context")) {
12787          filtertype = 2;
12788       } else {
12789          return RESULT_SHOWUSAGE;
12790       }
12791    }
12792    ast_cli(fd, FORMAT, "Chan", "Variant", "Max ANI", "Max DNIS", "ANI First", "Immediate Accept", "Tx CAS", "Rx CAS");
12793    ast_mutex_lock(&iflock);
12794    p = iflist;
12795    while (p) {
12796       if (!(p->sig & SIG_MFCR2) || !p->r2chan) {
12797          p = p->next;
12798          continue;
12799       }
12800       if (filtertype) {
12801          switch(filtertype) {
12802          case 1: /* mfcr2 show channels group <group> */
12803             if (p->group != targetnum) {
12804                p = p->next;
12805                continue;
12806             }
12807             break;
12808          case 2: /* mfcr2 show channels context <context> */
12809             if (strcasecmp(p->context, argv[4])) {
12810                p= p->next;
12811                continue;
12812             }
12813             break;
12814          default:
12815             ;
12816          }
12817       }
12818       r2context = openr2_chan_get_context(p->r2chan);
12819       r2variant = openr2_context_get_variant(r2context);
12820       snprintf(channo, sizeof(channo), "%d", p->channel);
12821       snprintf(anino, sizeof(anino), "%d", openr2_context_get_max_ani(r2context));
12822       snprintf(dnisno, sizeof(dnisno), "%d", openr2_context_get_max_dnis(r2context));
12823       ast_cli(fd, FORMAT, channo, openr2_proto_get_variant_string(r2variant), 
12824             anino, dnisno, openr2_context_get_ani_first(r2context) ? "Yes" : "No",  
12825             openr2_context_get_immediate_accept(r2context) ? "Yes" : "No",
12826             openr2_chan_get_tx_cas_string(p->r2chan), openr2_chan_get_rx_cas_string(p->r2chan));
12827       p = p->next;
12828    }
12829    ast_mutex_unlock(&iflock);
12830    return RESULT_SUCCESS;
12831 #undef FORMAT
12832 }
12833 
12834 static int handle_mfcr2_set_debug(int fd, int argc, char *argv[])
12835 {
12836    struct dahdi_pvt *p = NULL;
12837    int channo = 0;
12838    char *toklevel = NULL;
12839    char *saveptr = NULL;
12840    char *logval = NULL;
12841    openr2_log_level_t loglevel = OR2_LOG_NOTHING;
12842    openr2_log_level_t tmplevel = OR2_LOG_NOTHING;
12843    if (argc < 4) {
12844       return RESULT_SHOWUSAGE;
12845    }
12846    channo = (argc == 5) ? atoi(argv[4]) : -1;
12847    logval = ast_strdupa(argv[3]);
12848    toklevel = strtok_r(logval, ",", &saveptr);
12849    if (-1 == (tmplevel = openr2_log_get_level(toklevel))) {
12850       ast_cli(fd, "Invalid MFC/R2 logging level '%s'.\n", argv[3]);
12851       return RESULT_FAILURE;
12852    } else if (OR2_LOG_NOTHING == tmplevel) {
12853       loglevel = tmplevel;
12854    } else {
12855       loglevel |= tmplevel;
12856       while ((toklevel = strtok_r(NULL, ",", &saveptr))) {
12857          if (-1 == (tmplevel = openr2_log_get_level(toklevel))) {
12858             ast_cli(fd, "Ignoring invalid logging level: '%s'.\n", toklevel);
12859             continue;
12860          }
12861          loglevel |= tmplevel;
12862       }
12863    }
12864    ast_mutex_lock(&iflock);
12865    p = iflist;
12866    while (p) {
12867       if (!(p->sig & SIG_MFCR2) || !p->r2chan) {
12868          p = p->next;
12869          continue;
12870       }
12871       if ((channo != -1) && (p->channel != channo )) {
12872          p = p->next;
12873          continue;
12874       }
12875       openr2_chan_set_log_level(p->r2chan, loglevel);
12876       if (channo != -1) {
12877          ast_cli(fd, "MFC/R2 debugging set to '%s' for channel %d.\n", argv[3], p->channel);
12878          break;
12879       } else {
12880          p = p->next;
12881       }
12882    }
12883    if ((channo != -1) && !p) {
12884       ast_cli(fd, "MFC/R2 channel %d not found.\n", channo);
12885    }
12886    if (channo == -1) {
12887       ast_cli(fd, "MFC/R2 debugging set to '%s' for all channels.\n", argv[3]);
12888    }
12889    ast_mutex_unlock(&iflock);
12890    return RESULT_SUCCESS;
12891 }
12892 
12893 static int handle_mfcr2_call_files(int fd, int argc, char *argv[])
12894 {
12895    struct dahdi_pvt *p = NULL;
12896    int channo = 0;
12897    if (argc < 4) {
12898       return RESULT_SHOWUSAGE;
12899    }
12900    channo = (argc == 5) ? atoi(argv[4]) : -1;
12901    ast_mutex_lock(&iflock);
12902    p = iflist;
12903    while (p) {
12904       if (!(p->sig & SIG_MFCR2) || !p->r2chan) {
12905          p = p->next;
12906          continue;
12907       }
12908       if ((channo != -1) && (p->channel != channo )) {
12909          p = p->next;
12910          continue;
12911       }
12912       if (ast_true(argv[3])) {
12913          openr2_chan_enable_call_files(p->r2chan);
12914       } else {
12915          openr2_chan_disable_call_files(p->r2chan);
12916       }
12917       if (channo != -1) {
12918          if (ast_true(argv[3])) {
12919             ast_cli(fd, "MFC/R2 call files enabled for channel %d.\n", p->channel);
12920          } else {
12921             ast_cli(fd, "MFC/R2 call files disabled for channel %d.\n", p->channel);
12922          }
12923          break;
12924       } else {
12925          p = p->next;
12926       }
12927    }
12928    if ((channo != -1) && !p) {
12929       ast_cli(fd, "MFC/R2 channel %d not found.\n", channo);
12930    }
12931    if (channo == -1) {
12932       if (ast_true(argv[3])) {
12933          ast_cli(fd, "MFC/R2 Call files enabled for all channels.\n");
12934       } else {
12935          ast_cli(fd, "MFC/R2 Call files disabled for all channels.\n");
12936       }  
12937    }
12938    ast_mutex_unlock(&iflock);
12939    return RESULT_SUCCESS;
12940 }  
12941 
12942 static int handle_mfcr2_set_idle(int fd, int argc, char *argv[])
12943 {
12944    struct dahdi_pvt *p = NULL;
12945    int channo = 0;
12946    channo = (argc == 4) ? atoi(argv[3]) : -1;
12947    ast_mutex_lock(&iflock);
12948    p = iflist;
12949    while (p) {
12950       if (!(p->sig & SIG_MFCR2) || !p->r2chan) {
12951          p = p->next;
12952          continue;
12953       }
12954       if ((channo != -1) && (p->channel != channo )) {
12955          p = p->next;
12956          continue;
12957       }
12958       if (!openr2_chan_set_idle(p->r2chan)) {
12959          ast_mutex_lock(&p->lock);
12960          p->mfcr2call = 0;
12961          p->mfcr2block &= ~DAHDI_R2_LOCAL_BLOCK;
12962          ast_mutex_unlock(&p->lock);
12963       }
12964       if (channo != -1) {
12965          break;
12966       } else {
12967          p = p->next;
12968       }
12969    }
12970    if ((channo != -1) && !p) {
12971       ast_cli(fd, "MFC/R2 channel %d not found.\n", channo);
12972    }
12973    ast_mutex_unlock(&iflock);
12974    return RESULT_SUCCESS;
12975 }
12976 
12977 static int handle_mfcr2_set_blocked(int fd, int argc, char *argv[])
12978 {
12979    struct dahdi_pvt *p = NULL;
12980    int channo = 0;
12981    channo = (argc == 4) ? atoi(argv[3]) : -1;
12982    ast_mutex_lock(&iflock);
12983    p = iflist;
12984    while (p) {
12985       if (!(p->sig & SIG_MFCR2) || !p->r2chan) {
12986          p = p->next;
12987          continue;
12988       }
12989       if ((channo != -1) && (p->channel != channo )) {
12990          p = p->next;
12991          continue;
12992       }
12993       if (!openr2_chan_set_blocked(p->r2chan)) {
12994          ast_mutex_lock(&p->lock);
12995          p->mfcr2block |= DAHDI_R2_LOCAL_BLOCK;
12996          ast_mutex_unlock(&p->lock);
12997       } else {
12998          ast_cli(fd, "MFC/R2 channel %d could not be blocked.\n", p->channel);
12999       }
13000       if (channo != -1) {
13001          break;
13002       } else {
13003          p = p->next;
13004       }
13005    }
13006    if ((channo != -1) && !p) {
13007       ast_cli(fd, "MFC/R2 channel %d not found.\n", channo);
13008    }
13009    ast_mutex_unlock(&iflock);
13010    return RESULT_SUCCESS;
13011 }
13012 
13013 static const char dahdi_r2_version_help[] = 
13014          "Usage: mfcr2 show version\n"
13015          "       Shows the version of the OpenR2 library being used.\n";
13016 static const char dahdi_r2_variants_help[] = 
13017          "Usage: mfcr2 show variants\n"
13018          "       Show supported MFC/R2 variants.\n";
13019 static const char dahdi_r2_showchannels_help[] =
13020          "Usage: mfcr2 show channels [group <group> | context <context>]\n"
13021          "       Shows the zap channels configured with MFC/R2 signaling.\n";
13022 static const char dahdi_r2_setdebug_help[] =
13023          "Usage: mfcr2 set debug <loglevel> <channel>\n"
13024          "       Set a new logging level for the specified channel.\n"
13025          "       If no channel is specified the logging level will be applied to all channels.\n";
13026 static const char dahdi_r2_callfiles_help[] =
13027          "Usage: mfcr2 call files [on|off] <channel>\n"
13028          "       Enable call files creation on the specified channel.\n"
13029          "       If no channel is specified call files creation policy will be applied to all channels.\n";
13030 static const char dahdi_r2_setidle_help[] =
13031          "Usage: mfcr2 set idle <channel>\n"
13032          "       DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING.\n"
13033          "       Force the given channel into IDLE state.\n"
13034          "       If no channel is specified, all channels will be set to IDLE.\n";
13035 static const char dahdi_r2_setblocked_help[] =
13036          "Usage: mfcr2 set blocked <channel>\n"
13037          "       DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING.\n"
13038          "       Force the given channel into BLOCKED state.\n"
13039          "       If no channel is specified, all channels will be set to BLOCKED.\n";
13040 
13041 static struct ast_cli_entry dahdi_mfcr2_cli[] = {
13042    { { "mfcr2", "show", "version", NULL },
13043    handle_mfcr2_version, "Show OpenR2 library version",
13044    dahdi_r2_version_help },
13045 
13046    { { "mfcr2", "show", "variants", NULL },
13047    handle_mfcr2_show_variants, "Show supported MFC/R2 variants",
13048    dahdi_r2_variants_help },
13049 
13050    { { "mfcr2", "show", "channels", NULL },
13051    handle_mfcr2_show_channels, "Show MFC/R2 channels",
13052    dahdi_r2_showchannels_help },
13053 
13054    { { "mfcr2", "set", "debug", NULL },
13055    handle_mfcr2_set_debug, "Set MFC/R2 channel logging level",
13056    dahdi_r2_setdebug_help },
13057 
13058    { { "mfcr2", "call", "files", NULL },
13059    handle_mfcr2_call_files, "Enable/Disable MFC/R2 call files",
13060    dahdi_r2_callfiles_help },
13061 
13062    { { "mfcr2", "set", "idle", NULL },
13063    handle_mfcr2_set_idle, "Reset MFC/R2 channel forcing it to IDLE",
13064    dahdi_r2_setidle_help },
13065 
13066    { { "mfcr2", "set", "blocked", NULL },
13067    handle_mfcr2_set_blocked, "Reset MFC/R2 channel forcing it to BLOCKED",
13068    dahdi_r2_setblocked_help }
13069 
13070 };
13071 
13072 #endif /* HAVE_OPENR2 */
13073 
13074 static int dahdi_destroy_channel(int fd, int argc, char **argv)
13075 {
13076    int channel;
13077    
13078    if (argc != 4)
13079       return RESULT_SHOWUSAGE;
13080    
13081    channel = atoi(argv[3]);
13082 
13083    return dahdi_destroy_channel_bynum(channel);
13084 }
13085 
13086 static void dahdi_softhangup_all(void)
13087 {
13088    struct dahdi_pvt *p;
13089 retry:
13090    ast_mutex_lock(&iflock);
13091     for (p = iflist; p; p = p->next) {
13092       ast_mutex_lock(&p->lock);
13093         if (p->owner && !p->restartpending) {
13094          if (ast_channel_trylock(p->owner)) {
13095             if (option_debug > 2)
13096                ast_verbose("Avoiding deadlock\n");
13097             /* Avoid deadlock since you're not supposed to lock iflock or pvt before a channel */
13098             ast_mutex_unlock(&p->lock);
13099             ast_mutex_unlock(&iflock);
13100             goto retry;
13101          }
13102          if (option_debug > 2)
13103             ast_verbose("Softhanging up on %s\n", p->owner->name);
13104          ast_softhangup_nolock(p->owner, AST_SOFTHANGUP_EXPLICIT);
13105          p->restartpending = 1;
13106          num_restart_pending++;
13107          ast_channel_unlock(p->owner);
13108       }
13109       ast_mutex_unlock(&p->lock);
13110     }
13111    ast_mutex_unlock(&iflock);
13112 }
13113 
13114 static int setup_dahdi(int reload);
13115 static int dahdi_restart(void)
13116 {
13117 
13118 #ifdef HAVE_OPENR2
13119    int r;
13120 #endif
13121   
13122 #if defined(HAVE_PRI)
13123    int i, j;
13124 #endif
13125    int cancel_code;
13126    struct dahdi_pvt *p;
13127 
13128    ast_mutex_lock(&restart_lock);
13129  
13130    if (option_verbose)
13131       ast_verbose("Destroying channels and reloading DAHDI configuration.\n");
13132    dahdi_softhangup_all();
13133    if (option_verbose > 3)
13134       ast_verbose("Initial softhangup of all DAHDI channels complete.\n");
13135 
13136 #ifdef HAVE_OPENR2
13137    for (r = 0; r < NUM_SPANS; r++) {
13138       if (r2links[r].master != AST_PTHREADT_NULL) {
13139          ast_log(LOG_DEBUG, "Killing MFC/R2 monitor thread %p\n", &r2links[r].master);
13140          pthread_cancel(r2links[r].master);
13141          pthread_join(r2links[r].master, NULL);
13142          openr2_context_delete(r2links[r].protocol_context);
13143       }
13144    }
13145    init_mfcr2_globals();
13146 #endif
13147    
13148    #if defined(HAVE_PRI)
13149    for (i = 0; i < NUM_SPANS; i++) {
13150       if (pris[i].master && (pris[i].master != AST_PTHREADT_NULL)) {
13151          cancel_code = pthread_cancel(pris[i].master);
13152          pthread_kill(pris[i].master, SIGURG);
13153          if (option_debug > 3)
13154             ast_verbose("Waiting to join thread of span %d with pid=%p, cancel_code=%d\n", i, (void *) pris[i].master, cancel_code);
13155             pthread_join(pris[i].master, NULL);
13156          if (option_debug > 3)
13157             ast_verbose("Joined thread of span %d\n", i);
13158       }
13159     }
13160    #endif
13161 
13162     ast_mutex_lock(&monlock);
13163     if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) {
13164       cancel_code = pthread_cancel(monitor_thread);
13165       pthread_kill(monitor_thread, SIGURG);
13166       if (option_debug > 3)
13167          ast_verbose("Waiting to join monitor thread with pid=%p, cancel_code=%d\n", (void *) monitor_thread, cancel_code);
13168         pthread_join(monitor_thread, NULL);
13169       if (option_debug > 3)
13170          ast_verbose("Joined monitor thread\n");
13171     }
13172    monitor_thread = AST_PTHREADT_NULL; /* prepare to restart thread in setup_dahdi once channels are reconfigured */
13173 
13174    ast_mutex_lock(&ss_thread_lock);
13175    while (ss_thread_count > 0) { /* let ss_threads finish and run dahdi_hangup before dahvi_pvts are destroyed */
13176       int x = DAHDI_FLASH;
13177       if (option_debug > 2)
13178          ast_verbose("Waiting on %d ss_thread(s) to finish\n", ss_thread_count);
13179 
13180       for (p = iflist; p; p = p->next) {
13181          if (p->owner)
13182             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 */    
13183       }
13184       ast_cond_wait(&ss_thread_complete, &ss_thread_lock);
13185    }
13186 
13187    /* ensure any created channels before monitor threads were stopped are hungup */
13188    dahdi_softhangup_all();
13189    if (option_verbose > 3)
13190       ast_verbose("Final softhangup of all DAHDI channels complete.\n");
13191    destroy_all_channels();
13192    if (option_debug)
13193       ast_verbose("Channels destroyed. Now re-reading config. %d active channels remaining.\n", ast_active_channels());
13194 
13195     ast_mutex_unlock(&monlock);
13196 
13197    #ifdef HAVE_PRI
13198    for (i = 0; i < NUM_SPANS; i++) {
13199       for (j = 0; j < NUM_DCHANS; j++)
13200             dahdi_close_pri_fd(&(pris[i]), j);
13201    }
13202 
13203    memset(pris, 0, sizeof(pris));
13204    for (i = 0; i < NUM_SPANS; i++) {
13205       ast_mutex_init(&pris[i].lock);
13206       pris[i].offset = -1;
13207       pris[i].master = AST_PTHREADT_NULL;
13208       for (j = 0; j < NUM_DCHANS; j++)
13209          pris[i].fds[j] = -1;
13210    }
13211    pri_set_error(dahdi_pri_error);
13212    pri_set_message(dahdi_pri_message);
13213    #endif
13214 
13215    if (setup_dahdi(2) != 0) {
13216       ast_log(LOG_WARNING, "Reload channels from dahdi config failed!\n");
13217       ast_mutex_unlock(&ss_thread_lock);
13218       return 1;
13219    }
13220    ast_mutex_unlock(&ss_thread_lock);
13221    ast_mutex_unlock(&restart_lock);
13222    return 0;
13223 }
13224 
13225 static int dahdi_restart_cmd(int fd, int argc, char **argv)
13226 {
13227    if (argc != 2) {
13228       return RESULT_SHOWUSAGE;
13229    }
13230 
13231    if (dahdi_restart() != 0)
13232       return RESULT_FAILURE;
13233    return RESULT_SUCCESS;
13234 }
13235 
13236 static int dahdi_show_channels(int fd, int argc, char **argv)
13237 {
13238 #define FORMAT "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n"
13239 #define FORMAT2 "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n"
13240    struct dahdi_pvt *tmp = NULL;
13241    char tmps[20] = "";
13242    ast_mutex_t *lock;
13243    struct dahdi_pvt *start;
13244 #ifdef HAVE_PRI
13245    int trunkgroup;
13246    struct dahdi_pri *pri = NULL;
13247    int x;
13248 #endif
13249 
13250    lock = &iflock;
13251    start = iflist;
13252 
13253 #ifdef HAVE_PRI
13254    if (argc == 4) {
13255       if ((trunkgroup = atoi(argv[3])) < 1)
13256          return RESULT_SHOWUSAGE;
13257       for (x = 0; x < NUM_SPANS; x++) {
13258          if (pris[x].trunkgroup == trunkgroup) {
13259             pri = pris + x;
13260             break;
13261          }
13262       }
13263       if (pri) {
13264          start = pri->crvs;
13265          lock = &pri->lock;
13266       } else {
13267          ast_cli(fd, "No such trunk group %d\n", trunkgroup);
13268          return RESULT_FAILURE;
13269       }
13270    } else
13271 #endif
13272    if (argc != 3)
13273       return RESULT_SHOWUSAGE;
13274 
13275    ast_mutex_lock(lock);
13276 #ifdef HAVE_PRI
13277    ast_cli(fd, FORMAT2, pri ? "CRV" : "Chan", "Extension", "Context", "Language", "MOH Interpret");
13278 #else
13279    ast_cli(fd, FORMAT2, "Chan", "Extension", "Context", "Language", "MOH Interpret");
13280 #endif   
13281    
13282    tmp = start;
13283    while (tmp) {
13284       if (tmp->channel > 0) {
13285          snprintf(tmps, sizeof(tmps), "%d", tmp->channel);
13286       } else
13287          ast_copy_string(tmps, "pseudo", sizeof(tmps));
13288       ast_cli(fd, FORMAT, tmps, tmp->exten, tmp->context, tmp->language, tmp->mohinterpret);
13289       tmp = tmp->next;
13290    }
13291    ast_mutex_unlock(lock);
13292    return RESULT_SUCCESS;
13293 #undef FORMAT
13294 #undef FORMAT2
13295 }
13296 
13297 static int dahdi_show_channel(int fd, int argc, char **argv)
13298 {
13299    int channel;
13300    struct dahdi_pvt *tmp = NULL;
13301    struct dahdi_confinfo ci;
13302    struct dahdi_params ps;
13303    int x;
13304    ast_mutex_t *lock;
13305    struct dahdi_pvt *start;
13306 #ifdef HAVE_PRI
13307    char *c;
13308    int trunkgroup;
13309    struct dahdi_pri *pri=NULL;
13310 #endif
13311 
13312    lock = &iflock;
13313    start = iflist;
13314 
13315    if (argc != 4)
13316       return RESULT_SHOWUSAGE;
13317 #ifdef HAVE_PRI
13318    if ((c = strchr(argv[3], ':'))) {
13319       if (sscanf(argv[3], "%30d:%30d", &trunkgroup, &channel) != 2)
13320          return RESULT_SHOWUSAGE;
13321       if ((trunkgroup < 1) || (channel < 1))
13322          return RESULT_SHOWUSAGE;
13323       for (x = 0; x < NUM_SPANS; x++) {
13324          if (pris[x].trunkgroup == trunkgroup) {
13325             pri = pris + x;
13326             break;
13327          }
13328       }
13329       if (pri) {
13330          start = pri->crvs;
13331          lock = &pri->lock;
13332       } else {
13333          ast_cli(fd, "No such trunk group %d\n", trunkgroup);
13334          return RESULT_FAILURE;
13335       }
13336    } else
13337 #endif
13338       channel = atoi(argv[3]);
13339 
13340    ast_mutex_lock(lock);
13341    tmp = start;
13342    while (tmp) {
13343       if (tmp->channel == channel) {
13344 #ifdef HAVE_PRI
13345          if (pri) 
13346             ast_cli(fd, "Trunk/CRV: %d/%d\n", trunkgroup, tmp->channel);
13347          else
13348 #endif         
13349          ast_cli(fd, "Channel: %d\n", tmp->channel);
13350          ast_cli(fd, "File Descriptor: %d\n", tmp->subs[SUB_REAL].dfd);
13351          ast_cli(fd, "Span: %d\n", tmp->span);
13352          ast_cli(fd, "Extension: %s\n", tmp->exten);
13353          ast_cli(fd, "Dialing: %s\n", tmp->dialing ? "yes" : "no");
13354          ast_cli(fd, "Context: %s\n", tmp->context);
13355          ast_cli(fd, "Caller ID: %s\n", tmp->cid_num);
13356          ast_cli(fd, "Calling TON: %d\n", tmp->cid_ton);
13357          ast_cli(fd, "Caller ID name: %s\n", tmp->cid_name);
13358          ast_cli(fd, "Destroy: %d\n", tmp->destroy);
13359          ast_cli(fd, "InAlarm: %d\n", tmp->inalarm);
13360          ast_cli(fd, "Signalling Type: %s\n", sig2str(tmp->sig));
13361          ast_cli(fd, "Radio: %d\n", tmp->radio);
13362          ast_cli(fd, "Owner: %s\n", tmp->owner ? tmp->owner->name : "<None>");
13363          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)" : "");
13364          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)" : "");
13365          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)" : "");
13366          ast_cli(fd, "Confno: %d\n", tmp->confno);
13367          ast_cli(fd, "Propagated Conference: %d\n", tmp->propconfno);
13368          ast_cli(fd, "Real in conference: %d\n", tmp->inconference);
13369          ast_cli(fd, "DSP: %s\n", tmp->dsp ? "yes" : "no");
13370          ast_cli(fd, "Relax DTMF: %s\n", tmp->dtmfrelax ? "yes" : "no");
13371          ast_cli(fd, "Dialing/CallwaitCAS: %d/%d\n", tmp->dialing, tmp->callwaitcas);
13372          ast_cli(fd, "Default law: %s\n", tmp->law == DAHDI_LAW_MULAW ? "ulaw" : tmp->law == DAHDI_LAW_ALAW ? "alaw" : "unknown");
13373          ast_cli(fd, "Fax Handled: %s\n", tmp->faxhandled ? "yes" : "no");
13374          ast_cli(fd, "Pulse phone: %s\n", tmp->pulsedial ? "yes" : "no");
13375          ast_cli(fd, "Echo Cancellation: %d taps%s, currently %s\n", tmp->echocancel, tmp->echocanbridged ? "" : " unless TDM bridged", tmp->echocanon ? "ON" : "OFF");
13376          if (tmp->master)
13377             ast_cli(fd, "Master Channel: %d\n", tmp->master->channel);
13378          for (x = 0; x < MAX_SLAVES; x++) {
13379             if (tmp->slaves[x])
13380                ast_cli(fd, "Slave Channel: %d\n", tmp->slaves[x]->channel);
13381          }
13382 
13383 #ifdef HAVE_OPENR2
13384          if (tmp->mfcr2) {
13385             char calldir[OR2_MAX_PATH];
13386             openr2_context_t *r2context = openr2_chan_get_context(tmp->r2chan);
13387             openr2_variant_t r2variant = openr2_context_get_variant(r2context);
13388             ast_cli(fd, "MFC/R2 Call: %s\n", tmp->mfcr2call ? "Yes" : "No");
13389             ast_cli(fd, "MFC/R2 Blocked: %s\n", tmp->mfcr2block ? "Yes" : "No");
13390             ast_cli(fd, "MFC/R2 MF State: %s\n", openr2_chan_get_mf_state_string(tmp->r2chan));
13391             ast_cli(fd, "MFC/R2 MF Group: %s\n", openr2_chan_get_mf_group_string(tmp->r2chan));
13392             ast_cli(fd, "MFC/R2 State: %s\n", openr2_chan_get_r2_state_string(tmp->r2chan));
13393             ast_cli(fd, "MFC/R2 Call State: %s\n", openr2_chan_get_call_state_string(tmp->r2chan));
13394             ast_cli(fd, "MFC/R2 Call Files Enabled: %s\n", openr2_chan_get_call_files_enabled(tmp->r2chan) ? "Yes" : "No");
13395             ast_cli(fd, "MFC/R2 Variant: %s\n", openr2_proto_get_variant_string(r2variant));
13396             ast_cli(fd, "MFC/R2 Max ANI: %d\n", openr2_context_get_max_ani(r2context));
13397             ast_cli(fd, "MFC/R2 Max DNIS: %d\n", openr2_context_get_max_dnis(r2context));
13398 #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 2
13399             ast_cli(fd, "MFC/R2 DTMF Dialing: %s\n", openr2_context_get_dtmf_dialing(r2context, NULL, NULL) ? "Yes" : "No");
13400             ast_cli(fd, "MFC/R2 DTMF Detection: %s\n", openr2_context_get_dtmf_detection(r2context) ? "Yes" : "No");
13401 #endif
13402             ast_cli(fd, "MFC/R2 Get ANI First: %s\n", openr2_context_get_ani_first(r2context) ? "Yes" : "No");
13403             ast_cli(fd, "MFC/R2 Skip Category: %s\n", openr2_context_get_skip_category_request(r2context) ? "Yes" : "No");
13404             ast_cli(fd, "MFC/R2 Immediate Accept: %s\n", openr2_context_get_immediate_accept(r2context) ? "Yes" : "No");
13405             ast_cli(fd, "MFC/R2 Accept On Offer: %s\n", tmp->mfcr2_accept_on_offer ? "Yes" : "No");
13406             ast_cli(fd, "MFC/R2 Charge Calls: %s\n", tmp->mfcr2_charge_calls ? "Yes" : "No");
13407             ast_cli(fd, "MFC/R2 Allow Collect Calls: %s\n", tmp->mfcr2_allow_collect_calls ? "Yes" : "No");
13408             ast_cli(fd, "MFC/R2 Forced Release: %s\n", tmp->mfcr2_forced_release ? "Yes" : "No");
13409             ast_cli(fd, "MFC/R2 MF Back Timeout: %dms\n", openr2_context_get_mf_back_timeout(r2context));
13410             ast_cli(fd, "MFC/R2 R2 Metering Pulse Timeout: %dms\n", openr2_context_get_metering_pulse_timeout(r2context));
13411             ast_cli(fd, "MFC/R2 Rx CAS: %s\n", openr2_chan_get_rx_cas_string(tmp->r2chan));
13412             ast_cli(fd, "MFC/R2 Tx CAS : %s\n", openr2_chan_get_tx_cas_string(tmp->r2chan));
13413             ast_cli(fd, "MFC/R2 MF Tx Signal: %d\n", openr2_chan_get_tx_mf_signal(tmp->r2chan));
13414             ast_cli(fd, "MFC/R2 MF Rx Signal: %d\n", openr2_chan_get_rx_mf_signal(tmp->r2chan));
13415             ast_cli(fd, "MFC/R2 Call Files Directory: %s\n", openr2_context_get_log_directory(r2context, calldir, sizeof(calldir)));
13416          }
13417 #endif
13418 
13419 #ifdef HAVE_PRI
13420          if (tmp->pri) {
13421             ast_cli(fd, "PRI Flags: ");
13422             if (tmp->resetting)
13423                ast_cli(fd, "Resetting ");
13424             if (tmp->call)
13425                ast_cli(fd, "Call ");
13426             if (tmp->bearer)
13427                ast_cli(fd, "Bearer ");
13428             if (tmp->allocated) {
13429                ast_cli(fd, "Allocated ");
13430             }
13431             ast_cli(fd, "\n");
13432             if (tmp->logicalspan) 
13433                ast_cli(fd, "PRI Logical Span: %d\n", tmp->logicalspan);
13434             else
13435                ast_cli(fd, "PRI Logical Span: Implicit\n");
13436          }
13437 #endif
13438          memset(&ci, 0, sizeof(ci));
13439          ps.channo = tmp->channel;
13440          if (tmp->subs[SUB_REAL].dfd > -1) {
13441             memset(&ci, 0, sizeof(ci));
13442             if (!ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GETCONF, &ci)) {
13443                ast_cli(fd, "Actual Confinfo: Num/%d, Mode/0x%04x\n", ci.confno, ci.confmode);
13444             }
13445 #ifdef DAHDI_GETCONFMUTE
13446             if (!ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GETCONFMUTE, &x)) {
13447                ast_cli(fd, "Actual Confmute: %s\n", x ? "Yes" : "No");
13448             }
13449 #endif
13450             memset(&ps, 0, sizeof(ps));
13451             if (ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &ps) < 0) {
13452                ast_log(LOG_WARNING, "Failed to get parameters on channel %d: %s\n", tmp->channel, strerror(errno));
13453             } else {
13454                ast_cli(fd, "Hookstate (FXS only): %s\n", ps.rxisoffhook ? "Offhook" : "Onhook");
13455             }
13456          }
13457          if (ISTRUNK(tmp)) {
13458             ast_cli(fd, "Call Progress: %s\n", tmp->callprogress ? "yes" : "no");  
13459             if (!ast_strlen_zero(progzone))
13460                ast_cli(fd, "Progress Zone: %s\n", progzone);
13461             ast_cli(fd, "Busy Detect: %s\n", tmp->busydetect ? "yes" : "no");  
13462             if(tmp->busydetect) {
13463                ast_cli(fd, "Busy Count: %d\n", tmp->busycount);
13464                if(tmp->busytonelength > 0) {
13465                   ast_cli(fd, "Busy Pattern:\n");
13466                   ast_cli(fd, " -- Tone Length: %6d ms\n", tmp->busytonelength);
13467                   if (tmp->busyquietlength > 0) 
13468                      ast_cli(fd, " -- Quiet Length: %6d ms\n", tmp->busyquietlength);
13469                   else 
13470                      ast_cli(fd, " -- Detect Tone Only\n");
13471                   if(tmp->busyfuzziness > 0)
13472                      ast_cli(fd, "Busy Pattern Fuziness: %d\n", tmp->busyfuzziness);
13473                }
13474             }
13475          }
13476          ast_mutex_unlock(lock);
13477          return RESULT_SUCCESS;
13478       }
13479       tmp = tmp->next;
13480    }
13481    
13482    ast_cli(fd, "Unable to find given channel %d\n", channel);
13483    ast_mutex_unlock(lock);
13484    return RESULT_FAILURE;
13485 }
13486 
13487 static char dahdi_show_cadences_usage[] =
13488 "Usage: dahdi show cadences\n"
13489 "       Shows all cadences currently defined\n";
13490 
13491 static int handle_dahdi_show_cadences(int fd, int argc, char *argv[])
13492 {
13493    int i, j;
13494    for (i = 0; i < num_cadence; i++) {
13495       char output[1024];
13496       char tmp[16], tmp2[64];
13497       snprintf(tmp, sizeof(tmp), "r%d: ", i + 1);
13498       term_color(output, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(output));
13499 
13500       for (j = 0; j < 16; j++) {
13501          if (cadences[i].ringcadence[j] == 0)
13502             break;
13503          snprintf(tmp, sizeof(tmp), "%d", cadences[i].ringcadence[j]);
13504          if (cidrings[i] * 2 - 1 == j)
13505             term_color(tmp2, tmp, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp2) - 1);
13506          else
13507             term_color(tmp2, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(tmp2) - 1);
13508          if (j != 0)
13509             strncat(output, ",", sizeof(output) - strlen(output) - 1);
13510          strncat(output, tmp2, sizeof(output) - strlen(output) - 1);
13511       }
13512       ast_cli(fd,"%s\n",output);
13513    }
13514    return 0;
13515 }
13516 
13517 /* Based on irqmiss.c */
13518 static int dahdi_show_status(int fd, int argc, char *argv[]) {
13519    #define FORMAT "%-40.40s %-10.10s %-10d %-10d %-10d\n"
13520    #define FORMAT2 "%-40.40s %-10.10s %-10.10s %-10.10s %-10.10s\n"
13521 
13522    int span;
13523    int res;
13524    char alarms[50];
13525 
13526    int ctl;
13527    struct dahdi_spaninfo s;
13528 
13529    if ((ctl = open(DAHDI_FILE_CTL, O_RDWR)) < 0) {
13530       ast_log(LOG_WARNING, "Unable to open " DAHDI_FILE_CTL ": %s\n", strerror(errno));
13531       ast_cli(fd, "No " DAHDI_NAME " interface found.\n");
13532       return RESULT_FAILURE;
13533    }
13534    ast_cli(fd, FORMAT2, "Description", "Alarms", "IRQ", "bpviol", "CRC4");
13535 
13536    for (span = 1; span < DAHDI_MAX_SPANS; ++span) {
13537       s.spanno = span;
13538       res = ioctl(ctl, DAHDI_SPANSTAT, &s);
13539       if (res) {
13540          continue;
13541       }
13542       alarms[0] = '\0';
13543       if (s.alarms > 0) {
13544          if (s.alarms & DAHDI_ALARM_BLUE)
13545             strcat(alarms, "BLU/");
13546          if (s.alarms & DAHDI_ALARM_YELLOW)
13547             strcat(alarms, "YEL/");
13548          if (s.alarms & DAHDI_ALARM_RED)
13549             strcat(alarms, "RED/");
13550          if (s.alarms & DAHDI_ALARM_LOOPBACK)
13551             strcat(alarms, "LB/");
13552          if (s.alarms & DAHDI_ALARM_RECOVER)
13553             strcat(alarms, "REC/");
13554          if (s.alarms & DAHDI_ALARM_NOTOPEN)
13555             strcat(alarms, "NOP/");
13556          if (!strlen(alarms))
13557             strcat(alarms, "UUU/");
13558          if (strlen(alarms)) {
13559             /* Strip trailing / */
13560             alarms[strlen(alarms) - 1] = '\0';
13561          }
13562       } else {
13563          if (s.numchans)
13564             strcpy(alarms, "OK");
13565          else
13566             strcpy(alarms, "UNCONFIGURED");
13567       }
13568 
13569       ast_cli(fd, FORMAT, s.desc, alarms, s.irqmisses, s.bpvcount, s.crc4count);
13570    }
13571    close(ctl);
13572 
13573    return RESULT_SUCCESS;
13574 #undef FORMAT
13575 #undef FORMAT2
13576 }
13577 
13578 static char show_channels_usage[] =
13579    "Usage: dahdi show channels\n"
13580    "  Shows a list of available channels\n";
13581 
13582 static char show_channel_usage[] =
13583    "Usage: dahdi show channel <chan num>\n"
13584    "  Detailed information about a given channel\n";
13585 
13586 static char dahdi_show_status_usage[] =
13587    "Usage: dahdi show status\n"
13588    "       Shows a list of DAHDI cards with status\n";
13589 
13590 static char destroy_channel_usage[] =
13591    "Usage: dahdi destroy channel <chan num>\n"
13592    "  DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING.  Immediately removes a given channel, whether it is in use or not\n";
13593 
13594 static char dahdi_restart_usage[] =
13595    "Usage: dahdi restart\n"
13596    "  Restarts the DAHDI channels: destroys them all and then\n"
13597    "  re-reads them from chan_dahdi.conf.\n"
13598    "  Note that this will STOP any running CALL on DAHDI channels.\n"
13599    "";
13600 
13601 static struct ast_cli_entry cli_zap_show_cadences_deprecated = {
13602    { "zap", "show", "cadences", NULL },
13603    handle_dahdi_show_cadences, NULL,
13604    NULL };
13605 
13606 static struct ast_cli_entry cli_zap_show_channels_deprecated = {
13607    { "zap", "show", "channels", NULL },
13608    dahdi_show_channels, NULL,
13609    NULL };
13610 
13611 static struct ast_cli_entry cli_zap_show_channel_deprecated = {
13612    { "zap", "show", "channel", NULL },
13613    dahdi_show_channel, NULL,
13614    NULL };
13615 
13616 static struct ast_cli_entry cli_zap_destroy_channel_deprecated = {
13617    { "zap", "destroy", "channel", NULL },
13618    dahdi_destroy_channel, NULL,
13619    NULL };
13620 
13621 static struct ast_cli_entry cli_zap_restart_deprecated = {
13622    { "zap", "restart", NULL },
13623    dahdi_restart_cmd, NULL,
13624    NULL };
13625 
13626 static struct ast_cli_entry cli_zap_show_status_deprecated = {
13627    { "zap", "show", "status", NULL },
13628    dahdi_show_status, NULL,
13629    NULL };
13630 
13631 static struct ast_cli_entry dahdi_cli[] = {
13632    { { "dahdi", "show", "cadences", NULL },
13633    handle_dahdi_show_cadences, "List cadences",
13634    dahdi_show_cadences_usage, NULL, &cli_zap_show_cadences_deprecated },
13635 
13636    { { "dahdi", "show", "channels", NULL},
13637    dahdi_show_channels, "Show active DAHDI channels",
13638    show_channels_usage, NULL, &cli_zap_show_channels_deprecated },
13639 
13640    { { "dahdi", "show", "channel", NULL},
13641    dahdi_show_channel, "Show information on a channel",
13642    show_channel_usage, NULL, &cli_zap_show_channel_deprecated },
13643 
13644    { { "dahdi", "destroy", "channel", NULL},
13645    dahdi_destroy_channel, "Destroy a channel",
13646    destroy_channel_usage, NULL, &cli_zap_destroy_channel_deprecated },
13647 
13648    { { "dahdi", "restart", NULL},
13649    dahdi_restart_cmd, "Fully restart DAHDI channels",
13650    dahdi_restart_usage, NULL, &cli_zap_restart_deprecated },
13651 
13652    { { "dahdi", "show", "status", NULL},
13653    dahdi_show_status, "Show all DAHDI cards status",
13654    dahdi_show_status_usage, NULL, &cli_zap_show_status_deprecated },
13655 };
13656 
13657 #define TRANSFER  0
13658 #define HANGUP    1
13659 
13660 static int dahdi_fake_event(struct dahdi_pvt *p, int mode)
13661 {
13662    if (p) {
13663       switch (mode) {
13664          case TRANSFER:
13665             p->fake_event = DAHDI_EVENT_WINKFLASH;
13666             break;
13667          case HANGUP:
13668             p->fake_event = DAHDI_EVENT_ONHOOK;
13669             break;
13670          default:
13671             ast_log(LOG_WARNING, "I don't know how to handle transfer event with this: %d on channel %s\n",mode, p->owner->name);   
13672       }
13673    }
13674    return 0;
13675 }
13676 static struct dahdi_pvt *find_channel(int channel)
13677 {
13678    struct dahdi_pvt *p = iflist;
13679    while (p) {
13680       if (p->channel == channel) {
13681          break;
13682       }
13683       p = p->next;
13684    }
13685    return p;
13686 }
13687 
13688 #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)
13689 #define local_astman_header(m, hdr, zap) astman_get_header(m, (!zap) ? "DAHDI" hdr : "Zap" hdr)
13690 
13691 static int __action_dnd(struct mansession *s, const struct message *m, int zap_mode, int dnd)
13692 {
13693    struct dahdi_pvt *p = NULL;
13694    const char *channel = local_astman_header(m, "Channel", zap_mode);
13695 
13696    if (ast_strlen_zero(channel)) {
13697       astman_send_error(s, m, "No channel specified");
13698       return 0;
13699    }
13700    if (!(p = find_channel(atoi(channel)))) {
13701       astman_send_error(s, m, "No such channel");
13702       return 0;
13703    }
13704    p->dnd = dnd;
13705    local_astman_ack(s, m, "DND", zap_mode);
13706 
13707    return 0;
13708 }
13709 
13710 static int zap_action_dndon(struct mansession *s, const struct message *m)
13711 {
13712    return __action_dnd(s, m, 1, 1);
13713 }
13714 
13715 static int dahdi_action_dndon(struct mansession *s, const struct message *m)
13716 {
13717    return __action_dnd(s, m, 0, 1);
13718 }
13719 
13720 static int zap_action_dndoff(struct mansession *s, const struct message *m)
13721 {
13722    return __action_dnd(s, m, 1, 0);
13723 }
13724 
13725 static int dahdi_action_dndoff(struct mansession *s, const struct message *m)
13726 {
13727    return __action_dnd(s, m, 0, 0);
13728 }
13729 
13730 static int __action_transfer(struct mansession *s, const struct message *m, int zap_mode)
13731 {
13732    struct dahdi_pvt *p = NULL;
13733    const char *channel = local_astman_header(m, "Channel", zap_mode);
13734 
13735    if (ast_strlen_zero(channel)) {
13736       astman_send_error(s, m, "No channel specified");
13737       return 0;
13738    }
13739    if (!(p = find_channel(atoi(channel)))) {
13740       astman_send_error(s, m, "No such channel");
13741       return 0;
13742    }
13743    dahdi_fake_event(p,TRANSFER);
13744    local_astman_ack(s, m, "Transfer", zap_mode);
13745 
13746    return 0;
13747 }
13748 
13749 static int zap_action_transfer(struct mansession *s, const struct message *m)
13750 {
13751    return __action_transfer(s, m, 1);
13752 }
13753 
13754 static int dahdi_action_transfer(struct mansession *s, const struct message *m)
13755 {
13756    return __action_transfer(s, m, 0);
13757 }
13758 
13759 static int __action_transferhangup(struct mansession *s, const struct message *m, int zap_mode)
13760 {
13761    struct dahdi_pvt *p = NULL;
13762    const char *channel = local_astman_header(m, "Channel", zap_mode);
13763 
13764    if (ast_strlen_zero(channel)) {
13765       astman_send_error(s, m, "No channel specified");
13766       return 0;
13767    }
13768    if (!(p = find_channel(atoi(channel)))) {
13769       astman_send_error(s, m, "No such channel");
13770       return 0;
13771    }
13772    dahdi_fake_event(p, HANGUP);
13773    local_astman_ack(s, m, "Hangup", zap_mode);
13774    return 0;
13775 }
13776 
13777 static int zap_action_transferhangup(struct mansession *s, const struct message *m)
13778 {
13779    return __action_transferhangup(s, m, 1);
13780 }
13781 
13782 static int dahdi_action_transferhangup(struct mansession *s, const struct message *m)
13783 {
13784    return __action_transferhangup(s, m, 0);
13785 }
13786 
13787 static int __action_dialoffhook(struct mansession *s, const struct message *m, int zap_mode)
13788 {
13789    struct dahdi_pvt *p = NULL;
13790    const char *channel = local_astman_header(m, "Channel", zap_mode);
13791    const char *number = astman_get_header(m, "Number");
13792    int i;
13793 
13794    if (ast_strlen_zero(channel)) {
13795       astman_send_error(s, m, "No channel specified");
13796       return 0;
13797    }
13798    if (ast_strlen_zero(number)) {
13799       astman_send_error(s, m, "No number specified");
13800       return 0;
13801    }
13802    if (!(p = find_channel(atoi(channel)))) {
13803       astman_send_error(s, m, "No such channel");
13804       return 0;
13805    }
13806    if (!p->owner) {
13807       astman_send_error(s, m, "Channel does not have an owner");
13808       return 0;
13809    }
13810    for (i = 0; i < strlen(number); i++) {
13811       struct ast_frame f = { AST_FRAME_DTMF, number[i] };
13812 
13813       dahdi_queue_frame(p, &f, NULL); 
13814    }
13815    local_astman_ack(s, m, "DialOffHook", zap_mode);
13816 
13817    return 0;
13818 }
13819 
13820 static int zap_action_dialoffhook(struct mansession *s, const struct message *m)
13821 {
13822    return __action_dialoffhook(s, m, 1);
13823 }
13824 
13825 static int dahdi_action_dialoffhook(struct mansession *s, const struct message *m)
13826 {
13827    return __action_dialoffhook(s, m, 0);
13828 }
13829 
13830 static int __action_showchannels(struct mansession *s, const struct message *m, int zap_mode)
13831 {
13832    struct dahdi_pvt *tmp = NULL;
13833    const char *id = astman_get_header(m, "ActionID");
13834    char idText[256] = "";
13835 
13836    local_astman_ack(s, m, " channel status will follow", zap_mode);
13837    if (!ast_strlen_zero(id))
13838       snprintf(idText, sizeof(idText) - 1, "ActionID: %s\r\n", id);
13839 
13840    ast_mutex_lock(&iflock);
13841    
13842    tmp = iflist;
13843    while (tmp) {
13844       if (tmp->channel > 0) {
13845          int alarm = get_alarms(tmp);
13846          astman_append(s,
13847                   "Event: %sShowChannels\r\n"
13848                   "Channel: %d\r\n"
13849                   "Signalling: %s\r\n"
13850                   "Context: %s\r\n"
13851                   "DND: %s\r\n"
13852                   "Alarm: %s\r\n"
13853                   "%s"
13854                   "\r\n",
13855                   dahdi_chan_name,
13856                   tmp->channel, sig2str(tmp->sig), tmp->context, 
13857                   tmp->dnd ? "Enabled" : "Disabled",
13858                   alarm2str(alarm), idText);
13859       } 
13860 
13861       tmp = tmp->next;
13862    }
13863 
13864    ast_mutex_unlock(&iflock);
13865    
13866    astman_append(s, 
13867             "Event: %sShowChannelsComplete\r\n"
13868             "%s"
13869             "\r\n",
13870             dahdi_chan_name,
13871             idText);
13872    return 0;
13873 }
13874 
13875 static int zap_action_showchannels(struct mansession *s, const struct message *m)
13876 {
13877    return __action_showchannels(s, m, 1);
13878 }
13879 
13880 static int dahdi_action_showchannels(struct mansession *s, const struct message *m)
13881 {
13882    return __action_showchannels(s, m, 0);
13883 }
13884 
13885 static int __action_restart(struct mansession *s, const struct message *m, int zap_mode)
13886 {
13887    if (dahdi_restart() != 0) {
13888       if (zap_mode) {
13889          astman_send_error(s, m, "Failed to restart Zap");
13890       } else {
13891          astman_send_error(s, m, "Failed to restart DAHDI");
13892       }
13893       return 1;
13894    }
13895    local_astman_ack(s, m, "Restart: Success", zap_mode);
13896    return 0;
13897 }
13898 
13899 static int zap_action_restart(struct mansession *s, const struct message *m)
13900 {
13901    return __action_restart(s, m, 1);
13902 }
13903 
13904 static int dahdi_action_restart(struct mansession *s, const struct message *m)
13905 {
13906    return __action_restart(s, m, 0);
13907 }
13908 
13909 #define local_astman_unregister(a) do { \
13910                if (*dahdi_chan_mode == CHAN_DAHDI_PLUS_ZAP_MODE) { \
13911                   ast_manager_unregister("DAHDI" a); \
13912                } \
13913                ast_manager_unregister("Zap" a); \
13914                } while (0)
13915 
13916 static int __unload_module(void)
13917 {
13918    struct dahdi_pvt *p;
13919 
13920 #ifdef HAVE_OPENR2
13921    int r;
13922 #endif
13923 
13924 #ifdef HAVE_PRI
13925    int i, j;
13926    for (i = 0; i < NUM_SPANS; i++) {
13927       if (pris[i].master != AST_PTHREADT_NULL) 
13928          pthread_cancel(pris[i].master);
13929    }
13930    ast_cli_unregister_multiple(dahdi_pri_cli, sizeof(dahdi_pri_cli) / sizeof(struct ast_cli_entry));
13931 
13932    if (*dahdi_chan_mode == CHAN_DAHDI_PLUS_ZAP_MODE) {
13933       ast_unregister_application(dahdi_send_keypad_facility_app);
13934    }
13935    ast_unregister_application(zap_send_keypad_facility_app);
13936 #endif
13937 
13938 #ifdef HAVE_OPENR2
13939    for (r = 0; r < NUM_SPANS; r++) {
13940       if (r2links[r].master != AST_PTHREADT_NULL) {
13941          pthread_cancel(r2links[r].master);
13942          pthread_join(r2links[r].master, NULL);
13943       }
13944    }
13945    ast_cli_unregister_multiple(dahdi_mfcr2_cli, sizeof(dahdi_mfcr2_cli) / sizeof(dahdi_mfcr2_cli[0]));
13946    if (*dahdi_chan_mode == CHAN_DAHDI_PLUS_ZAP_MODE) {
13947       ast_unregister_application(dahdi_accept_r2_call_app);
13948    }
13949    ast_unregister_application(zap_accept_r2_call_app);
13950 #endif
13951 
13952    ast_cli_unregister_multiple(dahdi_cli, sizeof(dahdi_cli) / sizeof(struct ast_cli_entry));
13953    local_astman_unregister("DialOffHook");
13954    local_astman_unregister("Hangup");
13955    local_astman_unregister("Transfer");
13956    local_astman_unregister("DNDoff");
13957    local_astman_unregister("DNDon");
13958    local_astman_unregister("ShowChannels");
13959    local_astman_unregister("Restart");
13960    ast_channel_unregister(chan_tech);
13961    ast_mutex_lock(&iflock);
13962    /* Hangup all interfaces if they have an owner */
13963    p = iflist;
13964    while (p) {
13965       if (p->owner)
13966          ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
13967       p = p->next;
13968    }
13969    ast_mutex_unlock(&iflock);
13970    ast_mutex_lock(&monlock);
13971    if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) {
13972       pthread_cancel(monitor_thread);
13973       pthread_kill(monitor_thread, SIGURG);
13974       pthread_join(monitor_thread, NULL);
13975    }
13976    monitor_thread = AST_PTHREADT_STOP;
13977    ast_mutex_unlock(&monlock);
13978 
13979    destroy_all_channels();
13980 #ifdef HAVE_PRI      
13981    for (i = 0; i < NUM_SPANS; i++) {
13982       if (pris[i].master && (pris[i].master != AST_PTHREADT_NULL))
13983          pthread_join(pris[i].master, NULL);
13984       for (j = 0; j < NUM_DCHANS; j++) {
13985          dahdi_close_pri_fd(&(pris[i]), j);
13986       }
13987    }
13988 #endif
13989 
13990 #ifdef HAVE_OPENR2
13991    for (r = 0; r < NUM_SPANS; r++) {
13992       if (r2links[r].protocol_context) {
13993          openr2_context_delete(r2links[r].protocol_context);
13994       }
13995    }
13996 #endif
13997 
13998    ast_cond_destroy(&ss_thread_complete);
13999    return 0;
14000 }
14001 
14002 static int unload_module(void)
14003 {
14004 #ifdef HAVE_PRI      
14005    int y;
14006    for (y = 0; y < NUM_SPANS; y++)
14007       ast_mutex_destroy(&pris[y].lock);
14008 #endif
14009    return __unload_module();
14010 }
14011 
14012 static int build_channels(struct dahdi_chan_conf *conf, int iscrv, const char *value, int reload, int lineno, int *found_pseudo)
14013 {
14014    char *c, *chan;
14015    int x, start, finish;
14016    struct dahdi_pvt *tmp;
14017 #ifdef HAVE_PRI
14018    struct dahdi_pri *pri;
14019    int trunkgroup, y;
14020 #endif
14021    
14022    if ((reload == 0) && (conf->chan.sig < 0)) {
14023       ast_log(LOG_ERROR, "Signalling must be specified before any channels are.\n");
14024       return -1;
14025    }
14026 
14027    c = ast_strdupa(value);
14028 
14029 #ifdef HAVE_PRI
14030    pri = NULL;
14031    if (iscrv) {
14032       if (sscanf(c, "%30d:%n", &trunkgroup, &y) != 1) {
14033          ast_log(LOG_WARNING, "CRV must begin with trunkgroup followed by a colon at line %d\n", lineno);
14034          return -1;
14035       }
14036       if (trunkgroup < 1) {
14037          ast_log(LOG_WARNING, "CRV trunk group must be a positive number at line %d\n", lineno);
14038          return -1;
14039       }
14040       c += y;
14041       for (y = 0; y < NUM_SPANS; y++) {
14042          if (pris[y].trunkgroup == trunkgroup) {
14043             pri = pris + y;
14044             break;
14045          }
14046       }
14047       if (!pri) {
14048          ast_log(LOG_WARNING, "No such trunk group %d at CRV declaration at line %d\n", trunkgroup, lineno);
14049          return -1;
14050       }
14051    }
14052 #endif         
14053 
14054    while ((chan = strsep(&c, ","))) {
14055       if (sscanf(chan, "%30d-%30d", &start, &finish) == 2) {
14056          /* Range */
14057       } else if (sscanf(chan, "%30d", &start)) {
14058          /* Just one */
14059          finish = start;
14060       } else if (!strcasecmp(chan, "pseudo")) {
14061          finish = start = CHAN_PSEUDO;
14062          if (found_pseudo)
14063             *found_pseudo = 1;
14064       } else {
14065          ast_log(LOG_ERROR, "Syntax error parsing '%s' at '%s'\n", value, chan);
14066          return -1;
14067       }
14068       if (finish < start) {
14069          ast_log(LOG_WARNING, "Sillyness: %d < %d\n", start, finish);
14070          x = finish;
14071          finish = start;
14072          start = x;
14073       }
14074 
14075       for (x = start; x <= finish; x++) {
14076 #ifdef HAVE_PRI
14077          tmp = mkintf(x, conf, pri, reload);
14078 #else       
14079          tmp = mkintf(x, conf, NULL, reload);
14080 #endif         
14081 
14082          if (tmp) {
14083             if (option_verbose > 2) {
14084 #ifdef HAVE_PRI
14085                if (pri)
14086                   ast_verbose(VERBOSE_PREFIX_3 "%s CRV %d:%d, %s signalling\n", reload ? "Reconfigured" : "Registered", trunkgroup, x, sig2str(tmp->sig));
14087                else
14088 #endif
14089                   ast_verbose(VERBOSE_PREFIX_3 "%s channel %d, %s signalling\n", reload ? "Reconfigured" : "Registered", x, sig2str(tmp->sig));
14090             }
14091          } else {
14092             ast_log(LOG_ERROR, "Unable to %s channel '%s'\n",
14093                (reload == 1) ? "reconfigure" : "register", value);
14094             return -1;
14095          }
14096       }
14097 
14098 #ifdef HAVE_OPENR2
14099       if (reload != 1 && r2links[mfcr2_cur_context_index].protocol_context) {
14100          mfcr2_cur_context_index++;
14101       }  
14102 #endif
14103 
14104    }
14105 
14106    return 0;
14107 }
14108 
14109 /** The length of the parameters list of 'dahdichan'. 
14110  * \todo Move definition of MAX_CHANLIST_LEN to a proper place. */
14111 #define MAX_CHANLIST_LEN 80
14112 static int process_dahdi(struct dahdi_chan_conf *confp, const char *cat, struct ast_variable *v, int reload, int skipchannels)
14113 {
14114    struct dahdi_pvt *tmp;
14115    int y;
14116    int found_pseudo = 0;
14117         char dahdichan[MAX_CHANLIST_LEN] = {};
14118 
14119    for (; v; v = v->next) {
14120       if (!ast_jb_read_conf(&global_jbconf, v->name, v->value))
14121          continue;
14122 
14123       /* Create the interface list */
14124       if (!strcasecmp(v->name, "channel")
14125 #ifdef HAVE_PRI
14126           || !strcasecmp(v->name, "crv")
14127 #endif         
14128          ) {
14129          int iscrv;
14130          if (skipchannels)
14131             continue;
14132          iscrv = !strcasecmp(v->name, "crv");
14133          if (build_channels(confp, iscrv, v->value, reload, v->lineno, &found_pseudo))
14134                return -1;
14135       } else if (!strcasecmp(v->name, "zapchan") || !strcasecmp(v->name, "dahdichan")) {
14136          ast_copy_string(dahdichan, v->value, sizeof(dahdichan));
14137          if (v->name[0] == 'z' || v->name[0] == 'Z') {
14138             ast_log(LOG_WARNING, "Option zapchan has been deprecated in favor of dahdichan (found in [%s])\n", cat);
14139          }
14140       } else if (!strcasecmp(v->name, "buffers")) {
14141          if (parse_buffers_policy(v->value, &confp->chan.buf_no, &confp->chan.buf_policy)) {
14142             ast_log(LOG_WARNING, "Using default buffer policy.\n");
14143             confp->chan.buf_no = numbufs;
14144             confp->chan.buf_policy = DAHDI_POLICY_IMMEDIATE;
14145          }
14146       } else if (!strcasecmp(v->name, "usedistinctiveringdetection")) {
14147          if (ast_true(v->value))
14148             confp->chan.usedistinctiveringdetection = 1;
14149       } else if (!strcasecmp(v->name, "distinctiveringaftercid")) {
14150          if (ast_true(v->value))
14151             distinctiveringaftercid = 1;
14152       } else if (!strcasecmp(v->name, "dring1context")) {
14153          ast_copy_string(drings.ringContext[0].contextData, v->value, sizeof(drings.ringContext[0].contextData));
14154       } else if (!strcasecmp(v->name, "dring2context")) {
14155          ast_copy_string(drings.ringContext[1].contextData, v->value, sizeof(drings.ringContext[1].contextData));
14156       } else if (!strcasecmp(v->name, "dring3context")) {
14157          ast_copy_string(drings.ringContext[2].contextData, v->value, sizeof(drings.ringContext[2].contextData));
14158       } else if (!strcasecmp(v->name, "dring1")) {
14159          sscanf(v->value, "%30d,%30d,%30d", &drings.ringnum[0].ring[0], &drings.ringnum[0].ring[1], &drings.ringnum[0].ring[2]);
14160       } else if (!strcasecmp(v->name, "dring2")) {
14161          sscanf(v->value, "%30d,%30d,%30d", &drings.ringnum[1].ring[0], &drings.ringnum[1].ring[1], &drings.ringnum[1].ring[2]);
14162       } else if (!strcasecmp(v->name, "dring3")) {
14163          sscanf(v->value, "%30d,%30d,%30d", &drings.ringnum[2].ring[0], &drings.ringnum[2].ring[1], &drings.ringnum[2].ring[2]);
14164       } else if (!strcasecmp(v->name, "usecallerid")) {
14165          confp->chan.use_callerid = ast_true(v->value);
14166       } else if (!strcasecmp(v->name, "cidsignalling")) {
14167          if (!strcasecmp(v->value, "bell"))
14168             confp->chan.cid_signalling = CID_SIG_BELL;
14169          else if (!strcasecmp(v->value, "v23"))
14170             confp->chan.cid_signalling = CID_SIG_V23;
14171          else if (!strcasecmp(v->value, "dtmf"))
14172             confp->chan.cid_signalling = CID_SIG_DTMF;
14173          else if (!strcasecmp(v->value, "smdi"))
14174             confp->chan.cid_signalling = CID_SIG_SMDI;
14175          else if (!strcasecmp(v->value, "v23_jp"))
14176             confp->chan.cid_signalling = CID_SIG_V23_JP;
14177          else if (ast_true(v->value))
14178             confp->chan.cid_signalling = CID_SIG_BELL;
14179       } else if (!strcasecmp(v->name, "cidstart")) {
14180          if (!strcasecmp(v->value, "ring"))
14181             confp->chan.cid_start = CID_START_RING;
14182          else if (!strcasecmp(v->value, "polarity"))
14183             confp->chan.cid_start = CID_START_POLARITY;
14184          else if (!strcasecmp(v->value, "dtmf"))
14185             confp->chan.cid_start = CID_START_DTMF_NOALERT;
14186          else if (ast_true(v->value))
14187             confp->chan.cid_start = CID_START_RING;
14188       } else if (!strcasecmp(v->name, "threewaycalling")) {
14189          confp->chan.threewaycalling = ast_true(v->value);
14190       } else if (!strcasecmp(v->name, "cancallforward")) {
14191          confp->chan.cancallforward = ast_true(v->value);
14192       } else if (!strcasecmp(v->name, "relaxdtmf")) {
14193          if (ast_true(v->value)) 
14194             confp->chan.dtmfrelax = DSP_DIGITMODE_RELAXDTMF;
14195          else
14196             confp->chan.dtmfrelax = 0;
14197       } else if (!strcasecmp(v->name, "mailbox")) {
14198          ast_copy_string(confp->chan.mailbox, v->value, sizeof(confp->chan.mailbox));
14199       } else if (!strcasecmp(v->name, "hasvoicemail")) {
14200          if (ast_true(v->value) && ast_strlen_zero(confp->chan.mailbox)) {
14201             ast_copy_string(confp->chan.mailbox, cat, sizeof(confp->chan.mailbox));
14202          }
14203       } else if (!strcasecmp(v->name, "adsi")) {
14204          confp->chan.adsi = ast_true(v->value);
14205       } else if (!strcasecmp(v->name, "usesmdi")) {
14206          confp->chan.use_smdi = ast_true(v->value);
14207       } else if (!strcasecmp(v->name, "smdiport")) {
14208          ast_copy_string(confp->smdi_port, v->value, sizeof(confp->smdi_port));
14209       } else if (!strcasecmp(v->name, "transfer")) {
14210          confp->chan.transfer = ast_true(v->value);
14211       } else if (!strcasecmp(v->name, "canpark")) {
14212          confp->chan.canpark = ast_true(v->value);
14213       } else if (!strcasecmp(v->name, "echocancelwhenbridged")) {
14214          confp->chan.echocanbridged = ast_true(v->value);
14215       } else if (!strcasecmp(v->name, "busydetect")) {
14216          confp->chan.busydetect = ast_true(v->value);
14217       } else if (!strcasecmp(v->name, "busycount")) {
14218          confp->chan.busycount = atoi(v->value);
14219       } else if (!strcasecmp(v->name, "silencethreshold")) {
14220             confp->chan.silencethreshold = atoi(v->value);
14221       } else if (!strcasecmp(v->name, "busycompare")) {
14222             confp->chan.busycompare = ast_true(v->value);
14223       } else if (!strcasecmp(v->name, "busypattern")) {
14224          int count = sscanf(v->value, "%30d,%30d", &confp->chan.busytonelength, &confp->chan.busyquietlength);
14225          if (count == 1)
14226             confp->chan.busyquietlength = 0;
14227          else if (count < 1)
14228                ast_log(LOG_ERROR, "busypattern= expects busypattern=tonelength[,quietlength]\n");
14229       } else if (!strcasecmp(v->name, "busyfuzziness")) {
14230             confp->chan.busyfuzziness = atoi(v->value);
14231       } else if (!strcasecmp(v->name, "callprogress")) {
14232          if (ast_true(v->value))
14233             confp->chan.callprogress |= 1;
14234          else
14235             confp->chan.callprogress &= ~1;
14236       } else if (!strcasecmp(v->name, "faxdetect")) {
14237          if (!strcasecmp(v->value, "incoming")) {
14238             confp->chan.callprogress |= 4;
14239             confp->chan.callprogress &= ~2;
14240          } else if (!strcasecmp(v->value, "outgoing")) {
14241             confp->chan.callprogress &= ~4;
14242             confp->chan.callprogress |= 2;
14243          } else if (!strcasecmp(v->value, "both") || ast_true(v->value))
14244             confp->chan.callprogress |= 6;
14245          else
14246             confp->chan.callprogress &= ~6;
14247       } else if (!strcasecmp(v->name, "echocancel")) {
14248          if (!ast_strlen_zero(v->value)) {
14249             y = atoi(v->value);
14250          } else
14251             y = 0;
14252          if ((y == 32) || (y == 64) || (y == 128) || (y == 256) || (y == 512) || (y == 1024))
14253             confp->chan.echocancel = y;
14254          else {
14255             confp->chan.echocancel = ast_true(v->value);
14256             if (confp->chan.echocancel)
14257                confp->chan.echocancel=128;
14258          }
14259       } else if (!strcasecmp(v->name, "echotraining")) {
14260          if (sscanf(v->value, "%30d", &y) == 1) {
14261             if ((y < 10) || (y > 4000)) {
14262                ast_log(LOG_WARNING, "Echo training time must be within the range of 10 to 4000 ms at line %d\n", v->lineno);              
14263             } else {
14264                confp->chan.echotraining = y;
14265             }
14266          } else if (ast_true(v->value)) {
14267             confp->chan.echotraining = 400;
14268          } else
14269             confp->chan.echotraining = 0;
14270       } else if (!strcasecmp(v->name, "hidecallerid")) {
14271          confp->chan.hidecallerid = ast_true(v->value);
14272       } else if (!strcasecmp(v->name, "hidecalleridname")) {
14273          confp->chan.hidecalleridname = ast_true(v->value);
14274       } else if (!strcasecmp(v->name, "pulsedial")) {
14275          confp->chan.pulse = ast_true(v->value);
14276       } else if (!strcasecmp(v->name, "callreturn")) {
14277          confp->chan.callreturn = ast_true(v->value);
14278       } else if (!strcasecmp(v->name, "callwaiting")) {
14279          confp->chan.callwaiting = ast_true(v->value);
14280       } else if (!strcasecmp(v->name, "callwaitingcallerid")) {
14281          confp->chan.callwaitingcallerid = ast_true(v->value);
14282       } else if (!strcasecmp(v->name, "context")) {
14283          ast_copy_string(confp->chan.context, v->value, sizeof(confp->chan.context));
14284       } else if (!strcasecmp(v->name, "language")) {
14285          ast_copy_string(confp->chan.language, v->value, sizeof(confp->chan.language));
14286       } else if (!strcasecmp(v->name, "progzone")) {
14287          ast_copy_string(progzone, v->value, sizeof(progzone));
14288       } else if (!strcasecmp(v->name, "mohinterpret") 
14289          ||!strcasecmp(v->name, "musiconhold") || !strcasecmp(v->name, "musicclass")) {
14290          ast_copy_string(confp->chan.mohinterpret, v->value, sizeof(confp->chan.mohinterpret));
14291       } else if (!strcasecmp(v->name, "mohsuggest")) {
14292          ast_copy_string(confp->chan.mohsuggest, v->value, sizeof(confp->chan.mohsuggest));
14293       } else if (!strcasecmp(v->name, "stripmsd")) {
14294          confp->chan.stripmsd = atoi(v->value);
14295       } else if (!strcasecmp(v->name, "jitterbuffers")) {
14296          numbufs = atoi(v->value);
14297       } else if (!strcasecmp(v->name, "group")) {
14298          confp->chan.group = ast_get_group(v->value);
14299       } else if (!strcasecmp(v->name, "callgroup")) {
14300          confp->chan.callgroup = ast_get_group(v->value);
14301       } else if (!strcasecmp(v->name, "pickupgroup")) {
14302          confp->chan.pickupgroup = ast_get_group(v->value);
14303       } else if (!strcasecmp(v->name, "immediate")) {
14304          confp->chan.immediate = ast_true(v->value);
14305       } else if (!strcasecmp(v->name, "transfertobusy")) {
14306          confp->chan.transfertobusy = ast_true(v->value);
14307       } else if (!strcasecmp(v->name, "rxgain")) {
14308          if (sscanf(v->value, "%30f", &confp->chan.rxgain) != 1) {
14309             ast_log(LOG_WARNING, "Invalid rxgain: %s\n", v->value);
14310          }
14311       } else if (!strcasecmp(v->name, "txgain")) {
14312          if (sscanf(v->value, "%30f", &confp->chan.txgain) != 1) {
14313             ast_log(LOG_WARNING, "Invalid txgain: %s\n", v->value);
14314          }
14315       } else if (!strcasecmp(v->name, "tonezone")) {
14316          if (sscanf(v->value, "%30d", &confp->chan.tonezone) != 1) {
14317             ast_log(LOG_WARNING, "Invalid tonezone: %s\n", v->value);
14318          }
14319       } else if (!strcasecmp(v->name, "callerid")) {
14320          if (!strcasecmp(v->value, "asreceived")) {
14321             confp->chan.cid_num[0] = '\0';
14322             confp->chan.cid_name[0] = '\0';
14323          } else {
14324             ast_callerid_split(v->value, confp->chan.cid_name, sizeof(confp->chan.cid_name), confp->chan.cid_num, sizeof(confp->chan.cid_num));
14325          } 
14326       } else if (!strcasecmp(v->name, "fullname")) {
14327          ast_copy_string(confp->chan.cid_name, v->value, sizeof(confp->chan.cid_name));
14328       } else if (!strcasecmp(v->name, "cid_number")) {
14329          ast_copy_string(confp->chan.cid_num, v->value, sizeof(confp->chan.cid_num));
14330       } else if (!strcasecmp(v->name, "useincomingcalleridondahditransfer") || !strcasecmp(v->name, "useincomingcalleridonzaptransfer")) {
14331          confp->chan.dahditrcallerid = ast_true(v->value);
14332          if (strstr(v->name, "zap")) {
14333             ast_log(LOG_WARNING, "Option useincomingcalleridonzaptransfer has been deprecated in favor of useincomingcalleridondahditransfer (in [%s]).\n", cat);
14334          }
14335       } else if (!strcasecmp(v->name, "restrictcid")) {
14336          confp->chan.restrictcid = ast_true(v->value);
14337       } else if (!strcasecmp(v->name, "usecallingpres")) {
14338          confp->chan.use_callingpres = ast_true(v->value);
14339       } else if (!strcasecmp(v->name, "accountcode")) {
14340          ast_copy_string(confp->chan.accountcode, v->value, sizeof(confp->chan.accountcode));
14341       } else if (!strcasecmp(v->name, "amaflags")) {
14342          y = ast_cdr_amaflags2int(v->value);
14343          if (y < 0) 
14344             ast_log(LOG_WARNING, "Invalid AMA flags: %s at line %d\n", v->value, v->lineno);
14345          else
14346             confp->chan.amaflags = y;
14347       } else if (!strcasecmp(v->name, "polarityonanswerdelay")) {
14348          confp->chan.polarityonanswerdelay = atoi(v->value);
14349       } else if (!strcasecmp(v->name, "answeronpolarityswitch")) {
14350          confp->chan.answeronpolarityswitch = ast_true(v->value);
14351       } else if (!strcasecmp(v->name, "hanguponpolarityswitch")) {
14352          confp->chan.hanguponpolarityswitch = ast_true(v->value);
14353       } else if (!strcasecmp(v->name, "sendcalleridafter")) {
14354          confp->chan.sendcalleridafter = atoi(v->value);
14355       } else if (reload != 1) {
14356           if (!strcasecmp(v->name, "signalling") || !strcasecmp(v->name, "signaling")) {
14357             confp->chan.outsigmod = -1;
14358             if (!strcasecmp(v->value, "em")) {
14359                confp->chan.sig = SIG_EM;
14360             } else if (!strcasecmp(v->value, "em_e1")) {
14361                confp->chan.sig = SIG_EM_E1;
14362             } else if (!strcasecmp(v->value, "em_w")) {
14363                confp->chan.sig = SIG_EMWINK;
14364                confp->chan.radio = 0;
14365             } else if (!strcasecmp(v->value, "fxs_ls")) {
14366                confp->chan.sig = SIG_FXSLS;
14367                confp->chan.radio = 0;
14368             } else if (!strcasecmp(v->value, "fxs_gs")) {
14369                confp->chan.sig = SIG_FXSGS;
14370                confp->chan.radio = 0;
14371             } else if (!strcasecmp(v->value, "fxs_ks")) {
14372                confp->chan.sig = SIG_FXSKS;
14373                confp->chan.radio = 0;
14374             } else if (!strcasecmp(v->value, "fxo_ls")) {
14375                confp->chan.sig = SIG_FXOLS;
14376                confp->chan.radio = 0;
14377             } else if (!strcasecmp(v->value, "fxo_gs")) {
14378                confp->chan.sig = SIG_FXOGS;
14379                confp->chan.radio = 0;
14380             } else if (!strcasecmp(v->value, "fxo_ks")) {
14381                confp->chan.sig = SIG_FXOKS;
14382                confp->chan.radio = 0;
14383             } else if (!strcasecmp(v->value, "fxs_rx")) {
14384                confp->chan.sig = SIG_FXSKS;
14385                confp->chan.radio = 1;
14386             } else if (!strcasecmp(v->value, "fxo_rx")) {
14387                confp->chan.sig = SIG_FXOLS;
14388                confp->chan.radio = 1;
14389             } else if (!strcasecmp(v->value, "fxs_tx")) {
14390                confp->chan.sig = SIG_FXSLS;
14391                confp->chan.radio = 1;
14392             } else if (!strcasecmp(v->value, "fxo_tx")) {
14393                confp->chan.sig = SIG_FXOGS;
14394                confp->chan.radio = 1;
14395             } else if (!strcasecmp(v->value, "em_rx")) {
14396                confp->chan.sig = SIG_EM;
14397                confp->chan.radio = 1;
14398             } else if (!strcasecmp(v->value, "em_tx")) {
14399                confp->chan.sig = SIG_EM;
14400                confp->chan.radio = 1;
14401             } else if (!strcasecmp(v->value, "em_rxtx")) {
14402                confp->chan.sig = SIG_EM;
14403                confp->chan.radio = 2;
14404             } else if (!strcasecmp(v->value, "em_txrx")) {
14405                confp->chan.sig = SIG_EM;
14406                confp->chan.radio = 2;
14407             } else if (!strcasecmp(v->value, "sf")) {
14408                confp->chan.sig = SIG_SF;
14409                confp->chan.radio = 0;
14410             } else if (!strcasecmp(v->value, "sf_w")) {
14411                confp->chan.sig = SIG_SFWINK;
14412                confp->chan.radio = 0;
14413             } else if (!strcasecmp(v->value, "sf_featd")) {
14414                confp->chan.sig = SIG_FEATD;
14415                confp->chan.radio = 0;
14416             } else if (!strcasecmp(v->value, "sf_featdmf")) {
14417                confp->chan.sig = SIG_FEATDMF;
14418                confp->chan.radio = 0;
14419             } else if (!strcasecmp(v->value, "sf_featb")) {
14420                confp->chan.sig = SIG_SF_FEATB;
14421                confp->chan.radio = 0;
14422             } else if (!strcasecmp(v->value, "sf")) {
14423                confp->chan.sig = SIG_SF;
14424                confp->chan.radio = 0;
14425             } else if (!strcasecmp(v->value, "sf_rx")) {
14426                confp->chan.sig = SIG_SF;
14427                confp->chan.radio = 1;
14428             } else if (!strcasecmp(v->value, "sf_tx")) {
14429                confp->chan.sig = SIG_SF;
14430                confp->chan.radio = 1;
14431             } else if (!strcasecmp(v->value, "sf_rxtx")) {
14432                confp->chan.sig = SIG_SF;
14433                confp->chan.radio = 2;
14434             } else if (!strcasecmp(v->value, "sf_txrx")) {
14435                confp->chan.sig = SIG_SF;
14436                confp->chan.radio = 2;
14437             } else if (!strcasecmp(v->value, "featd")) {
14438                confp->chan.sig = SIG_FEATD;
14439                confp->chan.radio = 0;
14440             } else if (!strcasecmp(v->value, "featdmf")) {
14441                confp->chan.sig = SIG_FEATDMF;
14442                confp->chan.radio = 0;
14443             } else if (!strcasecmp(v->value, "featdmf_ta")) {
14444                confp->chan.sig = SIG_FEATDMF_TA;
14445                confp->chan.radio = 0;
14446             } else if (!strcasecmp(v->value, "e911")) {
14447                confp->chan.sig = SIG_E911;
14448                confp->chan.radio = 0;
14449             } else if (!strcasecmp(v->value, "fgccama")) {
14450                confp->chan.sig = SIG_FGC_CAMA;
14451                confp->chan.radio = 0;
14452             } else if (!strcasecmp(v->value, "fgccamamf")) {
14453                confp->chan.sig = SIG_FGC_CAMAMF;
14454                confp->chan.radio = 0;
14455             } else if (!strcasecmp(v->value, "featb")) {
14456                confp->chan.sig = SIG_FEATB;
14457                confp->chan.radio = 0;
14458 #ifdef HAVE_OPENR2
14459             } else if (!strcasecmp(v->value, "mfcr2")) {
14460                confp->chan.sig = SIG_MFCR2;
14461 #endif
14462 
14463 #ifdef HAVE_PRI
14464             } else if (!strcasecmp(v->value, "pri_net")) {
14465                confp->chan.radio = 0;
14466                confp->chan.sig = SIG_PRI;
14467                confp->pri.nodetype = PRI_NETWORK;
14468             } else if (!strcasecmp(v->value, "pri_cpe")) {
14469                confp->chan.sig = SIG_PRI;
14470                confp->chan.radio = 0;
14471                confp->pri.nodetype = PRI_CPE;
14472             } else if (!strcasecmp(v->value, "gr303fxoks_net")) {
14473                confp->chan.sig = SIG_GR303FXOKS;
14474                confp->chan.radio = 0;
14475                confp->pri.nodetype = PRI_NETWORK;
14476             } else if (!strcasecmp(v->value, "gr303fxsks_cpe")) {
14477                confp->chan.sig = SIG_GR303FXSKS;
14478                confp->chan.radio = 0;
14479                confp->pri.nodetype = PRI_CPE;
14480 #endif
14481             } else {
14482                ast_log(LOG_ERROR, "Unknown signalling method '%s'\n", v->value);
14483             }
14484           } else if (!strcasecmp(v->name, "outsignalling")) {
14485             if (!strcasecmp(v->value, "em")) {
14486                confp->chan.outsigmod = SIG_EM;
14487             } else if (!strcasecmp(v->value, "em_e1")) {
14488                confp->chan.outsigmod = SIG_EM_E1;
14489             } else if (!strcasecmp(v->value, "em_w")) {
14490                confp->chan.outsigmod = SIG_EMWINK;
14491             } else if (!strcasecmp(v->value, "sf")) {
14492                confp->chan.outsigmod = SIG_SF;
14493             } else if (!strcasecmp(v->value, "sf_w")) {
14494                confp->chan.outsigmod = SIG_SFWINK;
14495             } else if (!strcasecmp(v->value, "sf_featd")) {
14496                confp->chan.outsigmod = SIG_FEATD;
14497             } else if (!strcasecmp(v->value, "sf_featdmf")) {
14498                confp->chan.outsigmod = SIG_FEATDMF;
14499             } else if (!strcasecmp(v->value, "sf_featb")) {
14500                confp->chan.outsigmod = SIG_SF_FEATB;
14501             } else if (!strcasecmp(v->value, "sf")) {
14502                confp->chan.outsigmod = SIG_SF;
14503             } else if (!strcasecmp(v->value, "featd")) {
14504                confp->chan.outsigmod = SIG_FEATD;
14505             } else if (!strcasecmp(v->value, "featdmf")) {
14506                confp->chan.outsigmod = SIG_FEATDMF;
14507             } else if (!strcasecmp(v->value, "featdmf_ta")) {
14508                confp->chan.outsigmod = SIG_FEATDMF_TA;
14509             } else if (!strcasecmp(v->value, "e911")) {
14510                confp->chan.outsigmod = SIG_E911;
14511             } else if (!strcasecmp(v->value, "fgccama")) {
14512                confp->chan.outsigmod = SIG_FGC_CAMA;
14513             } else if (!strcasecmp(v->value, "fgccamamf")) {
14514                confp->chan.outsigmod = SIG_FGC_CAMAMF;
14515             } else if (!strcasecmp(v->value, "featb")) {
14516                confp->chan.outsigmod = SIG_FEATB;
14517             } else {
14518                ast_log(LOG_ERROR, "Unknown signalling method '%s'\n", v->value);
14519             }
14520 #ifdef HAVE_PRI
14521          } else if (!strcasecmp(v->name, "pridialplan")) {
14522             if (!strcasecmp(v->value, "national")) {
14523                confp->pri.dialplan = PRI_NATIONAL_ISDN + 1;
14524             } else if (!strcasecmp(v->value, "unknown")) {
14525                confp->pri.dialplan = PRI_UNKNOWN + 1;
14526             } else if (!strcasecmp(v->value, "private")) {
14527                confp->pri.dialplan = PRI_PRIVATE + 1;
14528             } else if (!strcasecmp(v->value, "international")) {
14529                confp->pri.dialplan = PRI_INTERNATIONAL_ISDN + 1;
14530             } else if (!strcasecmp(v->value, "local")) {
14531                confp->pri.dialplan = PRI_LOCAL_ISDN + 1;
14532             } else if (!strcasecmp(v->value, "dynamic")) {
14533                confp->pri.dialplan = -1;
14534             } else {
14535                ast_log(LOG_WARNING, "Unknown PRI dialplan '%s' at line %d.\n", v->value, v->lineno);
14536             }
14537          } else if (!strcasecmp(v->name, "prilocaldialplan")) {
14538             if (!strcasecmp(v->value, "national")) {
14539                confp->pri.localdialplan = PRI_NATIONAL_ISDN + 1;
14540             } else if (!strcasecmp(v->value, "unknown")) {
14541                confp->pri.localdialplan = PRI_UNKNOWN + 1;
14542             } else if (!strcasecmp(v->value, "private")) {
14543                confp->pri.localdialplan = PRI_PRIVATE + 1;
14544             } else if (!strcasecmp(v->value, "international")) {
14545                confp->pri.localdialplan = PRI_INTERNATIONAL_ISDN + 1;
14546             } else if (!strcasecmp(v->value, "local")) {
14547                confp->pri.localdialplan = PRI_LOCAL_ISDN + 1;
14548             } else if (!strcasecmp(v->value, "dynamic")) {
14549                confp->pri.localdialplan = -1;
14550             } else {
14551                ast_log(LOG_WARNING, "Unknown PRI dialplan '%s' at line %d.\n", v->value, v->lineno);
14552             }
14553          } else if (!strcasecmp(v->name, "switchtype")) {
14554             if (!strcasecmp(v->value, "national")) 
14555                confp->pri.switchtype = PRI_SWITCH_NI2;
14556             else if (!strcasecmp(v->value, "ni1"))
14557                confp->pri.switchtype = PRI_SWITCH_NI1;
14558             else if (!strcasecmp(v->value, "dms100"))
14559                confp->pri.switchtype = PRI_SWITCH_DMS100;
14560             else if (!strcasecmp(v->value, "4ess"))
14561                confp->pri.switchtype = PRI_SWITCH_ATT4ESS;
14562             else if (!strcasecmp(v->value, "5ess"))
14563                confp->pri.switchtype = PRI_SWITCH_LUCENT5E;
14564             else if (!strcasecmp(v->value, "euroisdn"))
14565                confp->pri.switchtype = PRI_SWITCH_EUROISDN_E1;
14566             else if (!strcasecmp(v->value, "qsig"))
14567                confp->pri.switchtype = PRI_SWITCH_QSIG;
14568             else {
14569                ast_log(LOG_ERROR, "Unknown switchtype '%s'\n", v->value);
14570                return -1;
14571             }
14572          } else if (!strcasecmp(v->name, "nsf")) {
14573             if (!strcasecmp(v->value, "sdn"))
14574                confp->pri.nsf = PRI_NSF_SDN;
14575             else if (!strcasecmp(v->value, "megacom"))
14576                confp->pri.nsf = PRI_NSF_MEGACOM;
14577             else if (!strcasecmp(v->value, "tollfreemegacom"))
14578                confp->pri.nsf = PRI_NSF_TOLL_FREE_MEGACOM;           
14579             else if (!strcasecmp(v->value, "accunet"))
14580                confp->pri.nsf = PRI_NSF_ACCUNET;
14581             else if (!strcasecmp(v->value, "none"))
14582                confp->pri.nsf = PRI_NSF_NONE;
14583             else {
14584                ast_log(LOG_WARNING, "Unknown network-specific facility '%s'\n", v->value);
14585                confp->pri.nsf = PRI_NSF_NONE;
14586             }
14587          } else if (!strcasecmp(v->name, "priindication")) {
14588             if (!strcasecmp(v->value, "outofband"))
14589                confp->chan.priindication_oob = 1;
14590             else if (!strcasecmp(v->value, "inband"))
14591                confp->chan.priindication_oob = 0;
14592             else
14593                ast_log(LOG_WARNING, "'%s' is not a valid pri indication value, should be 'inband' or 'outofband' at line %d\n",
14594                   v->value, v->lineno);
14595          } else if (!strcasecmp(v->name, "priexclusive")) {
14596             confp->chan.priexclusive = ast_true(v->value);
14597          } else if (!strcasecmp(v->name, "internationalprefix")) {
14598             ast_copy_string(confp->pri.internationalprefix, v->value, sizeof(confp->pri.internationalprefix));
14599          } else if (!strcasecmp(v->name, "nationalprefix")) {
14600             ast_copy_string(confp->pri.nationalprefix, v->value, sizeof(confp->pri.nationalprefix));
14601          } else if (!strcasecmp(v->name, "localprefix")) {
14602             ast_copy_string(confp->pri.localprefix, v->value, sizeof(confp->pri.localprefix));
14603          } else if (!strcasecmp(v->name, "privateprefix")) {
14604             ast_copy_string(confp->pri.privateprefix, v->value, sizeof(confp->pri.privateprefix));
14605          } else if (!strcasecmp(v->name, "unknownprefix")) {
14606             ast_copy_string(confp->pri.unknownprefix, v->value, sizeof(confp->pri.unknownprefix));
14607          } else if (!strcasecmp(v->name, "resetinterval")) {
14608             if (!strcasecmp(v->value, "never"))
14609                confp->pri.resetinterval = -1;
14610             else if (atoi(v->value) >= 60)
14611                confp->pri.resetinterval = atoi(v->value);
14612             else
14613                ast_log(LOG_WARNING, "'%s' is not a valid reset interval, should be >= 60 seconds or 'never' at line %d\n",
14614                   v->value, v->lineno);
14615          } else if (!strcasecmp(v->name, "minunused")) {
14616             confp->pri.minunused = atoi(v->value);
14617          } else if (!strcasecmp(v->name, "minidle")) {
14618             confp->pri.minidle = atoi(v->value); 
14619          } else if (!strcasecmp(v->name, "idleext")) {
14620             ast_copy_string(confp->pri.idleext, v->value, sizeof(confp->pri.idleext));
14621          } else if (!strcasecmp(v->name, "idledial")) {
14622             ast_copy_string(confp->pri.idledial, v->value, sizeof(confp->pri.idledial));
14623          } else if (!strcasecmp(v->name, "overlapdial")) {
14624             if (ast_true(v->value)) {
14625                confp->pri.overlapdial = DAHDI_OVERLAPDIAL_BOTH;
14626             } else if (!strcasecmp(v->value, "incoming")) {
14627                confp->pri.overlapdial = DAHDI_OVERLAPDIAL_INCOMING;
14628             } else if (!strcasecmp(v->value, "outgoing")) {
14629                confp->pri.overlapdial = DAHDI_OVERLAPDIAL_OUTGOING;
14630             } else if (!strcasecmp(v->value, "both") || ast_true(v->value)) {
14631                confp->pri.overlapdial = DAHDI_OVERLAPDIAL_BOTH;
14632             } else {
14633                confp->pri.overlapdial = DAHDI_OVERLAPDIAL_NONE;
14634             }
14635 #ifdef HAVE_PRI_INBANDDISCONNECT
14636          } else if (!strcasecmp(v->name, "inbanddisconnect")) {
14637             confp->pri.inbanddisconnect = ast_true(v->value);
14638 #endif
14639          } else if (!strcasecmp(v->name, "pritimer")) {
14640 #ifdef PRI_GETSET_TIMERS
14641             char tmp[20];
14642             char *timerc;
14643             char *c;
14644             int timer;
14645             int timeridx;
14646 
14647             ast_copy_string(tmp, v->value, sizeof(tmp));
14648             c = tmp;
14649             timerc = strsep(&c, ",");
14650             if (!ast_strlen_zero(timerc) && !ast_strlen_zero(c)) {
14651                timeridx = pri_timer2idx(timerc);
14652                timer = atoi(c);
14653                if (timeridx < 0 || PRI_MAX_TIMERS <= timeridx) {
14654                   ast_log(LOG_WARNING,
14655                      "'%s' is not a valid ISDN timer at line %d.\n", timerc,
14656                      v->lineno);
14657                } else if (!timer) {
14658                   ast_log(LOG_WARNING,
14659                      "'%s' is not a valid value for ISDN timer '%s' at line %d.\n",
14660                      c, timerc, v->lineno);
14661                } else {
14662                   pritimers[timeridx] = timer;
14663                }
14664             } else {
14665                ast_log(LOG_WARNING,
14666                   "'%s' is not a valid ISDN timer configuration string at line %d.\n",
14667                   v->value, v->lineno);
14668             }
14669 #endif /* PRI_GETSET_TIMERS */
14670          } else if (!strcasecmp(v->name, "facilityenable")) {
14671             confp->pri.facilityenable = ast_true(v->value);
14672 #endif /* HAVE_PRI */
14673 
14674 #ifdef HAVE_OPENR2
14675          } else if (!strcasecmp(v->name, "mfcr2_advanced_protocol_file")) {
14676             ast_copy_string(mfcr2_cur_r2proto_file, v->value, sizeof(mfcr2_cur_r2proto_file));
14677             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);
14678          } else if (!strcasecmp(v->name, "mfcr2_logdir")) {
14679             ast_copy_string(mfcr2_cur_logdir, v->value, sizeof(mfcr2_cur_logdir));
14680          } else if (!strcasecmp(v->name, "mfcr2_variant")) {
14681             mfcr2_cur_variant = openr2_proto_get_variant(v->value);
14682             if (OR2_VAR_UNKNOWN == mfcr2_cur_variant) {
14683                ast_log(LOG_WARNING, "Unknown MFC/R2 variant '%s' at line %d.\n", v->value, v->lineno);
14684             }
14685          } else if (!strcasecmp(v->name, "mfcr2_mfback_timeout")) {
14686             mfcr2_cur_mfback_timeout = atoi(v->value);
14687             if (!mfcr2_cur_mfback_timeout) {
14688                ast_log(LOG_WARNING, "MF timeout of 0? hum, I will protect you from your ignorance. Setting default.\n");
14689                mfcr2_cur_mfback_timeout = -1;
14690             } else if (mfcr2_cur_mfback_timeout > 0 && mfcr2_cur_mfback_timeout < 500) {
14691                ast_log(LOG_WARNING, "MF timeout less than 500ms is not recommended, you have been warned!\n");
14692             }
14693          } else if (!strcasecmp(v->name, "mfcr2_metering_pulse_timeout")) {
14694             mfcr2_cur_metering_pulse_timeout = atoi(v->value);
14695             if (mfcr2_cur_metering_pulse_timeout > 500) {
14696                ast_log(LOG_WARNING, "mfcr2_metering_pulse_timeout greater than 500ms is not recommended, you have been warned!\n");
14697             }
14698 #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 2
14699          } else if (!strcasecmp(v->name, "mfcr2_dtmf_detection")) {
14700             mfcr2_cur_dtmf_detection = ast_true(v->value) ? 1 : 0;
14701          } else if (!strcasecmp(v->name, "mfcr2_dtmf_dialing")) {
14702             mfcr2_cur_dtmf_dialing = ast_true(v->value) ? 1 : 0;
14703          } else if (!strcasecmp(v->name, "mfcr2_dtmf_time_on")) {
14704             mfcr2_cur_dtmf_time_on = atoi(v->value);
14705          } else if (!strcasecmp(v->name, "mfcr2_dtmf_time_off")) {
14706             mfcr2_cur_dtmf_time_off = atoi(v->value);
14707 #endif
14708          } else if (!strcasecmp(v->name, "mfcr2_get_ani_first")) {
14709             mfcr2_cur_get_ani_first = ast_true(v->value) ? 1 : 0;
14710          } else if (!strcasecmp(v->name, "mfcr2_skip_category")) {
14711             mfcr2_cur_skip_category = ast_true(v->value) ? 1 : 0;
14712          } else if (!strcasecmp(v->name, "mfcr2_double_answer")) {
14713             mfcr2_cur_double_answer = ast_true(v->value) ? 1 : 0;
14714          } else if (!strcasecmp(v->name, "mfcr2_accept_on_offer")) {
14715             mfcr2_cur_accept_on_offer = ast_true(v->value) ? 1 : 0;
14716          } else if (!strcasecmp(v->name, "mfcr2_charge_calls")) {
14717             mfcr2_cur_charge_calls = ast_true(v->value) ? 1 : 0;
14718          } else if (!strcasecmp(v->name, "mfcr2_allow_collect_calls")) {
14719             mfcr2_cur_allow_collect_calls = ast_true(v->value) ? 1 : 0;
14720          } else if (!strcasecmp(v->name, "mfcr2_forced_release")) {
14721             mfcr2_cur_forced_release= ast_true(v->value) ? 1 : 0;
14722          } else if (!strcasecmp(v->name, "mfcr2_immediate_accept")) {
14723             mfcr2_cur_immediate_accept = ast_true(v->value) ? 1 : 0;
14724          } else if (!strcasecmp(v->name, "mfcr2_call_files")) {
14725             mfcr2_cur_call_files = ast_true(v->value) ? 1 : 0;
14726          } else if (!strcasecmp(v->name, "mfcr2_max_ani")) {
14727             mfcr2_cur_max_ani = atoi(v->value);
14728             if (mfcr2_cur_max_ani >= AST_MAX_EXTENSION) {
14729                mfcr2_cur_max_ani = AST_MAX_EXTENSION - 1;
14730             }
14731          } else if (!strcasecmp(v->name, "mfcr2_max_dnis")) {
14732             mfcr2_cur_max_dnis = atoi(v->value);
14733             if (mfcr2_cur_max_dnis >= AST_MAX_EXTENSION) {
14734                mfcr2_cur_max_dnis = AST_MAX_EXTENSION - 1;
14735             }
14736          } else if (!strcasecmp(v->name, "mfcr2_category")) {
14737             mfcr2_cur_category = openr2_proto_get_category(v->value);
14738             if (OR2_CALLING_PARTY_CATEGORY_UNKNOWN == mfcr2_cur_category) {
14739                mfcr2_cur_category = OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER;
14740                ast_log(LOG_WARNING, "Invalid MFC/R2 caller category '%s' at line %d. Using national subscriber as default.\n", 
14741                      v->value, v->lineno);
14742             }
14743          } else if (!strcasecmp(v->name, "mfcr2_logging")) {
14744             openr2_log_level_t tmplevel;
14745             char *toklevel = NULL;
14746             char *saveptr = NULL;
14747             char *logval = ast_strdupa(v->value);
14748             toklevel = strtok_r(logval, ",", &saveptr);
14749             if (-1 == (tmplevel = openr2_log_get_level(toklevel))) {
14750                ast_log(LOG_WARNING, "Invalid MFC/R2 logging level '%s' at line %d.\n", v->value, v->lineno);
14751             } else if (OR2_LOG_NOTHING == tmplevel) {
14752                mfcr2_cur_loglevel = tmplevel;
14753             } else {
14754                mfcr2_cur_loglevel |= tmplevel;
14755                while ((toklevel = strtok_r(NULL, ",", &saveptr))) {
14756                   if (-1 == (tmplevel = openr2_log_get_level(toklevel))) {
14757                      ast_log(LOG_WARNING, "Ignoring invalid logging level: '%s' at line %d.\n", toklevel, v->lineno);
14758                      continue;
14759                   }
14760                   mfcr2_cur_loglevel |= tmplevel;
14761                }
14762             }
14763 #endif /* HAVE_OPENR2 */
14764 
14765          } else if (!strcasecmp(v->name, "cadence")) {
14766             /* setup to scan our argument */
14767             int element_count, c[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
14768             int i;
14769             struct dahdi_ring_cadence new_cadence;
14770             int cid_location = -1;
14771             int firstcadencepos = 0;
14772             char original_args[80];
14773             int cadence_is_ok = 1;
14774 
14775             ast_copy_string(original_args, v->value, sizeof(original_args));
14776             /* 16 cadences allowed (8 pairs) */
14777             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]);
14778    
14779             /* Cadence must be even (on/off) */
14780             if (element_count % 2 == 1) {
14781                ast_log(LOG_ERROR, "Must be a silence duration for each ring duration: %s\n",original_args);
14782                cadence_is_ok = 0;
14783             }
14784    
14785             /* Ring cadences cannot be negative */
14786             for (i = 0; i < element_count; i++) {
14787                if (c[i] == 0) {
14788                   ast_log(LOG_ERROR, "Ring or silence duration cannot be zero: %s\n", original_args);
14789                   cadence_is_ok = 0;
14790                   break;
14791                } else if (c[i] < 0) {
14792                   if (i % 2 == 1) {
14793                      /* Silence duration, negative possibly okay */
14794                      if (cid_location == -1) {
14795                         cid_location = i;
14796                         c[i] *= -1;
14797                      } else {
14798                         ast_log(LOG_ERROR, "CID location specified twice: %s\n",original_args);
14799                         cadence_is_ok = 0;
14800                         break;
14801                      }
14802                   } else {
14803                      if (firstcadencepos == 0) {
14804                         firstcadencepos = i; /* only recorded to avoid duplicate specification */
14805                                  /* duration will be passed negative to the DAHDI driver */
14806                      } else {
14807                          ast_log(LOG_ERROR, "First cadence position specified twice: %s\n",original_args);
14808                         cadence_is_ok = 0;
14809                         break;
14810                      }
14811                   }
14812                }
14813             }
14814    
14815             /* Substitute our scanned cadence */
14816             for (i = 0; i < 16; i++) {
14817                new_cadence.ringcadence[i] = c[i];
14818             }
14819    
14820             if (cadence_is_ok) {
14821                /* ---we scanned it without getting annoyed; now some sanity checks--- */
14822                if (element_count < 2) {
14823                   ast_log(LOG_ERROR, "Minimum cadence is ring,pause: %s\n", original_args);
14824                } else {
14825                   if (cid_location == -1) {
14826                      /* user didn't say; default to first pause */
14827                      cid_location = 1;
14828                   } else {
14829                      /* convert element_index to cidrings value */
14830                      cid_location = (cid_location + 1) / 2;
14831                   }
14832                   /* ---we like their cadence; try to install it--- */
14833                   if (!user_has_defined_cadences++)
14834                      /* this is the first user-defined cadence; clear the default user cadences */
14835                      num_cadence = 0;
14836                   if ((num_cadence+1) >= NUM_CADENCE_MAX)
14837                      ast_log(LOG_ERROR, "Already %d cadences; can't add another: %s\n", NUM_CADENCE_MAX, original_args);
14838                   else {
14839                      cadences[num_cadence] = new_cadence;
14840                      cidrings[num_cadence++] = cid_location;
14841                      if (option_verbose > 2)
14842                         ast_verbose(VERBOSE_PREFIX_3 "cadence 'r%d' added: %s\n",num_cadence,original_args);
14843                   }
14844                }
14845             }
14846          } else if (!strcasecmp(v->name, "ringtimeout")) {
14847             ringt_base = (atoi(v->value) * 8) / READ_SIZE;
14848          } else if (!strcasecmp(v->name, "prewink")) {
14849             confp->timing.prewinktime = atoi(v->value);
14850          } else if (!strcasecmp(v->name, "preflash")) {
14851             confp->timing.preflashtime = atoi(v->value);
14852          } else if (!strcasecmp(v->name, "wink")) {
14853             confp->timing.winktime = atoi(v->value);
14854          } else if (!strcasecmp(v->name, "flash")) {
14855             confp->timing.flashtime = atoi(v->value);
14856          } else if (!strcasecmp(v->name, "start")) {
14857             confp->timing.starttime = atoi(v->value);
14858          } else if (!strcasecmp(v->name, "rxwink")) {
14859             confp->timing.rxwinktime = atoi(v->value);
14860          } else if (!strcasecmp(v->name, "rxflash")) {
14861             confp->timing.rxflashtime = atoi(v->value);
14862          } else if (!strcasecmp(v->name, "debounce")) {
14863             confp->timing.debouncetime = atoi(v->value);
14864          } else if (!strcasecmp(v->name, "toneduration")) {
14865             int toneduration;
14866             int ctlfd;
14867             int res;
14868             struct dahdi_dialparams dps;
14869 
14870             ctlfd = open(DAHDI_FILE_CTL, O_RDWR);
14871 
14872             if (ctlfd == -1) {
14873                ast_log(LOG_ERROR, "Unable to open " DAHDI_FILE_CTL " to set toneduration\n");
14874                return -1;
14875             }
14876 
14877             toneduration = atoi(v->value);
14878             if (toneduration > -1) {
14879                memset(&dps, 0, sizeof(dps));
14880 
14881                dps.dtmf_tonelen = dps.mfv1_tonelen = toneduration;
14882                res = ioctl(ctlfd, DAHDI_SET_DIALPARAMS, &dps);
14883                if (res < 0) {
14884                   ast_log(LOG_ERROR, "Invalid tone duration: %d ms: %s\n", toneduration, strerror(errno));
14885                   close(ctlfd);
14886                   return -1;
14887                }
14888             }
14889             close(ctlfd);
14890          } else if (!strcasecmp(v->name, "defaultcic")) {
14891             ast_copy_string(defaultcic, v->value, sizeof(defaultcic));
14892          } else if (!strcasecmp(v->name, "defaultozz")) {
14893             ast_copy_string(defaultozz, v->value, sizeof(defaultozz));
14894          } else if (!strcasecmp(v->name, "dtmfcidlevel")) {
14895             dtmfcid_level = atoi(v->value);
14896          } 
14897       } else if (!skipchannels)
14898          ast_log(LOG_WARNING, "Ignoring any changes to '%s' (on reload)\n", v->name);
14899    }
14900    if (dahdichan[0]) { 
14901       /* The user has set 'dahdichan' */
14902       /*< \todo pass proper line number instead of 0 */
14903       if (build_channels(confp, 0, dahdichan, reload, 0, &found_pseudo)) {
14904          return -1;
14905       }
14906    }
14907    /*< \todo why check for the pseudo in the per-channel section.
14908     * Any actual use for manual setup of the pseudo channel? */
14909    if (!found_pseudo && reload != 1) {
14910       /* use the default configuration for a channel, so
14911          that any settings from real configured channels
14912          don't "leak" into the pseudo channel config
14913       */
14914       struct dahdi_chan_conf conf = dahdi_chan_conf_default();
14915 
14916       tmp = mkintf(CHAN_PSEUDO, &conf, NULL, reload);
14917 
14918       if (tmp) {
14919          if (option_verbose > 2)
14920             ast_verbose(VERBOSE_PREFIX_3 "Automatically generated pseudo channel\n");
14921       } else {
14922          ast_log(LOG_WARNING, "Unable to register pseudo channel!\n");
14923       }
14924    }
14925    return 0;
14926 }
14927       
14928 static int setup_dahdi(int reload)
14929 {
14930    struct ast_config *cfg;
14931    struct ast_variable *v;
14932    struct dahdi_chan_conf conf = dahdi_chan_conf_default();
14933    int res;
14934 
14935 #ifdef HAVE_PRI
14936    char *c;
14937    int spanno;
14938    int i, x;
14939    int logicalspan;
14940    int trunkgroup;
14941    int dchannels[NUM_DCHANS];
14942 #endif
14943 
14944 #ifdef HAVE_ZAPTEL
14945    int load_from_zapata_conf = 1;
14946 #else
14947    int load_from_zapata_conf = (*dahdi_chan_mode == CHAN_ZAP_MODE);
14948 #endif
14949 
14950    if (load_from_zapata_conf) {
14951       if (!(cfg = ast_config_load("zapata.conf"))) {
14952          ast_log(LOG_ERROR, "Unable to load zapata.conf\n");
14953          return 0;
14954       }
14955    } else {
14956       if (!(cfg = ast_config_load("chan_dahdi.conf"))) {
14957          ast_log(LOG_ERROR, "Unable to load chan_dahdi.conf\n");
14958          return 0;
14959       }
14960    }
14961 
14962    /* It's a little silly to lock it, but we mind as well just to be sure */
14963    ast_mutex_lock(&iflock);
14964 #ifdef HAVE_PRI
14965    if (reload != 1) {
14966       /* Process trunkgroups first */
14967       v = ast_variable_browse(cfg, "trunkgroups");
14968       while (v) {
14969          if (!strcasecmp(v->name, "trunkgroup")) {
14970             trunkgroup = atoi(v->value);
14971             if (trunkgroup > 0) {
14972                if ((c = strchr(v->value, ','))) {
14973                   i = 0;
14974                   memset(dchannels, 0, sizeof(dchannels));
14975                   while (c && (i < NUM_DCHANS)) {
14976                      dchannels[i] = atoi(c + 1);
14977                      if (dchannels[i] < 0) {
14978                         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);
14979                      } else
14980                         i++;
14981                      c = strchr(c + 1, ',');
14982                   }
14983                   if (i) {
14984                      if (pri_create_trunkgroup(trunkgroup, dchannels)) {
14985                         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);
14986                      } else if (option_verbose > 1)
14987                         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");
14988                   } else
14989                      ast_log(LOG_WARNING, "Trunk group %d lacks any valid D-channels at line %d of chan_dahdi.conf\n", trunkgroup, v->lineno);
14990                } else
14991                   ast_log(LOG_WARNING, "Trunk group %d lacks a primary D-channel at line %d of chan_dahdi.conf\n", trunkgroup, v->lineno);
14992             } else
14993                ast_log(LOG_WARNING, "Trunk group identifier must be a positive integer at line %d of chan_dahdi.conf\n", v->lineno);
14994          } else if (!strcasecmp(v->name, "spanmap")) {
14995             spanno = atoi(v->value);
14996             if (spanno > 0) {
14997                if ((c = strchr(v->value, ','))) {
14998                   trunkgroup = atoi(c + 1);
14999                   if (trunkgroup > 0) {
15000                      if ((c = strchr(c + 1, ','))) 
15001                         logicalspan = atoi(c + 1);
15002                      else
15003                         logicalspan = 0;
15004                      if (logicalspan >= 0) {
15005                         if (pri_create_spanmap(spanno - 1, trunkgroup, logicalspan)) {
15006                            ast_log(LOG_WARNING, "Failed to map span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan);
15007                         } else if (option_verbose > 1) 
15008                            ast_verbose(VERBOSE_PREFIX_2 "Mapped span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan);
15009                      } else
15010                         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);
15011                   } else
15012                      ast_log(LOG_WARNING, "Trunk group must be a postive number at line %d of chan_dahdi.conf\n", v->lineno);
15013                } else
15014                   ast_log(LOG_WARNING, "Missing trunk group for span map at line %d of chan_dahdi.conf\n", v->lineno);
15015             } else
15016                ast_log(LOG_WARNING, "Span number must be a postive integer at line %d of chan_dahdi.conf\n", v->lineno);
15017          } else {
15018             ast_log(LOG_NOTICE, "Ignoring unknown keyword '%s' in trunkgroups\n", v->name);
15019          }
15020          v = v->next;
15021       }
15022    }
15023 #endif
15024    
15025    /* Copy the default jb config over global_jbconf */
15026    memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
15027 
15028    v = ast_variable_browse(cfg, "channels");
15029    res = process_dahdi(&conf, "", v, reload, 0);
15030    ast_mutex_unlock(&iflock);
15031    ast_config_destroy(cfg);
15032    if (res)
15033       return res;
15034    cfg = ast_config_load("users.conf");
15035    if (cfg) {
15036       char *cat;
15037 
15038       /* Reset conf back to defaults, so values from chan_dahdi.conf don't leak in. */
15039       conf = dahdi_chan_conf_default();
15040       process_dahdi(&conf, "", ast_variable_browse(cfg, "general"), 1, 1);
15041       for (cat = ast_category_browse(cfg, NULL); cat ; cat = ast_category_browse(cfg, cat)) {
15042          if (!strcasecmp(cat, "general"))
15043             continue;
15044          if (!ast_strlen_zero(ast_variable_retrieve(cfg, cat, "dahdichan")) || !ast_strlen_zero(ast_variable_retrieve(cfg, cat, "zapchan"))) {
15045             struct dahdi_chan_conf sect_conf;
15046             memcpy(&sect_conf, &conf, sizeof(sect_conf));
15047 
15048             process_dahdi(&sect_conf, cat, ast_variable_browse(cfg, cat), reload, 0);
15049          }
15050       }
15051       ast_config_destroy(cfg);
15052    }
15053 #ifdef HAVE_PRI
15054    if (reload != 1) {
15055       for (x = 0; x < NUM_SPANS; x++) {
15056          if (pris[x].pvts[0]) {
15057             if (start_pri(pris + x)) {
15058                ast_log(LOG_ERROR, "Unable to start D-channel on span %d\n", x + 1);
15059                return -1;
15060             } else if (option_verbose > 1)
15061                ast_verbose(VERBOSE_PREFIX_2 "Starting D-Channel on span %d\n", x + 1);
15062          }
15063       }
15064    }
15065 #endif
15066 
15067 #ifdef HAVE_OPENR2
15068    if (reload != 1) {
15069       int x;
15070       for (x = 0; x < NUM_SPANS; x++) {
15071          if (r2links[x].protocol_context) {
15072             if (ast_pthread_create(&r2links[x].master, NULL, mfcr2_monitor, &r2links[x])) {
15073                ast_log(LOG_ERROR, "Unable to start R2 context on span %d\n", x + 1);
15074                return -1;
15075             } else {
15076                ast_verbose(VERBOSE_PREFIX_2 "Starting R2 context on span %d\n", x + 1);
15077             }
15078          }
15079       }
15080    }
15081 #endif
15082 
15083    /* And start the monitor for the first time */
15084    restart_monitor();
15085    return 0;
15086 }
15087 
15088 #define local_astman_register(a, b, c, d) do { \
15089                   if (*dahdi_chan_mode == CHAN_DAHDI_PLUS_ZAP_MODE) { \
15090                      ast_manager_register("DAHDI" a, b, dahdi_ ## c, d); \
15091                   } \
15092                   ast_manager_register("Zap" a, b, zap_ ## c, d); \
15093                  } while (0)
15094 
15095 static int load_module(void)
15096 {
15097    int res;
15098 
15099 #ifdef HAVE_PRI
15100    int y,i;
15101    memset(pris, 0, sizeof(pris));
15102    for (y = 0; y < NUM_SPANS; y++) {
15103       ast_mutex_init(&pris[y].lock);
15104       pris[y].offset = -1;
15105       pris[y].master = AST_PTHREADT_NULL;
15106       for (i = 0; i < NUM_DCHANS; i++)
15107          pris[y].fds[i] = -1;
15108    }
15109    pri_set_error(dahdi_pri_error);
15110    pri_set_message(dahdi_pri_message);
15111    if (*dahdi_chan_mode == CHAN_DAHDI_PLUS_ZAP_MODE) {
15112       ast_register_application(dahdi_send_keypad_facility_app, dahdi_send_keypad_facility_exec,
15113          dahdi_send_keypad_facility_synopsis, dahdi_send_keypad_facility_descrip);
15114    }
15115    ast_register_application(zap_send_keypad_facility_app, zap_send_keypad_facility_exec,
15116       zap_send_keypad_facility_synopsis, zap_send_keypad_facility_descrip);
15117 #endif
15118 
15119 #ifdef HAVE_OPENR2
15120    init_mfcr2_globals();
15121    if (*dahdi_chan_mode == CHAN_DAHDI_PLUS_ZAP_MODE) {
15122       ast_register_application(dahdi_accept_r2_call_app, dahdi_accept_r2_call_exec,
15123          dahdi_accept_r2_call_synopsis, dahdi_accept_r2_call_descrip);
15124    }
15125    ast_register_application(zap_accept_r2_call_app, zap_accept_r2_call_exec,
15126       zap_accept_r2_call_synopsis, zap_accept_r2_call_descrip);
15127 #endif
15128 
15129    if ((res = setup_dahdi(0))) {
15130       return AST_MODULE_LOAD_DECLINE;
15131    }
15132    if (*dahdi_chan_mode == CHAN_DAHDI_PLUS_ZAP_MODE) {
15133       chan_tech = &dahdi_tech;
15134    } else {
15135       chan_tech = &zap_tech;
15136    }
15137    if (ast_channel_register(chan_tech)) {
15138       ast_log(LOG_ERROR, "Unable to register channel class '%s'\n", chan_tech->type);
15139       __unload_module();
15140       return -1;
15141    }
15142 #ifdef HAVE_PRI
15143    ast_string_field_init(&inuse, 16);
15144    ast_string_field_set(&inuse, name, "GR-303InUse");
15145    ast_cli_register_multiple(dahdi_pri_cli, sizeof(dahdi_pri_cli) / sizeof(struct ast_cli_entry));
15146 #endif   
15147 
15148 #ifdef HAVE_OPENR2
15149    ast_cli_register_multiple(dahdi_mfcr2_cli, sizeof(dahdi_mfcr2_cli)/sizeof(dahdi_mfcr2_cli[0]));
15150 #endif
15151 
15152    ast_cli_register_multiple(dahdi_cli, sizeof(dahdi_cli) / sizeof(struct ast_cli_entry));
15153    
15154    memset(round_robin, 0, sizeof(round_robin));
15155    local_astman_register("Transfer", 0, action_transfer, "Transfer Channel");
15156    local_astman_register("Hangup", 0, action_transferhangup, "Hangup Channel");
15157    local_astman_register("DialOffHook", 0, action_dialoffhook, "Dial over channel while offhook");
15158    local_astman_register("DNDon", 0, action_dndon, "Toggle channel Do Not Disturb status ON");
15159    local_astman_register("DNDoff", 0, action_dndoff, "Toggle channel Do Not Disturb status OFF");
15160    local_astman_register("ShowChannels", 0, action_showchannels, "Show status channels");
15161    local_astman_register("Restart", 0, action_restart, "Fully Restart channels (terminates calls)");
15162 
15163    ast_cond_init(&ss_thread_complete, NULL);
15164 
15165    return res;
15166 }
15167 
15168 static int dahdi_sendtext(struct ast_channel *c, const char *text)
15169 {
15170 #define  END_SILENCE_LEN 400
15171 #define  HEADER_MS 50
15172 #define  TRAILER_MS 5
15173 #define  HEADER_LEN ((HEADER_MS + TRAILER_MS) * 8)
15174 #define  ASCII_BYTES_PER_CHAR 80
15175 
15176    unsigned char *buf,*mybuf;
15177    struct dahdi_pvt *p = c->tech_pvt;
15178    struct pollfd fds[1];
15179    int size,res,fd,len,x;
15180    int bytes=0;
15181    /* Initial carrier (imaginary) */
15182    float cr = 1.0;
15183    float ci = 0.0;
15184    float scont = 0.0;
15185    int index;
15186 
15187    index = dahdi_get_index(c, p, 0);
15188    if (index < 0) {
15189       ast_log(LOG_WARNING, "Huh?  I don't exist?\n");
15190       return -1;
15191    }
15192    if (!text[0]) return(0); /* if nothing to send, dont */
15193    if ((!p->tdd) && (!p->mate)) return(0);  /* if not in TDD mode, just return */
15194    if (p->mate) 
15195       buf = ast_malloc(((strlen(text) + 1) * ASCII_BYTES_PER_CHAR) + END_SILENCE_LEN + HEADER_LEN);
15196    else
15197       buf = ast_malloc(((strlen(text) + 1) * TDD_BYTES_PER_CHAR) + END_SILENCE_LEN);
15198    if (!buf)
15199       return -1;
15200    mybuf = buf;
15201    if (p->mate) {
15202       int codec = AST_LAW(p);
15203       for (x = 0; x < HEADER_MS; x++) {   /* 50 ms of Mark */
15204          PUT_CLID_MARKMS;
15205       }
15206       /* Put actual message */
15207       for (x = 0; text[x]; x++) {
15208          PUT_CLID(text[x]);
15209       }
15210       for (x = 0; x < TRAILER_MS; x++) {  /* 5 ms of Mark */
15211          PUT_CLID_MARKMS;
15212       }
15213       len = bytes;
15214       buf = mybuf;
15215    } else {
15216       len = tdd_generate(p->tdd, buf, text);
15217       if (len < 1) {
15218          ast_log(LOG_ERROR, "TDD generate (len %d) failed!!\n", (int)strlen(text));
15219          free(mybuf);
15220          return -1;
15221       }
15222    }
15223    memset(buf + len, 0x7f, END_SILENCE_LEN);
15224    len += END_SILENCE_LEN;
15225    fd = p->subs[index].dfd;
15226    while (len) {
15227       if (ast_check_hangup(c)) {
15228          free(mybuf);
15229          return -1;
15230       }
15231       size = len;
15232       if (size > READ_SIZE)
15233          size = READ_SIZE;
15234       fds[0].fd = fd;
15235       fds[0].events = POLLOUT | POLLPRI;
15236       fds[0].revents = 0;
15237       res = poll(fds, 1, -1);
15238       if (!res) {
15239          ast_log(LOG_DEBUG, "poll (for write) ret. 0 on channel %d\n", p->channel);
15240          continue;
15241       }
15242         /* if got exception */
15243       if (fds[0].revents & POLLPRI) {
15244          ast_free(mybuf);
15245          return -1;
15246       }
15247       if (!(fds[0].revents & POLLOUT)) {
15248          ast_log(LOG_DEBUG, "write fd not ready on channel %d\n", p->channel);
15249          continue;
15250       }
15251       res = write(fd, buf, size);
15252       if (res != size) {
15253          if (res == -1) {
15254             free(mybuf);
15255             return -1;
15256          }
15257          if (option_debug)
15258             ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
15259          break;
15260       }
15261       len -= size;
15262       buf += size;
15263    }
15264    free(mybuf);
15265    return(0);
15266 }
15267 
15268 
15269 static int reload(void)
15270 {
15271    int res = 0;
15272 
15273    res = setup_dahdi(1);
15274    if (res) {
15275       ast_log(LOG_WARNING, "Reload of chan_dahdi.so is unsuccessful!\n");
15276       return -1;
15277    }
15278    return 0;
15279 }
15280 
15281 /* This is a workaround so that menuselect displays a proper description
15282  * AST_MODULE_INFO(, , "DAHDI Telephony"
15283  */
15284 
15285 #ifdef HAVE_PRI
15286 #define tdesc "DAHDI Telephony w/PRI"
15287 #else
15288 #define tdesc "DAHDI Telephony"
15289 #endif
15290 
15291 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, tdesc,
15292       .load = load_module,
15293       .unload = unload_module,
15294       .reload = reload,
15295           );
15296 
15297 

Generated on 7 Jun 2012 for Asterisk - the Open Source PBX by  doxygen 1.6.1