Mon Jun 18 2012 03:55:41

Asterisk developer's documentation


sig_pri.c
Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 1999 - 2009, 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 PRI signaling module
00022  *
00023  * \author Matthew Fredrickson <creslin@digium.com>
00024  */
00025 
00026 
00027 #include "asterisk.h"
00028 
00029 #ifdef HAVE_PRI
00030 
00031 #include <errno.h>
00032 #include <ctype.h>
00033 #include <signal.h>
00034 
00035 #include "asterisk/utils.h"
00036 #include "asterisk/options.h"
00037 #include "asterisk/pbx.h"
00038 #include "asterisk/app.h"
00039 #include "asterisk/file.h"
00040 #include "asterisk/callerid.h"
00041 #include "asterisk/say.h"
00042 #include "asterisk/manager.h"
00043 #include "asterisk/astdb.h"
00044 #include "asterisk/causes.h"
00045 #include "asterisk/musiconhold.h"
00046 #include "asterisk/cli.h"
00047 #include "asterisk/transcap.h"
00048 #include "asterisk/features.h"
00049 #include "asterisk/aoc.h"
00050 
00051 #include "sig_pri.h"
00052 #ifndef PRI_EVENT_FACILITY
00053 #error please update libpri
00054 #endif
00055 
00056 /* define this to send PRI user-user information elements */
00057 #undef SUPPORT_USERUSER
00058 
00059 /*!
00060  * Define to make always pick a channel if allowed.  Useful for
00061  * testing channel shifting.
00062  */
00063 //#define ALWAYS_PICK_CHANNEL 1
00064 
00065 /*!
00066  * Define to force a RESTART on a channel that returns a cause
00067  * code of PRI_CAUSE_REQUESTED_CHAN_UNAVAIL(44).  If the cause
00068  * is because of a stuck channel on the peer and the channel is
00069  * always the next channel we pick for an outgoing call then
00070  * this can help.
00071  */
00072 #define FORCE_RESTART_UNAVAIL_CHANS    1
00073 
00074 #if defined(HAVE_PRI_CCSS)
00075 struct sig_pri_cc_agent_prv {
00076    /*! Asterisk span D channel control structure. */
00077    struct sig_pri_span *pri;
00078    /*! CC id value to use with libpri. -1 if invalid. */
00079    long cc_id;
00080    /*! TRUE if CC has been requested and we are waiting for the response. */
00081    unsigned char cc_request_response_pending;
00082 };
00083 
00084 struct sig_pri_cc_monitor_instance {
00085    /*! \brief Asterisk span D channel control structure. */
00086    struct sig_pri_span *pri;
00087    /*! CC id value to use with libpri. (-1 if already canceled). */
00088    long cc_id;
00089    /*! CC core id value. */
00090    int core_id;
00091    /*! Device name(Channel name less sequence number) */
00092    char name[1];
00093 };
00094 
00095 /*! Upper level agent/monitor type name. */
00096 static const char *sig_pri_cc_type_name;
00097 /*! Container of sig_pri monitor instances. */
00098 static struct ao2_container *sig_pri_cc_monitors;
00099 #endif   /* defined(HAVE_PRI_CCSS) */
00100 
00101 static int pri_matchdigittimeout = 3000;
00102 
00103 static int pri_gendigittimeout = 8000;
00104 
00105 #define DCHAN_NOTINALARM  (1 << 0)
00106 #define DCHAN_UP          (1 << 1)
00107 
00108 /* Defines to help decode the encoded event channel id. */
00109 #define PRI_CHANNEL(p)  ((p) & 0xff)
00110 #define PRI_SPAN(p)     (((p) >> 8) & 0xff)
00111 #define PRI_EXPLICIT (1 << 16)
00112 #define PRI_CIS_CALL (1 << 17)   /* Call is using the D channel only. */
00113 #define PRI_HELD_CALL   (1 << 18)
00114 
00115 
00116 #define DCHAN_AVAILABLE (DCHAN_NOTINALARM | DCHAN_UP)
00117 
00118 #define PRI_DEADLOCK_AVOIDANCE(p) \
00119    do { \
00120       sig_pri_unlock_private(p); \
00121       usleep(1); \
00122       sig_pri_lock_private(p); \
00123    } while (0)
00124 
00125 static int pri_active_dchan_index(struct sig_pri_span *pri);
00126 
00127 static const char *sig_pri_call_level2str(enum sig_pri_call_level level)
00128 {
00129    switch (level) {
00130    case SIG_PRI_CALL_LEVEL_IDLE:
00131       return "Idle";
00132    case SIG_PRI_CALL_LEVEL_SETUP:
00133       return "Setup";
00134    case SIG_PRI_CALL_LEVEL_OVERLAP:
00135       return "Overlap";
00136    case SIG_PRI_CALL_LEVEL_PROCEEDING:
00137       return "Proceeding";
00138    case SIG_PRI_CALL_LEVEL_ALERTING:
00139       return "Alerting";
00140    case SIG_PRI_CALL_LEVEL_DEFER_DIAL:
00141       return "DeferDial";
00142    case SIG_PRI_CALL_LEVEL_CONNECT:
00143       return "Connect";
00144    }
00145    return "Unknown";
00146 }
00147 
00148 static inline void pri_rel(struct sig_pri_span *pri)
00149 {
00150    ast_mutex_unlock(&pri->lock);
00151 }
00152 
00153 static unsigned int PVT_TO_CHANNEL(struct sig_pri_chan *p)
00154 {
00155    int res = (((p)->prioffset) | ((p)->logicalspan << 8) | (p->mastertrunkgroup ? PRI_EXPLICIT : 0));
00156    ast_debug(5, "prioffset: %d mastertrunkgroup: %d logicalspan: %d result: %d\n",
00157       p->prioffset, p->mastertrunkgroup, p->logicalspan, res);
00158 
00159    return res;
00160 }
00161 
00162 static void sig_pri_handle_dchan_exception(struct sig_pri_span *pri, int index)
00163 {
00164    if (pri->calls->handle_dchan_exception)
00165       pri->calls->handle_dchan_exception(pri, index);
00166 }
00167 
00168 static void sig_pri_set_dialing(struct sig_pri_chan *p, int is_dialing)
00169 {
00170    if (p->calls->set_dialing) {
00171       p->calls->set_dialing(p->chan_pvt, is_dialing);
00172    }
00173 }
00174 
00175 static void sig_pri_set_digital(struct sig_pri_chan *p, int is_digital)
00176 {
00177    p->digital = is_digital;
00178    if (p->calls->set_digital) {
00179       p->calls->set_digital(p->chan_pvt, is_digital);
00180    }
00181 }
00182 
00183 static void sig_pri_set_outgoing(struct sig_pri_chan *p, int is_outgoing)
00184 {
00185    p->outgoing = is_outgoing;
00186    if (p->calls->set_outgoing) {
00187       p->calls->set_outgoing(p->chan_pvt, is_outgoing);
00188    }
00189 }
00190 
00191 void sig_pri_set_alarm(struct sig_pri_chan *p, int in_alarm)
00192 {
00193    /*
00194     * Clear the channel restart flag when the channel alarm changes
00195     * to prevent the flag from getting stuck when the link goes
00196     * down.
00197     */
00198    p->resetting = 0;
00199 
00200    p->inalarm = in_alarm;
00201    if (p->calls->set_alarm) {
00202       p->calls->set_alarm(p->chan_pvt, in_alarm);
00203    }
00204 }
00205 
00206 static const char *sig_pri_get_orig_dialstring(struct sig_pri_chan *p)
00207 {
00208    if (p->calls->get_orig_dialstring) {
00209       return p->calls->get_orig_dialstring(p->chan_pvt);
00210    }
00211    ast_log(LOG_ERROR, "get_orig_dialstring callback not defined\n");
00212    return "";
00213 }
00214 
00215 #if defined(HAVE_PRI_CCSS)
00216 static void sig_pri_make_cc_dialstring(struct sig_pri_chan *p, char *buf, size_t buf_size)
00217 {
00218    if (p->calls->make_cc_dialstring) {
00219       p->calls->make_cc_dialstring(p->chan_pvt, buf, buf_size);
00220    } else {
00221       ast_log(LOG_ERROR, "make_cc_dialstring callback not defined\n");
00222       buf[0] = '\0';
00223    }
00224 }
00225 #endif   /* defined(HAVE_PRI_CCSS) */
00226 
00227 static void sig_pri_dial_digits(struct sig_pri_chan *p, const char *dial_string)
00228 {
00229    if (p->calls->dial_digits) {
00230       p->calls->dial_digits(p->chan_pvt, dial_string);
00231    }
00232 }
00233 
00234 /*!
00235  * \internal
00236  * \brief Reevaluate the PRI span device state.
00237  * \since 1.8
00238  *
00239  * \param pri PRI span control structure.
00240  *
00241  * \return Nothing
00242  *
00243  * \note Assumes the pri->lock is already obtained.
00244  */
00245 static void sig_pri_span_devstate_changed(struct sig_pri_span *pri)
00246 {
00247    if (pri->calls->update_span_devstate) {
00248       pri->calls->update_span_devstate(pri);
00249    }
00250 }
00251 
00252 /*!
00253  * \internal
00254  * \brief Set the caller id information in the parent module.
00255  * \since 1.8
00256  *
00257  * \param p sig_pri channel structure.
00258  *
00259  * \return Nothing
00260  */
00261 static void sig_pri_set_caller_id(struct sig_pri_chan *p)
00262 {
00263    struct ast_party_caller caller;
00264 
00265    if (p->calls->set_callerid) {
00266       ast_party_caller_init(&caller);
00267 
00268       caller.id.name.str = p->cid_name;
00269       caller.id.name.presentation = p->callingpres;
00270       caller.id.name.valid = 1;
00271 
00272       caller.id.number.str = p->cid_num;
00273       caller.id.number.plan = p->cid_ton;
00274       caller.id.number.presentation = p->callingpres;
00275       caller.id.number.valid = 1;
00276 
00277       if (!ast_strlen_zero(p->cid_subaddr)) {
00278          caller.id.subaddress.valid = 1;
00279          //caller.id.subaddress.type = 0;/* nsap */
00280          //caller.id.subaddress.odd_even_indicator = 0;
00281          caller.id.subaddress.str = p->cid_subaddr;
00282       }
00283       caller.id.tag = p->user_tag;
00284 
00285       caller.ani.number.str = p->cid_ani;
00286       //caller.ani.number.plan = p->xxx;
00287       //caller.ani.number.presentation = p->xxx;
00288       caller.ani.number.valid = 1;
00289 
00290       caller.ani2 = p->cid_ani2;
00291       p->calls->set_callerid(p->chan_pvt, &caller);
00292    }
00293 }
00294 
00295 /*!
00296  * \internal
00297  * \brief Set the Dialed Number Identifier.
00298  * \since 1.8
00299  *
00300  * \param p sig_pri channel structure.
00301  * \param dnid Dialed Number Identifier string.
00302  *
00303  * \return Nothing
00304  */
00305 static void sig_pri_set_dnid(struct sig_pri_chan *p, const char *dnid)
00306 {
00307    if (p->calls->set_dnid) {
00308       p->calls->set_dnid(p->chan_pvt, dnid);
00309    }
00310 }
00311 
00312 /*!
00313  * \internal
00314  * \brief Set the Redirecting Directory Number Information Service (RDNIS).
00315  * \since 1.8
00316  *
00317  * \param p sig_pri channel structure.
00318  * \param rdnis Redirecting Directory Number Information Service (RDNIS) string.
00319  *
00320  * \return Nothing
00321  */
00322 static void sig_pri_set_rdnis(struct sig_pri_chan *p, const char *rdnis)
00323 {
00324    if (p->calls->set_rdnis) {
00325       p->calls->set_rdnis(p->chan_pvt, rdnis);
00326    }
00327 }
00328 
00329 static void sig_pri_unlock_private(struct sig_pri_chan *p)
00330 {
00331    if (p->calls->unlock_private)
00332       p->calls->unlock_private(p->chan_pvt);
00333 }
00334 
00335 static void sig_pri_lock_private(struct sig_pri_chan *p)
00336 {
00337    if (p->calls->lock_private)
00338       p->calls->lock_private(p->chan_pvt);
00339 }
00340 
00341 static inline int pri_grab(struct sig_pri_chan *p, struct sig_pri_span *pri)
00342 {
00343    int res;
00344    /* Grab the lock first */
00345    do {
00346       res = ast_mutex_trylock(&pri->lock);
00347       if (res) {
00348          PRI_DEADLOCK_AVOIDANCE(p);
00349       }
00350    } while (res);
00351    /* Then break the poll */
00352    pthread_kill(pri->master, SIGURG);
00353    return 0;
00354 }
00355 
00356 /*!
00357  * \internal
00358  * \brief Convert PRI redirecting reason to asterisk version.
00359  * \since 1.8
00360  *
00361  * \param pri_reason PRI redirecting reason.
00362  *
00363  * \return Equivalent asterisk redirecting reason value.
00364  */
00365 static enum AST_REDIRECTING_REASON pri_to_ast_reason(int pri_reason)
00366 {
00367    enum AST_REDIRECTING_REASON ast_reason;
00368 
00369    switch (pri_reason) {
00370    case PRI_REDIR_FORWARD_ON_BUSY:
00371       ast_reason = AST_REDIRECTING_REASON_USER_BUSY;
00372       break;
00373    case PRI_REDIR_FORWARD_ON_NO_REPLY:
00374       ast_reason = AST_REDIRECTING_REASON_NO_ANSWER;
00375       break;
00376    case PRI_REDIR_DEFLECTION:
00377       ast_reason = AST_REDIRECTING_REASON_DEFLECTION;
00378       break;
00379    case PRI_REDIR_UNCONDITIONAL:
00380       ast_reason = AST_REDIRECTING_REASON_UNCONDITIONAL;
00381       break;
00382    case PRI_REDIR_UNKNOWN:
00383    default:
00384       ast_reason = AST_REDIRECTING_REASON_UNKNOWN;
00385       break;
00386    }
00387 
00388    return ast_reason;
00389 }
00390 
00391 /*!
00392  * \internal
00393  * \brief Convert asterisk redirecting reason to PRI version.
00394  * \since 1.8
00395  *
00396  * \param ast_reason Asterisk redirecting reason.
00397  *
00398  * \return Equivalent PRI redirecting reason value.
00399  */
00400 static int ast_to_pri_reason(enum AST_REDIRECTING_REASON ast_reason)
00401 {
00402    int pri_reason;
00403 
00404    switch (ast_reason) {
00405    case AST_REDIRECTING_REASON_USER_BUSY:
00406       pri_reason = PRI_REDIR_FORWARD_ON_BUSY;
00407       break;
00408    case AST_REDIRECTING_REASON_NO_ANSWER:
00409       pri_reason = PRI_REDIR_FORWARD_ON_NO_REPLY;
00410       break;
00411    case AST_REDIRECTING_REASON_UNCONDITIONAL:
00412       pri_reason = PRI_REDIR_UNCONDITIONAL;
00413       break;
00414    case AST_REDIRECTING_REASON_DEFLECTION:
00415       pri_reason = PRI_REDIR_DEFLECTION;
00416       break;
00417    case AST_REDIRECTING_REASON_UNKNOWN:
00418    default:
00419       pri_reason = PRI_REDIR_UNKNOWN;
00420       break;
00421    }
00422 
00423    return pri_reason;
00424 }
00425 
00426 /*!
00427  * \internal
00428  * \brief Convert PRI number presentation to asterisk version.
00429  * \since 1.8
00430  *
00431  * \param pri_presentation PRI number presentation.
00432  *
00433  * \return Equivalent asterisk number presentation value.
00434  */
00435 static int pri_to_ast_presentation(int pri_presentation)
00436 {
00437    int ast_presentation;
00438 
00439    switch (pri_presentation) {
00440    case PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_UNSCREENED:
00441       ast_presentation = AST_PRES_ALLOWED | AST_PRES_USER_NUMBER_UNSCREENED;
00442       break;
00443    case PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_PASSED_SCREEN:
00444       ast_presentation = AST_PRES_ALLOWED | AST_PRES_USER_NUMBER_PASSED_SCREEN;
00445       break;
00446    case PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_FAILED_SCREEN:
00447       ast_presentation = AST_PRES_ALLOWED | AST_PRES_USER_NUMBER_FAILED_SCREEN;
00448       break;
00449    case PRI_PRES_ALLOWED | PRI_PRES_NETWORK_NUMBER:
00450       ast_presentation = AST_PRES_ALLOWED | AST_PRES_NETWORK_NUMBER;
00451       break;
00452 
00453    case PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_UNSCREENED:
00454       ast_presentation = AST_PRES_RESTRICTED | AST_PRES_USER_NUMBER_UNSCREENED;
00455       break;
00456    case PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_PASSED_SCREEN:
00457       ast_presentation = AST_PRES_RESTRICTED | AST_PRES_USER_NUMBER_PASSED_SCREEN;
00458       break;
00459    case PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_FAILED_SCREEN:
00460       ast_presentation = AST_PRES_RESTRICTED | AST_PRES_USER_NUMBER_FAILED_SCREEN;
00461       break;
00462    case PRI_PRES_RESTRICTED | PRI_PRES_NETWORK_NUMBER:
00463       ast_presentation = AST_PRES_RESTRICTED | AST_PRES_NETWORK_NUMBER;
00464       break;
00465 
00466    case PRI_PRES_UNAVAILABLE | PRI_PRES_USER_NUMBER_UNSCREENED:
00467    case PRI_PRES_UNAVAILABLE | PRI_PRES_USER_NUMBER_PASSED_SCREEN:
00468    case PRI_PRES_UNAVAILABLE | PRI_PRES_USER_NUMBER_FAILED_SCREEN:
00469    case PRI_PRES_UNAVAILABLE | PRI_PRES_NETWORK_NUMBER:
00470       ast_presentation = AST_PRES_NUMBER_NOT_AVAILABLE;
00471       break;
00472 
00473    default:
00474       ast_presentation = AST_PRES_RESTRICTED | AST_PRES_USER_NUMBER_UNSCREENED;
00475       break;
00476    }
00477 
00478    return ast_presentation;
00479 }
00480 
00481 /*!
00482  * \internal
00483  * \brief Convert asterisk number presentation to PRI version.
00484  * \since 1.8
00485  *
00486  * \param ast_presentation Asterisk number presentation.
00487  *
00488  * \return Equivalent PRI number presentation value.
00489  */
00490 static int ast_to_pri_presentation(int ast_presentation)
00491 {
00492    int pri_presentation;
00493 
00494    switch (ast_presentation) {
00495    case AST_PRES_ALLOWED | AST_PRES_USER_NUMBER_UNSCREENED:
00496       pri_presentation = PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_UNSCREENED;
00497       break;
00498    case AST_PRES_ALLOWED | AST_PRES_USER_NUMBER_PASSED_SCREEN:
00499       pri_presentation = PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_PASSED_SCREEN;
00500       break;
00501    case AST_PRES_ALLOWED | AST_PRES_USER_NUMBER_FAILED_SCREEN:
00502       pri_presentation = PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_FAILED_SCREEN;
00503       break;
00504    case AST_PRES_ALLOWED | AST_PRES_NETWORK_NUMBER:
00505       pri_presentation = PRI_PRES_ALLOWED | PRI_PRES_NETWORK_NUMBER;
00506       break;
00507 
00508    case AST_PRES_RESTRICTED | AST_PRES_USER_NUMBER_UNSCREENED:
00509       pri_presentation = PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_UNSCREENED;
00510       break;
00511    case AST_PRES_RESTRICTED | AST_PRES_USER_NUMBER_PASSED_SCREEN:
00512       pri_presentation = PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_PASSED_SCREEN;
00513       break;
00514    case AST_PRES_RESTRICTED | AST_PRES_USER_NUMBER_FAILED_SCREEN:
00515       pri_presentation = PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_FAILED_SCREEN;
00516       break;
00517    case AST_PRES_RESTRICTED | AST_PRES_NETWORK_NUMBER:
00518       pri_presentation = PRI_PRES_RESTRICTED | PRI_PRES_NETWORK_NUMBER;
00519       break;
00520 
00521    case AST_PRES_UNAVAILABLE | AST_PRES_USER_NUMBER_UNSCREENED:
00522    case AST_PRES_UNAVAILABLE | AST_PRES_USER_NUMBER_PASSED_SCREEN:
00523    case AST_PRES_UNAVAILABLE | AST_PRES_USER_NUMBER_FAILED_SCREEN:
00524    case AST_PRES_UNAVAILABLE | AST_PRES_NETWORK_NUMBER:
00525       pri_presentation = PRES_NUMBER_NOT_AVAILABLE;
00526       break;
00527 
00528    default:
00529       pri_presentation = PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_UNSCREENED;
00530       break;
00531    }
00532 
00533    return pri_presentation;
00534 }
00535 
00536 /*!
00537  * \internal
00538  * \brief Convert PRI name char_set to asterisk version.
00539  * \since 1.8
00540  *
00541  * \param pri_char_set PRI name char_set.
00542  *
00543  * \return Equivalent asterisk name char_set value.
00544  */
00545 static enum AST_PARTY_CHAR_SET pri_to_ast_char_set(int pri_char_set)
00546 {
00547    enum AST_PARTY_CHAR_SET ast_char_set;
00548 
00549    switch (pri_char_set) {
00550    default:
00551    case PRI_CHAR_SET_UNKNOWN:
00552       ast_char_set = AST_PARTY_CHAR_SET_UNKNOWN;
00553       break;
00554    case PRI_CHAR_SET_ISO8859_1:
00555       ast_char_set = AST_PARTY_CHAR_SET_ISO8859_1;
00556       break;
00557    case PRI_CHAR_SET_WITHDRAWN:
00558       ast_char_set = AST_PARTY_CHAR_SET_WITHDRAWN;
00559       break;
00560    case PRI_CHAR_SET_ISO8859_2:
00561       ast_char_set = AST_PARTY_CHAR_SET_ISO8859_2;
00562       break;
00563    case PRI_CHAR_SET_ISO8859_3:
00564       ast_char_set = AST_PARTY_CHAR_SET_ISO8859_3;
00565       break;
00566    case PRI_CHAR_SET_ISO8859_4:
00567       ast_char_set = AST_PARTY_CHAR_SET_ISO8859_4;
00568       break;
00569    case PRI_CHAR_SET_ISO8859_5:
00570       ast_char_set = AST_PARTY_CHAR_SET_ISO8859_5;
00571       break;
00572    case PRI_CHAR_SET_ISO8859_7:
00573       ast_char_set = AST_PARTY_CHAR_SET_ISO8859_7;
00574       break;
00575    case PRI_CHAR_SET_ISO10646_BMPSTRING:
00576       ast_char_set = AST_PARTY_CHAR_SET_ISO10646_BMPSTRING;
00577       break;
00578    case PRI_CHAR_SET_ISO10646_UTF_8STRING:
00579       ast_char_set = AST_PARTY_CHAR_SET_ISO10646_UTF_8STRING;
00580       break;
00581    }
00582 
00583    return ast_char_set;
00584 }
00585 
00586 /*!
00587  * \internal
00588  * \brief Convert asterisk name char_set to PRI version.
00589  * \since 1.8
00590  *
00591  * \param ast_char_set Asterisk name char_set.
00592  *
00593  * \return Equivalent PRI name char_set value.
00594  */
00595 static int ast_to_pri_char_set(enum AST_PARTY_CHAR_SET ast_char_set)
00596 {
00597    int pri_char_set;
00598 
00599    switch (ast_char_set) {
00600    default:
00601    case AST_PARTY_CHAR_SET_UNKNOWN:
00602       pri_char_set = PRI_CHAR_SET_UNKNOWN;
00603       break;
00604    case AST_PARTY_CHAR_SET_ISO8859_1:
00605       pri_char_set = PRI_CHAR_SET_ISO8859_1;
00606       break;
00607    case AST_PARTY_CHAR_SET_WITHDRAWN:
00608       pri_char_set = PRI_CHAR_SET_WITHDRAWN;
00609       break;
00610    case AST_PARTY_CHAR_SET_ISO8859_2:
00611       pri_char_set = PRI_CHAR_SET_ISO8859_2;
00612       break;
00613    case AST_PARTY_CHAR_SET_ISO8859_3:
00614       pri_char_set = PRI_CHAR_SET_ISO8859_3;
00615       break;
00616    case AST_PARTY_CHAR_SET_ISO8859_4:
00617       pri_char_set = PRI_CHAR_SET_ISO8859_4;
00618       break;
00619    case AST_PARTY_CHAR_SET_ISO8859_5:
00620       pri_char_set = PRI_CHAR_SET_ISO8859_5;
00621       break;
00622    case AST_PARTY_CHAR_SET_ISO8859_7:
00623       pri_char_set = PRI_CHAR_SET_ISO8859_7;
00624       break;
00625    case AST_PARTY_CHAR_SET_ISO10646_BMPSTRING:
00626       pri_char_set = PRI_CHAR_SET_ISO10646_BMPSTRING;
00627       break;
00628    case AST_PARTY_CHAR_SET_ISO10646_UTF_8STRING:
00629       pri_char_set = PRI_CHAR_SET_ISO10646_UTF_8STRING;
00630       break;
00631    }
00632 
00633    return pri_char_set;
00634 }
00635 
00636 #if defined(HAVE_PRI_SUBADDR)
00637 /*!
00638  * \internal
00639  * \brief Fill in the asterisk party subaddress from the given PRI party subaddress.
00640  * \since 1.8
00641  *
00642  * \param ast_subaddress Asterisk party subaddress structure.
00643  * \param pri_subaddress PRI party subaddress structure.
00644  *
00645  * \return Nothing
00646  *
00647  */
00648 static void sig_pri_set_subaddress(struct ast_party_subaddress *ast_subaddress, const struct pri_party_subaddress *pri_subaddress)
00649 {
00650    char *cnum, *ptr;
00651    int x, len;
00652 
00653    if (ast_subaddress->str) {
00654       ast_free(ast_subaddress->str);
00655    }
00656    if (pri_subaddress->length <= 0) {
00657       ast_party_subaddress_init(ast_subaddress);
00658       return;
00659    }
00660 
00661    if (!pri_subaddress->type) {
00662       /* NSAP */
00663       ast_subaddress->str = ast_strdup((char *) pri_subaddress->data);
00664    } else {
00665       /* User Specified */
00666       if (!(cnum = ast_malloc(2 * pri_subaddress->length + 1))) {
00667          ast_party_subaddress_init(ast_subaddress);
00668          return;
00669       }
00670 
00671       ptr = cnum;
00672       len = pri_subaddress->length - 1; /* -1 account for zero based indexing */
00673       for (x = 0; x < len; ++x) {
00674          ptr += sprintf(ptr, "%02x", pri_subaddress->data[x]);
00675       }
00676 
00677       if (pri_subaddress->odd_even_indicator) {
00678          /* ODD */
00679          sprintf(ptr, "%01x", (pri_subaddress->data[len]) >> 4);
00680       } else {
00681          /* EVEN */
00682          sprintf(ptr, "%02x", pri_subaddress->data[len]);
00683       }
00684       ast_subaddress->str = cnum;
00685    }
00686    ast_subaddress->type = pri_subaddress->type;
00687    ast_subaddress->odd_even_indicator = pri_subaddress->odd_even_indicator;
00688    ast_subaddress->valid = 1;
00689 }
00690 #endif   /* defined(HAVE_PRI_SUBADDR) */
00691 
00692 #if defined(HAVE_PRI_SUBADDR)
00693 static unsigned char ast_pri_pack_hex_char(char c)
00694 {
00695    unsigned char res;
00696 
00697    if (c < '0') {
00698       res = 0;
00699    } else if (c < ('9' + 1)) {
00700       res = c - '0';
00701    } else if (c < 'A') {
00702       res = 0;
00703    } else if (c < ('F' + 1)) {
00704       res = c - 'A' + 10;
00705    } else if (c < 'a') {
00706       res = 0;
00707    } else if (c < ('f' + 1)) {
00708       res = c - 'a' + 10;
00709    } else {
00710       res = 0;
00711    }
00712    return res;
00713 }
00714 #endif   /* defined(HAVE_PRI_SUBADDR) */
00715 
00716 #if defined(HAVE_PRI_SUBADDR)
00717 /*!
00718  * \internal
00719  * \brief Convert a null terminated hexadecimal string to a packed hex byte array.
00720  * \details left justified, with 0 padding if odd length.
00721  * \since 1.8
00722  *
00723  * \param dst pointer to packed byte array.
00724  * \param src pointer to null terminated hexadecimal string.
00725  * \param maxlen destination array size.
00726  *
00727  * \return Length of byte array
00728  *
00729  * \note The dst is not an ASCIIz string.
00730  * \note The src is an ASCIIz hex string.
00731  */
00732 static int ast_pri_pack_hex_string(unsigned char *dst, char *src, int maxlen)
00733 {
00734    int res = 0;
00735    int len = strlen(src);
00736 
00737    if (len > (2 * maxlen)) {
00738       len = 2 * maxlen;
00739    }
00740 
00741    res = len / 2 + len % 2;
00742 
00743    while (len > 1) {
00744       *dst = ast_pri_pack_hex_char(*src) << 4;
00745       src++;
00746       *dst |= ast_pri_pack_hex_char(*src);
00747       dst++, src++;
00748       len -= 2;
00749    }
00750    if (len) { /* 1 left */
00751       *dst = ast_pri_pack_hex_char(*src) << 4;
00752    }
00753    return res;
00754 }
00755 #endif   /* defined(HAVE_PRI_SUBADDR) */
00756 
00757 #if defined(HAVE_PRI_SUBADDR)
00758 /*!
00759  * \internal
00760  * \brief Fill in the PRI party subaddress from the given asterisk party subaddress.
00761  * \since 1.8
00762  *
00763  * \param pri_subaddress PRI party subaddress structure.
00764  * \param ast_subaddress Asterisk party subaddress structure.
00765  *
00766  * \return Nothing
00767  *
00768  * \note Assumes that pri_subaddress has been previously memset to zero.
00769  */
00770 static void sig_pri_party_subaddress_from_ast(struct pri_party_subaddress *pri_subaddress, const struct ast_party_subaddress *ast_subaddress)
00771 {
00772    if (ast_subaddress->valid && !ast_strlen_zero(ast_subaddress->str)) {
00773       pri_subaddress->type = ast_subaddress->type;
00774       if (!ast_subaddress->type) {
00775          /* 0 = NSAP */
00776          ast_copy_string((char *) pri_subaddress->data, ast_subaddress->str,
00777             sizeof(pri_subaddress->data));
00778          pri_subaddress->length = strlen((char *) pri_subaddress->data);
00779          pri_subaddress->odd_even_indicator = 0;
00780          pri_subaddress->valid = 1;
00781       } else {
00782          /* 2 = User Specified */
00783          /*
00784           * Copy HexString to packed HexData,
00785           * if odd length then right pad trailing byte with 0
00786           */
00787          int length = ast_pri_pack_hex_string(pri_subaddress->data,
00788             ast_subaddress->str, sizeof(pri_subaddress->data));
00789 
00790          pri_subaddress->length = length; /* packed data length */
00791 
00792          length = strlen(ast_subaddress->str);
00793          if (length > 2 * sizeof(pri_subaddress->data)) {
00794             pri_subaddress->odd_even_indicator = 0;
00795          } else {
00796             pri_subaddress->odd_even_indicator = (length & 1);
00797          }
00798          pri_subaddress->valid = 1;
00799       }
00800    }
00801 }
00802 #endif   /* defined(HAVE_PRI_SUBADDR) */
00803 
00804 /*!
00805  * \internal
00806  * \brief Fill in the PRI party name from the given asterisk party name.
00807  * \since 1.8
00808  *
00809  * \param pri_name PRI party name structure.
00810  * \param ast_name Asterisk party name structure.
00811  *
00812  * \return Nothing
00813  *
00814  * \note Assumes that pri_name has been previously memset to zero.
00815  */
00816 static void sig_pri_party_name_from_ast(struct pri_party_name *pri_name, const struct ast_party_name *ast_name)
00817 {
00818    if (!ast_name->valid) {
00819       return;
00820    }
00821    pri_name->valid = 1;
00822    pri_name->presentation = ast_to_pri_presentation(ast_name->presentation);
00823    pri_name->char_set = ast_to_pri_char_set(ast_name->char_set);
00824    if (!ast_strlen_zero(ast_name->str)) {
00825       ast_copy_string(pri_name->str, ast_name->str, sizeof(pri_name->str));
00826    }
00827 }
00828 
00829 /*!
00830  * \internal
00831  * \brief Fill in the PRI party number from the given asterisk party number.
00832  * \since 1.8
00833  *
00834  * \param pri_number PRI party number structure.
00835  * \param ast_number Asterisk party number structure.
00836  *
00837  * \return Nothing
00838  *
00839  * \note Assumes that pri_number has been previously memset to zero.
00840  */
00841 static void sig_pri_party_number_from_ast(struct pri_party_number *pri_number, const struct ast_party_number *ast_number)
00842 {
00843    if (!ast_number->valid) {
00844       return;
00845    }
00846    pri_number->valid = 1;
00847    pri_number->presentation = ast_to_pri_presentation(ast_number->presentation);
00848    pri_number->plan = ast_number->plan;
00849    if (!ast_strlen_zero(ast_number->str)) {
00850       ast_copy_string(pri_number->str, ast_number->str, sizeof(pri_number->str));
00851    }
00852 }
00853 
00854 /*!
00855  * \internal
00856  * \brief Fill in the PRI party id from the given asterisk party id.
00857  * \since 1.8
00858  *
00859  * \param pri_id PRI party id structure.
00860  * \param ast_id Asterisk party id structure.
00861  *
00862  * \return Nothing
00863  *
00864  * \note Assumes that pri_id has been previously memset to zero.
00865  */
00866 static void sig_pri_party_id_from_ast(struct pri_party_id *pri_id, const struct ast_party_id *ast_id)
00867 {
00868    sig_pri_party_name_from_ast(&pri_id->name, &ast_id->name);
00869    sig_pri_party_number_from_ast(&pri_id->number, &ast_id->number);
00870 #if defined(HAVE_PRI_SUBADDR)
00871    sig_pri_party_subaddress_from_ast(&pri_id->subaddress, &ast_id->subaddress);
00872 #endif   /* defined(HAVE_PRI_SUBADDR) */
00873 }
00874 
00875 /*!
00876  * \internal
00877  * \brief Update the PRI redirecting information for the current call.
00878  * \since 1.8
00879  *
00880  * \param pvt sig_pri private channel structure.
00881  * \param ast Asterisk channel
00882  *
00883  * \return Nothing
00884  *
00885  * \note Assumes that the PRI lock is already obtained.
00886  */
00887 static void sig_pri_redirecting_update(struct sig_pri_chan *pvt, struct ast_channel *ast)
00888 {
00889    struct pri_party_redirecting pri_redirecting;
00890 
00891 /*! \todo XXX Original called data can be put in a channel data store that is inherited. */
00892 
00893    memset(&pri_redirecting, 0, sizeof(pri_redirecting));
00894    sig_pri_party_id_from_ast(&pri_redirecting.from, &ast->redirecting.from);
00895    sig_pri_party_id_from_ast(&pri_redirecting.to, &ast->redirecting.to);
00896    pri_redirecting.count = ast->redirecting.count;
00897    pri_redirecting.reason = ast_to_pri_reason(ast->redirecting.reason);
00898 
00899    pri_redirecting_update(pvt->pri->pri, pvt->call, &pri_redirecting);
00900 }
00901 
00902 /*!
00903  * \internal
00904  * \brief Reset DTMF detector.
00905  * \since 1.8
00906  *
00907  * \param p sig_pri channel structure.
00908  *
00909  * \return Nothing
00910  */
00911 static void sig_pri_dsp_reset_and_flush_digits(struct sig_pri_chan *p)
00912 {
00913    if (p->calls->dsp_reset_and_flush_digits) {
00914       p->calls->dsp_reset_and_flush_digits(p->chan_pvt);
00915    }
00916 }
00917 
00918 static int sig_pri_set_echocanceller(struct sig_pri_chan *p, int enable)
00919 {
00920    if (p->calls->set_echocanceller)
00921       return p->calls->set_echocanceller(p->chan_pvt, enable);
00922    else
00923       return -1;
00924 }
00925 
00926 static void sig_pri_fixup_chans(struct sig_pri_chan *old_chan, struct sig_pri_chan *new_chan)
00927 {
00928    if (old_chan->calls->fixup_chans)
00929       old_chan->calls->fixup_chans(old_chan->chan_pvt, new_chan->chan_pvt);
00930 }
00931 
00932 static int sig_pri_play_tone(struct sig_pri_chan *p, enum sig_pri_tone tone)
00933 {
00934    if (p->calls->play_tone)
00935       return p->calls->play_tone(p->chan_pvt, tone);
00936    else
00937       return -1;
00938 }
00939 
00940 static struct ast_channel *sig_pri_new_ast_channel(struct sig_pri_chan *p, int state, int ulaw, int transfercapability, char *exten, const struct ast_channel *requestor)
00941 {
00942    struct ast_channel *c;
00943 
00944    if (p->calls->new_ast_channel) {
00945       c = p->calls->new_ast_channel(p->chan_pvt, state, ulaw, exten, requestor);
00946    } else {
00947       return NULL;
00948    }
00949    if (!c) {
00950       return NULL;
00951    }
00952 
00953    if (!p->owner)
00954       p->owner = c;
00955    p->isidlecall = 0;
00956    p->alreadyhungup = 0;
00957    c->transfercapability = transfercapability;
00958    pbx_builtin_setvar_helper(c, "TRANSFERCAPABILITY",
00959       ast_transfercapability2str(transfercapability));
00960    if (transfercapability & AST_TRANS_CAP_DIGITAL) {
00961       sig_pri_set_digital(p, 1);
00962    }
00963    if (p->pri) {
00964       ast_mutex_lock(&p->pri->lock);
00965       sig_pri_span_devstate_changed(p->pri);
00966       ast_mutex_unlock(&p->pri->lock);
00967    }
00968 
00969    return c;
00970 }
00971 
00972 /*!
00973  * \internal
00974  * \brief Open the PRI channel media path.
00975  * \since 1.8
00976  *
00977  * \param p Channel private control structure.
00978  *
00979  * \return Nothing
00980  */
00981 static void sig_pri_open_media(struct sig_pri_chan *p)
00982 {
00983    if (p->no_b_channel) {
00984       return;
00985    }
00986 
00987    if (p->calls->open_media) {
00988       p->calls->open_media(p->chan_pvt);
00989    }
00990 }
00991 
00992 /*!
00993  * \internal
00994  * \brief Post an AMI B channel association event.
00995  * \since 1.8
00996  *
00997  * \param p Channel private control structure.
00998  *
00999  * \note Assumes the private and owner are locked.
01000  *
01001  * \return Nothing
01002  */
01003 static void sig_pri_ami_channel_event(struct sig_pri_chan *p)
01004 {
01005    if (p->calls->ami_channel_event) {
01006       p->calls->ami_channel_event(p->chan_pvt, p->owner);
01007    }
01008 }
01009 
01010 struct ast_channel *sig_pri_request(struct sig_pri_chan *p, enum sig_pri_law law, const struct ast_channel *requestor, int transfercapability)
01011 {
01012    struct ast_channel *ast;
01013 
01014    ast_log(LOG_DEBUG, "%s %d\n", __FUNCTION__, p->channel);
01015 
01016    sig_pri_set_outgoing(p, 1);
01017    ast = sig_pri_new_ast_channel(p, AST_STATE_RESERVED, law, transfercapability, p->exten, requestor);
01018    if (!ast) {
01019       sig_pri_set_outgoing(p, 0);
01020    }
01021    return ast;
01022 }
01023 
01024 int pri_is_up(struct sig_pri_span *pri)
01025 {
01026    int x;
01027    for (x = 0; x < SIG_PRI_NUM_DCHANS; x++) {
01028       if (pri->dchanavail[x] == DCHAN_AVAILABLE)
01029          return 1;
01030    }
01031    return 0;
01032 }
01033 
01034 static const char *pri_order(int level)
01035 {
01036    switch (level) {
01037    case 0:
01038       return "Primary";
01039    case 1:
01040       return "Secondary";
01041    case 2:
01042       return "Tertiary";
01043    case 3:
01044       return "Quaternary";
01045    default:
01046       return "<Unknown>";
01047    }
01048 }
01049 
01050 /* Returns index of the active dchan */
01051 static int pri_active_dchan_index(struct sig_pri_span *pri)
01052 {
01053    int x;
01054 
01055    for (x = 0; x < SIG_PRI_NUM_DCHANS; x++) {
01056       if ((pri->dchans[x] == pri->pri))
01057          return x;
01058    }
01059 
01060    ast_log(LOG_WARNING, "No active dchan found!\n");
01061    return -1;
01062 }
01063 
01064 static void pri_find_dchan(struct sig_pri_span *pri)
01065 {
01066    struct pri *old;
01067    int oldslot = -1;
01068    int newslot = -1;
01069    int idx;
01070 
01071    old = pri->pri;
01072    for (idx = 0; idx < SIG_PRI_NUM_DCHANS; ++idx) {
01073       if (!pri->dchans[idx]) {
01074          /* No more D channels defined on the span. */
01075          break;
01076       }
01077       if (pri->dchans[idx] == old) {
01078          oldslot = idx;
01079       }
01080       if (newslot < 0 && pri->dchanavail[idx] == DCHAN_AVAILABLE) {
01081          newslot = idx;
01082       }
01083    }
01084    /* At this point, idx is a count of how many D-channels are defined on the span. */
01085 
01086    if (1 < idx) {
01087       /* We have several D-channels defined on the span.  (NFAS PRI setup) */
01088       if (newslot < 0) {
01089          /* No D-channels available.  Default to the primary D-channel. */
01090          newslot = 0;
01091 
01092          if (!pri->no_d_channels) {
01093             pri->no_d_channels = 1;
01094             if (old && oldslot != newslot) {
01095                ast_log(LOG_WARNING,
01096                   "Span %d: No D-channels up!  Switching selected D-channel from %s to %s.\n",
01097                   pri->span, pri_order(oldslot), pri_order(newslot));
01098             } else {
01099                ast_log(LOG_WARNING, "Span %d: No D-channels up!\n", pri->span);
01100             }
01101          }
01102       } else {
01103          pri->no_d_channels = 0;
01104       }
01105       if (old && oldslot != newslot) {
01106          ast_log(LOG_NOTICE,
01107             "Switching selected D-channel from %s (fd %d) to %s (fd %d)!\n",
01108             pri_order(oldslot), pri->fds[oldslot],
01109             pri_order(newslot), pri->fds[newslot]);
01110       }
01111    } else {
01112       if (newslot < 0) {
01113          /* The only D-channel is not up. */
01114          newslot = 0;
01115 
01116          if (!pri->no_d_channels) {
01117             pri->no_d_channels = 1;
01118 
01119             /*
01120              * This is annoying to see on non-persistent layer 2
01121              * connections.  Let's not complain in that case.
01122              */
01123             if (pri->sig != SIG_BRI_PTMP) {
01124                ast_log(LOG_WARNING, "Span %d: D-channel is down!\n", pri->span);
01125             }
01126          }
01127       } else {
01128          pri->no_d_channels = 0;
01129       }
01130    }
01131    pri->pri = pri->dchans[newslot];
01132 }
01133 
01134 /*!
01135  * \internal
01136  * \brief Determine if a private channel structure is in use.
01137  * \since 1.8
01138  *
01139  * \param pvt Channel to determine if in use.
01140  *
01141  * \return TRUE if the channel is in use.
01142  */
01143 static int sig_pri_is_chan_in_use(struct sig_pri_chan *pvt)
01144 {
01145    return pvt->owner || pvt->call || pvt->allocated || pvt->resetting || pvt->inalarm;
01146 }
01147 
01148 /*!
01149  * \brief Determine if a private channel structure is available.
01150  * \since 1.8
01151  *
01152  * \param pvt Channel to determine if available.
01153  *
01154  * \return TRUE if the channel is available.
01155  */
01156 int sig_pri_is_chan_available(struct sig_pri_chan *pvt)
01157 {
01158    return !sig_pri_is_chan_in_use(pvt)
01159 #if defined(HAVE_PRI_SERVICE_MESSAGES)
01160       /* And not out-of-service */
01161       && !pvt->service_status
01162 #endif   /* defined(HAVE_PRI_SERVICE_MESSAGES) */
01163       ;
01164 }
01165 
01166 /*!
01167  * \internal
01168  * \brief Obtain the sig_pri owner channel lock if the owner exists.
01169  * \since 1.8
01170  *
01171  * \param pri PRI span control structure.
01172  * \param chanpos Channel position in the span.
01173  *
01174  * \note Assumes the pri->lock is already obtained.
01175  * \note Assumes the sig_pri_lock_private(pri->pvts[chanpos]) is already obtained.
01176  *
01177  * \return Nothing
01178  */
01179 static void sig_pri_lock_owner(struct sig_pri_span *pri, int chanpos)
01180 {
01181    for (;;) {
01182       if (!pri->pvts[chanpos]->owner) {
01183          /* There is no owner lock to get. */
01184          break;
01185       }
01186       if (!ast_channel_trylock(pri->pvts[chanpos]->owner)) {
01187          /* We got the lock */
01188          break;
01189       }
01190       /* We must unlock the PRI to avoid the possibility of a deadlock */
01191       ast_mutex_unlock(&pri->lock);
01192       PRI_DEADLOCK_AVOIDANCE(pri->pvts[chanpos]);
01193       ast_mutex_lock(&pri->lock);
01194    }
01195 }
01196 
01197 /*!
01198  * \internal
01199  * \brief Queue the given frame onto the owner channel.
01200  * \since 1.8
01201  *
01202  * \param pri PRI span control structure.
01203  * \param chanpos Channel position in the span.
01204  * \param frame Frame to queue onto the owner channel.
01205  *
01206  * \note Assumes the pri->lock is already obtained.
01207  * \note Assumes the sig_pri_lock_private(pri->pvts[chanpos]) is already obtained.
01208  *
01209  * \return Nothing
01210  */
01211 static void pri_queue_frame(struct sig_pri_span *pri, int chanpos, struct ast_frame *frame)
01212 {
01213    sig_pri_lock_owner(pri, chanpos);
01214    if (pri->pvts[chanpos]->owner) {
01215       ast_queue_frame(pri->pvts[chanpos]->owner, frame);
01216       ast_channel_unlock(pri->pvts[chanpos]->owner);
01217    }
01218 }
01219 
01220 /*!
01221  * \internal
01222  * \brief Queue a control frame of the specified subclass onto the owner channel.
01223  * \since 1.8
01224  *
01225  * \param pri PRI span control structure.
01226  * \param chanpos Channel position in the span.
01227  * \param subclass Control frame subclass to queue onto the owner channel.
01228  *
01229  * \note Assumes the pri->lock is already obtained.
01230  * \note Assumes the sig_pri_lock_private(pri->pvts[chanpos]) is already obtained.
01231  *
01232  * \return Nothing
01233  */
01234 static void pri_queue_control(struct sig_pri_span *pri, int chanpos, int subclass)
01235 {
01236    struct ast_frame f = {AST_FRAME_CONTROL, };
01237    struct sig_pri_chan *p = pri->pvts[chanpos];
01238 
01239    if (p->calls->queue_control) {
01240       p->calls->queue_control(p->chan_pvt, subclass);
01241    }
01242 
01243    f.subclass.integer = subclass;
01244    pri_queue_frame(pri, chanpos, &f);
01245 }
01246 
01247 /*!
01248  * \internal
01249  * \brief Find the channel associated with the libpri call.
01250  * \since 1.10
01251  *
01252  * \param pri PRI span control structure.
01253  * \param call LibPRI opaque call pointer to find.
01254  *
01255  * \note Assumes the pri->lock is already obtained.
01256  *
01257  * \retval array-index into private pointer array on success.
01258  * \retval -1 on error.
01259  */
01260 static int pri_find_principle_by_call(struct sig_pri_span *pri, q931_call *call)
01261 {
01262    int idx;
01263 
01264    if (!call) {
01265       /* Cannot find a call without a call. */
01266       return -1;
01267    }
01268    for (idx = 0; idx < pri->numchans; ++idx) {
01269       if (pri->pvts[idx] && pri->pvts[idx]->call == call) {
01270          /* Found the principle */
01271          return idx;
01272       }
01273    }
01274    return -1;
01275 }
01276 
01277 /*!
01278  * \internal
01279  * \brief Kill the call.
01280  * \since 1.10
01281  *
01282  * \param pri PRI span control structure.
01283  * \param call LibPRI opaque call pointer to find.
01284  * \param cause Reason call was killed.
01285  *
01286  * \note Assumes the pvt->pri->lock is already obtained.
01287  *
01288  * \return Nothing
01289  */
01290 static void sig_pri_kill_call(struct sig_pri_span *pri, q931_call *call, int cause)
01291 {
01292    int chanpos;
01293 
01294    chanpos = pri_find_principle_by_call(pri, call);
01295    if (chanpos < 0) {
01296       pri_hangup(pri->pri, call, cause);
01297       return;
01298    }
01299    sig_pri_lock_private(pri->pvts[chanpos]);
01300    if (!pri->pvts[chanpos]->owner) {
01301       pri_hangup(pri->pri, call, cause);
01302       pri->pvts[chanpos]->call = NULL;
01303       sig_pri_unlock_private(pri->pvts[chanpos]);
01304       sig_pri_span_devstate_changed(pri);
01305       return;
01306    }
01307    pri->pvts[chanpos]->owner->hangupcause = cause;
01308    pri_queue_control(pri, chanpos, AST_CONTROL_HANGUP);
01309    sig_pri_unlock_private(pri->pvts[chanpos]);
01310 }
01311 
01312 /*!
01313  * \internal
01314  * \brief Find the private structure for the libpri call.
01315  *
01316  * \param pri PRI span control structure.
01317  * \param channel LibPRI encoded channel ID.
01318  * \param call LibPRI opaque call pointer.
01319  *
01320  * \note Assumes the pri->lock is already obtained.
01321  *
01322  * \retval array-index into private pointer array on success.
01323  * \retval -1 on error.
01324  */
01325 static int pri_find_principle(struct sig_pri_span *pri, int channel, q931_call *call)
01326 {
01327    int x;
01328    int span;
01329    int principle;
01330    int prioffset;
01331 
01332    if (channel < 0) {
01333       /* Channel is not picked yet. */
01334       return -1;
01335    }
01336 
01337    prioffset = PRI_CHANNEL(channel);
01338    if (!prioffset || (channel & PRI_HELD_CALL)) {
01339       if (!call) {
01340          /* Cannot find a call waiting call or held call without a call. */
01341          return -1;
01342       }
01343       principle = -1;
01344       for (x = 0; x < pri->numchans; ++x) {
01345          if (pri->pvts[x]
01346             && pri->pvts[x]->call == call) {
01347             principle = x;
01348             break;
01349          }
01350       }
01351       return principle;
01352    }
01353 
01354    span = PRI_SPAN(channel);
01355    if (!(channel & PRI_EXPLICIT)) {
01356       int index;
01357 
01358       index = pri_active_dchan_index(pri);
01359       if (index == -1) {
01360          return -1;
01361       }
01362       span = pri->dchan_logical_span[index];
01363    }
01364 
01365    principle = -1;
01366    for (x = 0; x < pri->numchans; x++) {
01367       if (pri->pvts[x]
01368          && pri->pvts[x]->prioffset == prioffset
01369          && pri->pvts[x]->logicalspan == span
01370          && !pri->pvts[x]->no_b_channel) {
01371          principle = x;
01372          break;
01373       }
01374    }
01375 
01376    return principle;
01377 }
01378 
01379 /*!
01380  * \internal
01381  * \brief Fixup the private structure associated with the libpri call.
01382  *
01383  * \param pri PRI span control structure.
01384  * \param principle Array-index into private array to move call to if not already there.
01385  * \param call LibPRI opaque call pointer to find if need to move call.
01386  *
01387  * \note Assumes the pri->lock is already obtained.
01388  *
01389  * \retval principle on success.
01390  * \retval -1 on error.
01391  */
01392 static int pri_fixup_principle(struct sig_pri_span *pri, int principle, q931_call *call)
01393 {
01394    int x;
01395 
01396    if (principle < 0 || pri->numchans <= principle) {
01397       /* Out of rannge */
01398       return -1;
01399    }
01400    if (!call) {
01401       /* No call */
01402       return principle;
01403    }
01404    if (pri->pvts[principle] && pri->pvts[principle]->call == call) {
01405       /* Call is already on the specified principle. */
01406       return principle;
01407    }
01408 
01409    /* Find the old principle location. */
01410    for (x = 0; x < pri->numchans; x++) {
01411       struct sig_pri_chan *new_chan;
01412       struct sig_pri_chan *old_chan;
01413 
01414       if (!pri->pvts[x] || pri->pvts[x]->call != call) {
01415          continue;
01416       }
01417 
01418       /* Found our call */
01419       new_chan = pri->pvts[principle];
01420       old_chan = pri->pvts[x];
01421 
01422       /* Get locks to safely move to the new private structure. */
01423       sig_pri_lock_private(old_chan);
01424       sig_pri_lock_owner(pri, x);
01425       sig_pri_lock_private(new_chan);
01426 
01427       ast_verb(3, "Moving call (%s) from channel %d to %d.\n",
01428          old_chan->owner ? old_chan->owner->name : "",
01429          old_chan->channel, new_chan->channel);
01430       if (!sig_pri_is_chan_available(new_chan)) {
01431          ast_log(LOG_WARNING,
01432             "Can't move call (%s) from channel %d to %d.  It is already in use.\n",
01433             old_chan->owner ? old_chan->owner->name : "",
01434             old_chan->channel, new_chan->channel);
01435          sig_pri_unlock_private(new_chan);
01436          if (old_chan->owner) {
01437             ast_channel_unlock(old_chan->owner);
01438          }
01439          sig_pri_unlock_private(old_chan);
01440          return -1;
01441       }
01442 
01443       sig_pri_fixup_chans(old_chan, new_chan);
01444 
01445       /* Fix it all up now */
01446       new_chan->owner = old_chan->owner;
01447       old_chan->owner = NULL;
01448 
01449       new_chan->call = old_chan->call;
01450       old_chan->call = NULL;
01451 
01452       /* Transfer flags from the old channel. */
01453 #if defined(HAVE_PRI_AOC_EVENTS)
01454       new_chan->aoc_s_request_invoke_id_valid = old_chan->aoc_s_request_invoke_id_valid;
01455       new_chan->waiting_for_aoce = old_chan->waiting_for_aoce;
01456       new_chan->holding_aoce = old_chan->holding_aoce;
01457 #endif   /* defined(HAVE_PRI_AOC_EVENTS) */
01458       new_chan->alreadyhungup = old_chan->alreadyhungup;
01459       new_chan->isidlecall = old_chan->isidlecall;
01460       new_chan->progress = old_chan->progress;
01461       new_chan->allocated = old_chan->allocated;
01462       new_chan->outgoing = old_chan->outgoing;
01463       new_chan->digital = old_chan->digital;
01464 #if defined(HAVE_PRI_CALL_WAITING)
01465       new_chan->is_call_waiting = old_chan->is_call_waiting;
01466 #endif   /* defined(HAVE_PRI_CALL_WAITING) */
01467 
01468 #if defined(HAVE_PRI_AOC_EVENTS)
01469       old_chan->aoc_s_request_invoke_id_valid = 0;
01470       old_chan->waiting_for_aoce = 0;
01471       old_chan->holding_aoce = 0;
01472 #endif   /* defined(HAVE_PRI_AOC_EVENTS) */
01473       old_chan->alreadyhungup = 0;
01474       old_chan->isidlecall = 0;
01475       old_chan->progress = 0;
01476       old_chan->allocated = 0;
01477       old_chan->outgoing = 0;
01478       old_chan->digital = 0;
01479 #if defined(HAVE_PRI_CALL_WAITING)
01480       old_chan->is_call_waiting = 0;
01481 #endif   /* defined(HAVE_PRI_CALL_WAITING) */
01482 
01483       /* More stuff to transfer to the new channel. */
01484       new_chan->call_level = old_chan->call_level;
01485       old_chan->call_level = SIG_PRI_CALL_LEVEL_IDLE;
01486 #if defined(HAVE_PRI_REVERSE_CHARGE)
01487       new_chan->reverse_charging_indication = old_chan->reverse_charging_indication;
01488 #endif   /* defined(HAVE_PRI_REVERSE_CHARGE) */
01489 #if defined(HAVE_PRI_SETUP_KEYPAD)
01490       strcpy(new_chan->keypad_digits, old_chan->keypad_digits);
01491 #endif   /* defined(HAVE_PRI_SETUP_KEYPAD) */
01492       strcpy(new_chan->deferred_digits, old_chan->deferred_digits);
01493 #if defined(HAVE_PRI_AOC_EVENTS)
01494       new_chan->aoc_s_request_invoke_id = old_chan->aoc_s_request_invoke_id;
01495       new_chan->aoc_e = old_chan->aoc_e;
01496 #endif   /* defined(HAVE_PRI_AOC_EVENTS) */
01497       strcpy(new_chan->user_tag, old_chan->user_tag);
01498 
01499       if (new_chan->no_b_channel) {
01500          /* Copy the real channel configuration to the no B channel interface. */
01501          new_chan->hidecallerid = old_chan->hidecallerid;
01502          new_chan->hidecalleridname = old_chan->hidecalleridname;
01503          new_chan->immediate = old_chan->immediate;
01504          new_chan->priexclusive = old_chan->priexclusive;
01505          new_chan->priindication_oob = old_chan->priindication_oob;
01506          new_chan->use_callerid = old_chan->use_callerid;
01507          new_chan->use_callingpres = old_chan->use_callingpres;
01508          new_chan->stripmsd = old_chan->stripmsd;
01509          strcpy(new_chan->context, old_chan->context);
01510          strcpy(new_chan->mohinterpret, old_chan->mohinterpret);
01511 
01512          /* Become a member of the old channel span/trunk-group. */
01513          new_chan->logicalspan = old_chan->logicalspan;
01514          new_chan->mastertrunkgroup = old_chan->mastertrunkgroup;
01515       } else if (old_chan->no_b_channel) {
01516          /*
01517           * We are transitioning from a held/call-waiting channel to a
01518           * real channel so we need to make sure that the media path is
01519           * open.  (Needed especially if the channel is natively
01520           * bridged.)
01521           */
01522          sig_pri_open_media(new_chan);
01523       }
01524 
01525       if (new_chan->owner) {
01526          sig_pri_ami_channel_event(new_chan);
01527       }
01528 
01529       sig_pri_unlock_private(old_chan);
01530       if (new_chan->owner) {
01531          ast_channel_unlock(new_chan->owner);
01532       }
01533       sig_pri_unlock_private(new_chan);
01534 
01535       return principle;
01536    }
01537    ast_verb(3, "Call specified, but not found.\n");
01538    return -1;
01539 }
01540 
01541 /*!
01542  * \internal
01543  * \brief Find and fixup the private structure associated with the libpri call.
01544  *
01545  * \param pri PRI span control structure.
01546  * \param channel LibPRI encoded channel ID.
01547  * \param call LibPRI opaque call pointer.
01548  *
01549  * \details
01550  * This is a combination of pri_find_principle() and pri_fixup_principle()
01551  * to reduce code redundancy and to make handling several PRI_EVENT_xxx's
01552  * consistent for the current architecture.
01553  *
01554  * \note Assumes the pri->lock is already obtained.
01555  *
01556  * \retval array-index into private pointer array on success.
01557  * \retval -1 on error.
01558  */
01559 static int pri_find_fixup_principle(struct sig_pri_span *pri, int channel, q931_call *call)
01560 {
01561    int chanpos;
01562 
01563    chanpos = pri_find_principle(pri, channel, call);
01564    if (chanpos < 0) {
01565       ast_log(LOG_WARNING, "Span %d: PRI requested channel %d/%d is unconfigured.\n",
01566          pri->span, PRI_SPAN(channel), PRI_CHANNEL(channel));
01567       sig_pri_kill_call(pri, call, PRI_CAUSE_IDENTIFIED_CHANNEL_NOTEXIST);
01568       return -1;
01569    }
01570    chanpos = pri_fixup_principle(pri, chanpos, call);
01571    if (chanpos < 0) {
01572       ast_log(LOG_WARNING, "Span %d: PRI requested channel %d/%d is not available.\n",
01573          pri->span, PRI_SPAN(channel), PRI_CHANNEL(channel));
01574       /*
01575        * Using Q.931 section 5.2.3.1 b) as the reason for picking
01576        * PRI_CAUSE_CHANNEL_UNACCEPTABLE.  Receiving a
01577        * PRI_CAUSE_REQUESTED_CHAN_UNAVAIL would cause us to restart
01578        * that channel (which is not specified by Q.931) and kill some
01579        * other call which would be bad.
01580        */
01581       sig_pri_kill_call(pri, call, PRI_CAUSE_CHANNEL_UNACCEPTABLE);
01582       return -1;
01583    }
01584    return chanpos;
01585 }
01586 
01587 static char * redirectingreason2str(int redirectingreason)
01588 {
01589    switch (redirectingreason) {
01590    case 0:
01591       return "UNKNOWN";
01592    case 1:
01593       return "BUSY";
01594    case 2:
01595       return "NO_REPLY";
01596    case 0xF:
01597       return "UNCONDITIONAL";
01598    default:
01599       return "NOREDIRECT";
01600    }
01601 }
01602 
01603 static char *dialplan2str(int dialplan)
01604 {
01605    if (dialplan == -1) {
01606       return("Dynamically set dialplan in ISDN");
01607    }
01608    return (pri_plan2str(dialplan));
01609 }
01610 
01611 /*!
01612  * \internal
01613  * \brief Apply numbering plan prefix to the given number.
01614  *
01615  * \param buf Buffer to put number into.
01616  * \param size Size of given buffer.
01617  * \param pri PRI span control structure.
01618  * \param number Number to apply numbering plan.
01619  * \param plan Numbering plan to apply.
01620  *
01621  * \return Nothing
01622  */
01623 static void apply_plan_to_number(char *buf, size_t size, const struct sig_pri_span *pri, const char *number, int plan)
01624 {
01625    switch (plan) {
01626    case PRI_INTERNATIONAL_ISDN:     /* Q.931 dialplan == 0x11 international dialplan => prepend international prefix digits */
01627       snprintf(buf, size, "%s%s", pri->internationalprefix, number);
01628       break;
01629    case PRI_NATIONAL_ISDN:       /* Q.931 dialplan == 0x21 national dialplan => prepend national prefix digits */
01630       snprintf(buf, size, "%s%s", pri->nationalprefix, number);
01631       break;
01632    case PRI_LOCAL_ISDN:       /* Q.931 dialplan == 0x41 local dialplan => prepend local prefix digits */
01633       snprintf(buf, size, "%s%s", pri->localprefix, number);
01634       break;
01635    case PRI_PRIVATE:       /* Q.931 dialplan == 0x49 private dialplan => prepend private prefix digits */
01636       snprintf(buf, size, "%s%s", pri->privateprefix, number);
01637       break;
01638    case PRI_UNKNOWN:       /* Q.931 dialplan == 0x00 unknown dialplan => prepend unknown prefix digits */
01639       snprintf(buf, size, "%s%s", pri->unknownprefix, number);
01640       break;
01641    default:          /* other Q.931 dialplan => don't twiddle with callingnum */
01642       snprintf(buf, size, "%s", number);
01643       break;
01644    }
01645 }
01646 
01647 /*!
01648  * \internal
01649  * \brief Apply numbering plan prefix to the given number if the number exists.
01650  *
01651  * \param buf Buffer to put number into.
01652  * \param size Size of given buffer.
01653  * \param pri PRI span control structure.
01654  * \param number Number to apply numbering plan.
01655  * \param plan Numbering plan to apply.
01656  *
01657  * \return Nothing
01658  */
01659 static void apply_plan_to_existing_number(char *buf, size_t size, const struct sig_pri_span *pri, const char *number, int plan)
01660 {
01661    /* Make sure a number exists so the prefix isn't placed on an empty string. */
01662    if (ast_strlen_zero(number)) {
01663       if (size) {
01664          *buf = '\0';
01665       }
01666       return;
01667    }
01668    apply_plan_to_number(buf, size, pri, number, plan);
01669 }
01670 
01671 /*!
01672  * \internal
01673  * \brief Restart the next channel we think is idle on the span.
01674  *
01675  * \param pri PRI span control structure.
01676  *
01677  * \note Assumes the pri->lock is already obtained.
01678  *
01679  * \return Nothing
01680  */
01681 static void pri_check_restart(struct sig_pri_span *pri)
01682 {
01683 #if defined(HAVE_PRI_SERVICE_MESSAGES)
01684    unsigned why;
01685 #endif   /* defined(HAVE_PRI_SERVICE_MESSAGES) */
01686 
01687    for (++pri->resetpos; pri->resetpos < pri->numchans; ++pri->resetpos) {
01688       if (!pri->pvts[pri->resetpos]
01689          || pri->pvts[pri->resetpos]->no_b_channel
01690          || sig_pri_is_chan_in_use(pri->pvts[pri->resetpos])) {
01691          continue;
01692       }
01693 #if defined(HAVE_PRI_SERVICE_MESSAGES)
01694       why = pri->pvts[pri->resetpos]->service_status;
01695       if (why) {
01696          ast_log(LOG_NOTICE,
01697             "Span %d: channel %d out-of-service (reason: %s), not sending RESTART\n",
01698             pri->span, pri->pvts[pri->resetpos]->channel,
01699             (why & SRVST_FAREND) ? (why & SRVST_NEAREND) ? "both ends" : "far end" : "near end");
01700          continue;
01701       }
01702 #endif   /* defined(HAVE_PRI_SERVICE_MESSAGES) */
01703       break;
01704    }
01705    if (pri->resetpos < pri->numchans) {
01706       /* Mark the channel as resetting and restart it */
01707       pri->pvts[pri->resetpos]->resetting = 1;
01708       pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[pri->resetpos]));
01709    } else {
01710       pri->resetting = 0;
01711       time(&pri->lastreset);
01712       sig_pri_span_devstate_changed(pri);
01713    }
01714 }
01715 
01716 #if defined(HAVE_PRI_CALL_WAITING)
01717 /*!
01718  * \internal
01719  * \brief Init the private channel configuration using the span controller.
01720  * \since 1.8
01721  *
01722  * \param pvt Channel to init the configuration.
01723  * \param pri PRI span control structure.
01724  *
01725  * \note Assumes the pri->lock is already obtained.
01726  *
01727  * \return Nothing
01728  */
01729 static void sig_pri_init_config(struct sig_pri_chan *pvt, struct sig_pri_span *pri)
01730 {
01731    pvt->stripmsd = pri->ch_cfg.stripmsd;
01732    pvt->hidecallerid = pri->ch_cfg.hidecallerid;
01733    pvt->hidecalleridname = pri->ch_cfg.hidecalleridname;
01734    pvt->immediate = pri->ch_cfg.immediate;
01735    pvt->priexclusive = pri->ch_cfg.priexclusive;
01736    pvt->priindication_oob = pri->ch_cfg.priindication_oob;
01737    pvt->use_callerid = pri->ch_cfg.use_callerid;
01738    pvt->use_callingpres = pri->ch_cfg.use_callingpres;
01739    ast_copy_string(pvt->context, pri->ch_cfg.context, sizeof(pvt->context));
01740    ast_copy_string(pvt->mohinterpret, pri->ch_cfg.mohinterpret, sizeof(pvt->mohinterpret));
01741 
01742    if (pri->calls->init_config) {
01743       pri->calls->init_config(pvt->chan_pvt, pri);
01744    }
01745 }
01746 #endif   /* defined(HAVE_PRI_CALL_WAITING) */
01747 
01748 /*!
01749  * \internal
01750  * \brief Find an empty B-channel interface to use.
01751  *
01752  * \param pri PRI span control structure.
01753  * \param backwards TRUE if the search starts from higher channels.
01754  *
01755  * \note Assumes the pri->lock is already obtained.
01756  *
01757  * \retval array-index into private pointer array on success.
01758  * \retval -1 on error.
01759  */
01760 static int pri_find_empty_chan(struct sig_pri_span *pri, int backwards)
01761 {
01762    int x;
01763    if (backwards)
01764       x = pri->numchans;
01765    else
01766       x = 0;
01767    for (;;) {
01768       if (backwards && (x < 0))
01769          break;
01770       if (!backwards && (x >= pri->numchans))
01771          break;
01772       if (pri->pvts[x]
01773          && !pri->pvts[x]->no_b_channel
01774          && sig_pri_is_chan_available(pri->pvts[x])) {
01775          ast_debug(1, "Found empty available channel %d/%d\n",
01776             pri->pvts[x]->logicalspan, pri->pvts[x]->prioffset);
01777          return x;
01778       }
01779       if (backwards)
01780          x--;
01781       else
01782          x++;
01783    }
01784    return -1;
01785 }
01786 
01787 #if defined(HAVE_PRI_CALL_HOLD)
01788 /*!
01789  * \internal
01790  * \brief Find or create an empty no-B-channel interface to use.
01791  * \since 1.8
01792  *
01793  * \param pri PRI span control structure.
01794  *
01795  * \note Assumes the pri->lock is already obtained.
01796  *
01797  * \retval array-index into private pointer array on success.
01798  * \retval -1 on error.
01799  */
01800 static int pri_find_empty_nobch(struct sig_pri_span *pri)
01801 {
01802    int idx;
01803 
01804    for (idx = 0; idx < pri->numchans; ++idx) {
01805       if (pri->pvts[idx]
01806          && pri->pvts[idx]->no_b_channel
01807          && sig_pri_is_chan_available(pri->pvts[idx])) {
01808          ast_debug(1, "Found empty available no B channel interface\n");
01809          return idx;
01810       }
01811    }
01812 
01813    /* Need to create a new interface. */
01814    if (pri->calls->new_nobch_intf) {
01815       idx = pri->calls->new_nobch_intf(pri);
01816    } else {
01817       idx = -1;
01818    }
01819    return idx;
01820 }
01821 #endif   /* defined(HAVE_PRI_CALL_HOLD) */
01822 
01823 static void *do_idle_thread(void *v_pvt)
01824 {
01825    struct sig_pri_chan *pvt = v_pvt;
01826    struct ast_channel *chan = pvt->owner;
01827    struct ast_frame *f;
01828    char ex[80];
01829    /* Wait up to 30 seconds for an answer */
01830    int newms, ms = 30000;
01831 
01832    ast_verb(3, "Initiating idle call on channel %s\n", chan->name);
01833    snprintf(ex, sizeof(ex), "%d/%s", pvt->channel, pvt->pri->idledial);
01834    if (ast_call(chan, ex, 0)) {
01835       ast_log(LOG_WARNING, "Idle dial failed on '%s' to '%s'\n", chan->name, ex);
01836       ast_hangup(chan);
01837       return NULL;
01838    }
01839    while ((newms = ast_waitfor(chan, ms)) > 0) {
01840       f = ast_read(chan);
01841       if (!f) {
01842          /* Got hangup */
01843          break;
01844       }
01845       if (f->frametype == AST_FRAME_CONTROL) {
01846          switch (f->subclass.integer) {
01847          case AST_CONTROL_ANSWER:
01848             /* Launch the PBX */
01849             ast_copy_string(chan->exten, pvt->pri->idleext, sizeof(chan->exten));
01850             ast_copy_string(chan->context, pvt->pri->idlecontext, sizeof(chan->context));
01851             chan->priority = 1;
01852             ast_verb(4, "Idle channel '%s' answered, sending to %s@%s\n", chan->name, chan->exten, chan->context);
01853             ast_pbx_run(chan);
01854             /* It's already hungup, return immediately */
01855             return NULL;
01856          case AST_CONTROL_BUSY:
01857             ast_verb(4, "Idle channel '%s' busy, waiting...\n", chan->name);
01858             break;
01859          case AST_CONTROL_CONGESTION:
01860             ast_verb(4, "Idle channel '%s' congested, waiting...\n", chan->name);
01861             break;
01862          };
01863       }
01864       ast_frfree(f);
01865       ms = newms;
01866    }
01867    /* Hangup the channel since nothing happend */
01868    ast_hangup(chan);
01869    return NULL;
01870 }
01871 
01872 static void *pri_ss_thread(void *data)
01873 {
01874    struct sig_pri_chan *p = data;
01875    struct ast_channel *chan = p->owner;
01876    char exten[AST_MAX_EXTENSION];
01877    int res;
01878    int len;
01879    int timeout;
01880 
01881    if (!chan) {
01882       /* We lost the owner before we could get started. */
01883       return NULL;
01884    }
01885 
01886    /*
01887     * In the bizarre case where the channel has become a zombie before we
01888     * even get started here, abort safely.
01889     */
01890    if (!chan->tech_pvt) {
01891       ast_log(LOG_WARNING, "Channel became a zombie before simple switch could be started (%s)\n", chan->name);
01892       ast_hangup(chan);
01893       return NULL;
01894    }
01895 
01896    ast_verb(3, "Starting simple switch on '%s'\n", chan->name);
01897 
01898    sig_pri_dsp_reset_and_flush_digits(p);
01899 
01900    /* Now loop looking for an extension */
01901    ast_copy_string(exten, p->exten, sizeof(exten));
01902    len = strlen(exten);
01903    res = 0;
01904    while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) {
01905       if (len && !ast_ignore_pattern(chan->context, exten))
01906          sig_pri_play_tone(p, -1);
01907       else
01908          sig_pri_play_tone(p, SIG_PRI_TONE_DIALTONE);
01909       if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num))
01910          timeout = pri_matchdigittimeout;
01911       else
01912          timeout = pri_gendigittimeout;
01913       res = ast_waitfordigit(chan, timeout);
01914       if (res < 0) {
01915          ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n");
01916          ast_hangup(chan);
01917          return NULL;
01918       } else if (res) {
01919          exten[len++] = res;
01920          exten[len] = '\0';
01921       } else
01922          break;
01923    }
01924    /* if no extension was received ('unspecified') on overlap call, use the 's' extension */
01925    if (ast_strlen_zero(exten)) {
01926       ast_verb(3, "Going to extension s|1 because of empty extension received on overlap call\n");
01927       exten[0] = 's';
01928       exten[1] = '\0';
01929    } else {
01930       ast_free(chan->dialed.number.str);
01931       chan->dialed.number.str = ast_strdup(exten);
01932 
01933       if (p->pri->append_msn_to_user_tag && p->pri->nodetype != PRI_NETWORK) {
01934          /*
01935           * Update the user tag for party id's from this device for this call
01936           * now that we have a complete MSN from the network.
01937           */
01938          snprintf(p->user_tag, sizeof(p->user_tag), "%s_%s", p->pri->initial_user_tag,
01939             exten);
01940          ast_free(chan->caller.id.tag);
01941          chan->caller.id.tag = ast_strdup(p->user_tag);
01942       }
01943    }
01944    sig_pri_play_tone(p, -1);
01945    if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num)) {
01946       /* Start the real PBX */
01947       ast_copy_string(chan->exten, exten, sizeof(chan->exten));
01948       sig_pri_dsp_reset_and_flush_digits(p);
01949 #if defined(ISSUE_16789)
01950       /*
01951        * Conditionaled out this code to effectively revert the Mantis
01952        * issue 16789 change.  It breaks overlap dialing through
01953        * Asterisk.  There is not enough information available at this
01954        * point to know if dialing is complete.  The
01955        * ast_exists_extension(), ast_matchmore_extension(), and
01956        * ast_canmatch_extension() calls are not adequate to detect a
01957        * dial through extension pattern of "_9!".
01958        *
01959        * Workaround is to use the dialplan Proceeding() application
01960        * early on non-dial through extensions.
01961        */
01962       if ((p->pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)
01963          && !ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) {
01964          sig_pri_lock_private(p);
01965          if (p->pri->pri) {
01966             pri_grab(p, p->pri);
01967             if (p->call_level < SIG_PRI_CALL_LEVEL_PROCEEDING) {
01968                p->call_level = SIG_PRI_CALL_LEVEL_PROCEEDING;
01969             }
01970             pri_proceeding(p->pri->pri, p->call, PVT_TO_CHANNEL(p), 0);
01971             pri_rel(p->pri);
01972          }
01973          sig_pri_unlock_private(p);
01974       }
01975 #endif   /* defined(ISSUE_16789) */
01976 
01977       sig_pri_set_echocanceller(p, 1);
01978       ast_setstate(chan, AST_STATE_RING);
01979       res = ast_pbx_run(chan);
01980       if (res) {
01981          ast_log(LOG_WARNING, "PBX exited non-zero!\n");
01982       }
01983    } else {
01984       ast_log(LOG_DEBUG, "No such possible extension '%s' in context '%s'\n", exten, chan->context);
01985       chan->hangupcause = AST_CAUSE_UNALLOCATED;
01986       ast_hangup(chan);
01987       p->exten[0] = '\0';
01988       /* Since we send release complete here, we won't get one */
01989       p->call = NULL;
01990       ast_mutex_lock(&p->pri->lock);
01991       sig_pri_span_devstate_changed(p->pri);
01992       ast_mutex_unlock(&p->pri->lock);
01993    }
01994    return NULL;
01995 }
01996 
01997 void pri_event_alarm(struct sig_pri_span *pri, int index, int before_start_pri)
01998 {
01999    pri->dchanavail[index] &= ~(DCHAN_NOTINALARM | DCHAN_UP);
02000    if (!before_start_pri) {
02001       pri_find_dchan(pri);
02002    }
02003 }
02004 
02005 void pri_event_noalarm(struct sig_pri_span *pri, int index, int before_start_pri)
02006 {
02007    pri->dchanavail[index] |= DCHAN_NOTINALARM;
02008    if (!before_start_pri)
02009       pri_restart(pri->dchans[index]);
02010 }
02011 
02012 /*!
02013  * \internal
02014  * \brief Convert libpri party name into asterisk party name.
02015  * \since 1.8
02016  *
02017  * \param ast_name Asterisk party name structure to fill.  Must already be set initialized.
02018  * \param pri_name libpri party name structure containing source information.
02019  *
02020  * \note The filled in ast_name structure needs to be destroyed by
02021  * ast_party_name_free() when it is no longer needed.
02022  *
02023  * \return Nothing
02024  */
02025 static void sig_pri_party_name_convert(struct ast_party_name *ast_name, const struct pri_party_name *pri_name)
02026 {
02027    ast_name->str = ast_strdup(pri_name->str);
02028    ast_name->char_set = pri_to_ast_char_set(pri_name->char_set);
02029    ast_name->presentation = pri_to_ast_presentation(pri_name->presentation);
02030    ast_name->valid = 1;
02031 }
02032 
02033 /*!
02034  * \internal
02035  * \brief Convert libpri party number into asterisk party number.
02036  * \since 1.8
02037  *
02038  * \param ast_number Asterisk party number structure to fill.  Must already be set initialized.
02039  * \param pri_number libpri party number structure containing source information.
02040  * \param pri PRI span control structure.
02041  *
02042  * \note The filled in ast_number structure needs to be destroyed by
02043  * ast_party_number_free() when it is no longer needed.
02044  *
02045  * \return Nothing
02046  */
02047 static void sig_pri_party_number_convert(struct ast_party_number *ast_number, const struct pri_party_number *pri_number, struct sig_pri_span *pri)
02048 {
02049    char number[AST_MAX_EXTENSION];
02050 
02051    apply_plan_to_existing_number(number, sizeof(number), pri, pri_number->str,
02052       pri_number->plan);
02053    ast_number->str = ast_strdup(number);
02054    ast_number->plan = pri_number->plan;
02055    ast_number->presentation = pri_to_ast_presentation(pri_number->presentation);
02056    ast_number->valid = 1;
02057 }
02058 
02059 /*!
02060  * \internal
02061  * \brief Convert libpri party id into asterisk party id.
02062  * \since 1.8
02063  *
02064  * \param ast_id Asterisk party id structure to fill.  Must already be set initialized.
02065  * \param pri_id libpri party id structure containing source information.
02066  * \param pri PRI span control structure.
02067  *
02068  * \note The filled in ast_id structure needs to be destroyed by
02069  * ast_party_id_free() when it is no longer needed.
02070  *
02071  * \return Nothing
02072  */
02073 static void sig_pri_party_id_convert(struct ast_party_id *ast_id, const struct pri_party_id *pri_id, struct sig_pri_span *pri)
02074 {
02075    if (pri_id->name.valid) {
02076       sig_pri_party_name_convert(&ast_id->name, &pri_id->name);
02077    }
02078    if (pri_id->number.valid) {
02079       sig_pri_party_number_convert(&ast_id->number, &pri_id->number, pri);
02080    }
02081 #if defined(HAVE_PRI_SUBADDR)
02082    if (pri_id->subaddress.valid) {
02083       sig_pri_set_subaddress(&ast_id->subaddress, &pri_id->subaddress);
02084    }
02085 #endif   /* defined(HAVE_PRI_SUBADDR) */
02086 }
02087 
02088 /*!
02089  * \internal
02090  * \brief Convert libpri redirecting information into asterisk redirecting information.
02091  * \since 1.8
02092  *
02093  * \param ast_redirecting Asterisk redirecting structure to fill.
02094  * \param pri_redirecting libpri redirecting structure containing source information.
02095  * \param ast_guide Asterisk redirecting structure to use as an initialization guide.
02096  * \param pri PRI span control structure.
02097  *
02098  * \note The filled in ast_redirecting structure needs to be destroyed by
02099  * ast_party_redirecting_free() when it is no longer needed.
02100  *
02101  * \return Nothing
02102  */
02103 static void sig_pri_redirecting_convert(struct ast_party_redirecting *ast_redirecting,
02104    const struct pri_party_redirecting *pri_redirecting,
02105    const struct ast_party_redirecting *ast_guide,
02106    struct sig_pri_span *pri)
02107 {
02108    ast_party_redirecting_set_init(ast_redirecting, ast_guide);
02109 
02110    sig_pri_party_id_convert(&ast_redirecting->from, &pri_redirecting->from, pri);
02111    sig_pri_party_id_convert(&ast_redirecting->to, &pri_redirecting->to, pri);
02112    ast_redirecting->count = pri_redirecting->count;
02113    ast_redirecting->reason = pri_to_ast_reason(pri_redirecting->reason);
02114 }
02115 
02116 /*!
02117  * \internal
02118  * \brief Determine if the given extension matches one of the MSNs in the pattern list.
02119  * \since 1.8
02120  *
02121  * \param msn_patterns Comma separated list of MSN patterns to match.
02122  * \param exten Extension to match in the MSN list.
02123  *
02124  * \retval 1 if matches.
02125  * \retval 0 if no match.
02126  */
02127 static int sig_pri_msn_match(const char *msn_patterns, const char *exten)
02128 {
02129    char *pattern;
02130    char *msn_list;
02131    char *list_tail;
02132 
02133    msn_list = ast_strdupa(msn_patterns);
02134 
02135    list_tail = NULL;
02136    pattern = strtok_r(msn_list, ",", &list_tail);
02137    while (pattern) {
02138       pattern = ast_strip(pattern);
02139       if (!ast_strlen_zero(pattern) && ast_extension_match(pattern, exten)) {
02140          /* Extension matched the pattern. */
02141          return 1;
02142       }
02143       pattern = strtok_r(NULL, ",", &list_tail);
02144    }
02145    /* Did not match any pattern in the list. */
02146    return 0;
02147 }
02148 
02149 #if defined(HAVE_PRI_MCID)
02150 /*!
02151  * \internal
02152  * \brief Append the given party id to the event string.
02153  * \since 1.8
02154  *
02155  * \param msg Event message string being built.
02156  * \param prefix Prefix to add to the party id lines.
02157  * \param party Party information to encode.
02158  *
02159  * \return Nothing
02160  */
02161 static void sig_pri_event_party_id(struct ast_str **msg, const char *prefix, struct ast_party_id *party)
02162 {
02163    int pres;
02164 
02165    /* Combined party presentation */
02166    pres = ast_party_id_presentation(party);
02167    ast_str_append(msg, 0, "%sPres: %d (%s)\r\n", prefix, pres,
02168       ast_describe_caller_presentation(pres));
02169 
02170    /* Party number */
02171    ast_str_append(msg, 0, "%sNumValid: %d\r\n", prefix,
02172       (unsigned) party->number.valid);
02173    ast_str_append(msg, 0, "%sNum: %s\r\n", prefix,
02174       S_COR(party->number.valid, party->number.str, ""));
02175    ast_str_append(msg, 0, "%ston: %d\r\n", prefix, party->number.plan);
02176    if (party->number.valid) {
02177       ast_str_append(msg, 0, "%sNumPlan: %d\r\n", prefix, party->number.plan);
02178       ast_str_append(msg, 0, "%sNumPres: %d (%s)\r\n", prefix,
02179          party->number.presentation,
02180          ast_describe_caller_presentation(party->number.presentation));
02181    }
02182 
02183    /* Party name */
02184    ast_str_append(msg, 0, "%sNameValid: %d\r\n", prefix,
02185       (unsigned) party->name.valid);
02186    ast_str_append(msg, 0, "%sName: %s\r\n", prefix,
02187       S_COR(party->name.valid, party->name.str, ""));
02188    if (party->name.valid) {
02189       ast_str_append(msg, 0, "%sNameCharSet: %s\r\n", prefix,
02190          ast_party_name_charset_describe(party->name.char_set));
02191       ast_str_append(msg, 0, "%sNamePres: %d (%s)\r\n", prefix,
02192          party->name.presentation,
02193          ast_describe_caller_presentation(party->name.presentation));
02194    }
02195 
02196 #if defined(HAVE_PRI_SUBADDR)
02197    /* Party subaddress */
02198    if (party->subaddress.valid) {
02199       static const char subaddress[] = "Subaddr";
02200 
02201       ast_str_append(msg, 0, "%s%s: %s\r\n", prefix, subaddress,
02202          S_OR(party->subaddress.str, ""));
02203       ast_str_append(msg, 0, "%s%sType: %d\r\n", prefix, subaddress,
02204          party->subaddress.type);
02205       ast_str_append(msg, 0, "%s%sOdd: %d\r\n", prefix, subaddress,
02206          party->subaddress.odd_even_indicator);
02207    }
02208 #endif   /* defined(HAVE_PRI_SUBADDR) */
02209 }
02210 #endif   /* defined(HAVE_PRI_MCID) */
02211 
02212 #if defined(HAVE_PRI_MCID)
02213 /*!
02214  * \internal
02215  * \brief Handle the MCID event.
02216  * \since 1.8
02217  *
02218  * \param pri PRI span control structure.
02219  * \param mcid MCID event parameters.
02220  * \param owner Asterisk channel associated with the call.
02221  * NULL if Asterisk no longer has the ast_channel struct.
02222  *
02223  * \note Assumes the pri->lock is already obtained.
02224  * \note Assumes the owner channel lock is already obtained if still present.
02225  *
02226  * \return Nothing
02227  */
02228 static void sig_pri_mcid_event(struct sig_pri_span *pri, const struct pri_subcmd_mcid_req *mcid, struct ast_channel *owner)
02229 {
02230    struct ast_channel *chans[1];
02231    struct ast_str *msg;
02232    struct ast_party_id party;
02233 
02234    msg = ast_str_create(4096);
02235    if (!msg) {
02236       return;
02237    }
02238 
02239    if (owner) {
02240       /* The owner channel is present. */
02241       ast_str_append(&msg, 0, "Channel: %s\r\n", owner->name);
02242       ast_str_append(&msg, 0, "UniqueID: %s\r\n", owner->uniqueid);
02243 
02244       sig_pri_event_party_id(&msg, "CallerID", &owner->connected.id);
02245    } else {
02246       /*
02247        * Since we no longer have an owner channel,
02248        * we have to use the caller information supplied by libpri.
02249        */
02250       ast_party_id_init(&party);
02251       sig_pri_party_id_convert(&party, &mcid->originator, pri);
02252       sig_pri_event_party_id(&msg, "CallerID", &party);
02253       ast_party_id_free(&party);
02254    }
02255 
02256    /* Always use libpri's called party information. */
02257    ast_party_id_init(&party);
02258    sig_pri_party_id_convert(&party, &mcid->answerer, pri);
02259    sig_pri_event_party_id(&msg, "ConnectedID", &party);
02260    ast_party_id_free(&party);
02261 
02262    chans[0] = owner;
02263    ast_manager_event_multichan(EVENT_FLAG_CALL, "MCID", owner ? 1 : 0, chans, "%s",
02264       ast_str_buffer(msg));
02265    ast_free(msg);
02266 }
02267 #endif   /* defined(HAVE_PRI_MCID) */
02268 
02269 #if defined(HAVE_PRI_TRANSFER)
02270 struct xfer_rsp_data {
02271    struct sig_pri_span *pri;
02272    /*! Call to send transfer success/fail response over. */
02273    q931_call *call;
02274    /*! Invocation ID to use when sending a reply to the transfer request. */
02275    int invoke_id;
02276 };
02277 #endif   /* defined(HAVE_PRI_TRANSFER) */
02278 
02279 #if defined(HAVE_PRI_TRANSFER)
02280 /*!
02281  * \internal
02282  * \brief Send the transfer success/fail response message.
02283  * \since 1.8
02284  *
02285  * \param data Callback user data pointer
02286  * \param is_successful TRUE if the transfer was successful.
02287  *
02288  * \return Nothing
02289  */
02290 static void sig_pri_transfer_rsp(void *data, int is_successful)
02291 {
02292    struct xfer_rsp_data *rsp = data;
02293 
02294    pri_transfer_rsp(rsp->pri->pri, rsp->call, rsp->invoke_id, is_successful);
02295 }
02296 #endif   /* defined(HAVE_PRI_TRANSFER) */
02297 
02298 #if defined(HAVE_PRI_CALL_HOLD) || defined(HAVE_PRI_TRANSFER)
02299 /*!
02300  * \brief Protocol callback to indicate if transfer will happen.
02301  * \since 1.8
02302  *
02303  * \param data Callback user data pointer
02304  * \param is_successful TRUE if the transfer will happen.
02305  *
02306  * \return Nothing
02307  */
02308 typedef void (*xfer_rsp_callback)(void *data, int is_successful);
02309 #endif   /* defined(HAVE_PRI_CALL_HOLD) || defined(HAVE_PRI_TRANSFER) */
02310 
02311 #if defined(HAVE_PRI_CALL_HOLD) || defined(HAVE_PRI_TRANSFER)
02312 /*!
02313  * \internal
02314  * \brief Attempt to transfer the two calls to each other.
02315  * \since 1.8
02316  *
02317  * \param pri PRI span control structure.
02318  * \param call_1_pri First call involved in the transfer. (transferee; usually on hold)
02319  * \param call_1_held TRUE if call_1_pri is on hold.
02320  * \param call_2_pri Second call involved in the transfer. (target; usually active/ringing)
02321  * \param call_2_held TRUE if call_2_pri is on hold.
02322  * \param rsp_callback Protocol callback to indicate if transfer will happen. NULL if not used.
02323  * \param data Callback user data pointer
02324  *
02325  * \note Assumes the pri->lock is already obtained.
02326  *
02327  * \retval 0 on success.
02328  * \retval -1 on error.
02329  */
02330 static int sig_pri_attempt_transfer(struct sig_pri_span *pri, q931_call *call_1_pri, int call_1_held, q931_call *call_2_pri, int call_2_held, xfer_rsp_callback rsp_callback, void *data)
02331 {
02332    struct attempt_xfer_call {
02333       q931_call *pri;
02334       struct ast_channel *ast;
02335       int held;
02336       int chanpos;
02337    };
02338    int retval;
02339    struct ast_channel *transferee;
02340    struct attempt_xfer_call *call_1;
02341    struct attempt_xfer_call *call_2;
02342    struct attempt_xfer_call *swap_call;
02343    struct attempt_xfer_call c1;
02344    struct attempt_xfer_call c2;
02345 
02346    c1.pri = call_1_pri;
02347    c1.held = call_1_held;
02348    call_1 = &c1;
02349 
02350    c2.pri = call_2_pri;
02351    c2.held = call_2_held;
02352    call_2 = &c2;
02353 
02354    call_1->chanpos = pri_find_principle_by_call(pri, call_1->pri);
02355    call_2->chanpos = pri_find_principle_by_call(pri, call_2->pri);
02356    if (call_1->chanpos < 0 || call_2->chanpos < 0) {
02357       /* Calls not found in span control. */
02358       if (rsp_callback) {
02359          /* Transfer failed. */
02360          rsp_callback(data, 0);
02361       }
02362       return -1;
02363    }
02364 
02365    /* Attempt to make transferee and target consistent. */
02366    if (!call_1->held && call_2->held) {
02367       /*
02368        * Swap call_1 and call_2 to make call_1 the transferee(held call)
02369        * and call_2 the target(active call).
02370        */
02371       swap_call = call_1;
02372       call_1 = call_2;
02373       call_2 = swap_call;
02374    }
02375 
02376    /* Deadlock avoidance is attempted. */
02377    sig_pri_lock_private(pri->pvts[call_1->chanpos]);
02378    sig_pri_lock_owner(pri, call_1->chanpos);
02379    sig_pri_lock_private(pri->pvts[call_2->chanpos]);
02380    sig_pri_lock_owner(pri, call_2->chanpos);
02381 
02382    call_1->ast = pri->pvts[call_1->chanpos]->owner;
02383    call_2->ast = pri->pvts[call_2->chanpos]->owner;
02384    if (!call_1->ast || !call_2->ast) {
02385       /* At least one owner is not present. */
02386       if (call_1->ast) {
02387          ast_channel_unlock(call_1->ast);
02388       }
02389       if (call_2->ast) {
02390          ast_channel_unlock(call_2->ast);
02391       }
02392       sig_pri_unlock_private(pri->pvts[call_1->chanpos]);
02393       sig_pri_unlock_private(pri->pvts[call_2->chanpos]);
02394       if (rsp_callback) {
02395          /* Transfer failed. */
02396          rsp_callback(data, 0);
02397       }
02398       return -1;
02399    }
02400 
02401    for (;;) {
02402       transferee = ast_bridged_channel(call_1->ast);
02403       if (transferee) {
02404          break;
02405       }
02406 
02407       /* Try masquerading the other way. */
02408       swap_call = call_1;
02409       call_1 = call_2;
02410       call_2 = swap_call;
02411 
02412       transferee = ast_bridged_channel(call_1->ast);
02413       if (transferee) {
02414          break;
02415       }
02416 
02417       /* Could not transfer.  Neither call is bridged. */
02418       ast_channel_unlock(call_1->ast);
02419       ast_channel_unlock(call_2->ast);
02420       sig_pri_unlock_private(pri->pvts[call_1->chanpos]);
02421       sig_pri_unlock_private(pri->pvts[call_2->chanpos]);
02422 
02423       if (rsp_callback) {
02424          /* Transfer failed. */
02425          rsp_callback(data, 0);
02426       }
02427       return -1;
02428    }
02429 
02430    ast_verb(3, "TRANSFERRING %s to %s\n", call_1->ast->name, call_2->ast->name);
02431 
02432    /*
02433     * Setup transfer masquerade.
02434     *
02435     * Note:  There is an extremely nasty deadlock avoidance issue
02436     * with ast_channel_transfer_masquerade().  Deadlock may be possible if
02437     * the channels involved are proxies (chan_agent channels) and
02438     * it is called with locks.  Unfortunately, there is no simple
02439     * or even merely difficult way to guarantee deadlock avoidance
02440     * and still be able to send an ECT success response without the
02441     * possibility of the bridged channel hanging up on us.
02442     */
02443    ast_mutex_unlock(&pri->lock);
02444    retval = ast_channel_transfer_masquerade(
02445       call_2->ast,
02446       &call_2->ast->connected,
02447       call_2->held,
02448       transferee,
02449       &call_1->ast->connected,
02450       call_1->held);
02451 
02452    /* Reacquire the pri->lock to hold off completion of the transfer masquerade. */
02453    ast_mutex_lock(&pri->lock);
02454 
02455    ast_channel_unlock(call_1->ast);
02456    ast_channel_unlock(call_2->ast);
02457    sig_pri_unlock_private(pri->pvts[call_1->chanpos]);
02458    sig_pri_unlock_private(pri->pvts[call_2->chanpos]);
02459 
02460    if (rsp_callback) {
02461       /*
02462        * Report transfer status.
02463        *
02464        * Must do the callback before the masquerade completes to ensure
02465        * that the protocol message goes out before the call leg is
02466        * disconnected.
02467        */
02468       rsp_callback(data, retval ? 0 : 1);
02469    }
02470    return retval;
02471 }
02472 #endif   /* defined(HAVE_PRI_CALL_HOLD) || defined(HAVE_PRI_TRANSFER) */
02473 
02474 #if defined(HAVE_PRI_CCSS)
02475 /*!
02476  * \internal
02477  * \brief Compare the CC agent private data by libpri cc_id.
02478  * \since 1.8
02479  *
02480  * \param obj pointer to the (user-defined part) of an object.
02481  * \param arg callback argument from ao2_callback()
02482  * \param flags flags from ao2_callback()
02483  *
02484  * \return values are a combination of enum _cb_results.
02485  */
02486 static int sig_pri_cc_agent_cmp_cc_id(void *obj, void *arg, int flags)
02487 {
02488    struct ast_cc_agent *agent_1 = obj;
02489    struct sig_pri_cc_agent_prv *agent_prv_1 = agent_1->private_data;
02490    struct sig_pri_cc_agent_prv *agent_prv_2 = arg;
02491 
02492    return (agent_prv_1 && agent_prv_1->pri == agent_prv_2->pri
02493       && agent_prv_1->cc_id == agent_prv_2->cc_id) ? CMP_MATCH | CMP_STOP : 0;
02494 }
02495 #endif   /* defined(HAVE_PRI_CCSS) */
02496 
02497 #if defined(HAVE_PRI_CCSS)
02498 /*!
02499  * \internal
02500  * \brief Find the CC agent by libpri cc_id.
02501  * \since 1.8
02502  *
02503  * \param pri PRI span control structure.
02504  * \param cc_id CC record ID to find.
02505  *
02506  * \note
02507  * Since agents are refcounted, and this function returns
02508  * a reference to the agent, it is imperative that you decrement
02509  * the refcount of the agent once you have finished using it.
02510  *
02511  * \retval agent on success.
02512  * \retval NULL not found.
02513  */
02514 static struct ast_cc_agent *sig_pri_find_cc_agent_by_cc_id(struct sig_pri_span *pri, long cc_id)
02515 {
02516    struct sig_pri_cc_agent_prv finder = {
02517       .pri = pri,
02518       .cc_id = cc_id,
02519    };
02520 
02521    return ast_cc_agent_callback(0, sig_pri_cc_agent_cmp_cc_id, &finder,
02522       sig_pri_cc_type_name);
02523 }
02524 #endif   /* defined(HAVE_PRI_CCSS) */
02525 
02526 #if defined(HAVE_PRI_CCSS)
02527 /*!
02528  * \internal
02529  * \brief Compare the CC monitor instance by libpri cc_id.
02530  * \since 1.8
02531  *
02532  * \param obj pointer to the (user-defined part) of an object.
02533  * \param arg callback argument from ao2_callback()
02534  * \param flags flags from ao2_callback()
02535  *
02536  * \return values are a combination of enum _cb_results.
02537  */
02538 static int sig_pri_cc_monitor_cmp_cc_id(void *obj, void *arg, int flags)
02539 {
02540    struct sig_pri_cc_monitor_instance *monitor_1 = obj;
02541    struct sig_pri_cc_monitor_instance *monitor_2 = arg;
02542 
02543    return (monitor_1->pri == monitor_2->pri
02544       && monitor_1->cc_id == monitor_2->cc_id) ? CMP_MATCH | CMP_STOP : 0;
02545 }
02546 #endif   /* defined(HAVE_PRI_CCSS) */
02547 
02548 #if defined(HAVE_PRI_CCSS)
02549 /*!
02550  * \internal
02551  * \brief Find the CC monitor instance by libpri cc_id.
02552  * \since 1.8
02553  *
02554  * \param pri PRI span control structure.
02555  * \param cc_id CC record ID to find.
02556  *
02557  * \note
02558  * Since monitor_instances are refcounted, and this function returns
02559  * a reference to the instance, it is imperative that you decrement
02560  * the refcount of the instance once you have finished using it.
02561  *
02562  * \retval monitor_instance on success.
02563  * \retval NULL not found.
02564  */
02565 static struct sig_pri_cc_monitor_instance *sig_pri_find_cc_monitor_by_cc_id(struct sig_pri_span *pri, long cc_id)
02566 {
02567    struct sig_pri_cc_monitor_instance finder = {
02568       .pri = pri,
02569       .cc_id = cc_id,
02570    };
02571 
02572    return ao2_callback(sig_pri_cc_monitors, 0, sig_pri_cc_monitor_cmp_cc_id, &finder);
02573 }
02574 #endif   /* defined(HAVE_PRI_CCSS) */
02575 
02576 #if defined(HAVE_PRI_CCSS)
02577 /*!
02578  * \internal
02579  * \brief Destroy the given monitor instance.
02580  * \since 1.8
02581  *
02582  * \param data Monitor instance to destroy.
02583  *
02584  * \return Nothing
02585  */
02586 static void sig_pri_cc_monitor_instance_destroy(void *data)
02587 {
02588    struct sig_pri_cc_monitor_instance *monitor_instance = data;
02589 
02590    if (monitor_instance->cc_id != -1) {
02591       ast_mutex_lock(&monitor_instance->pri->lock);
02592       pri_cc_cancel(monitor_instance->pri->pri, monitor_instance->cc_id);
02593       ast_mutex_unlock(&monitor_instance->pri->lock);
02594    }
02595    monitor_instance->pri->calls->module_unref();
02596 }
02597 #endif   /* defined(HAVE_PRI_CCSS) */
02598 
02599 #if defined(HAVE_PRI_CCSS)
02600 /*!
02601  * \internal
02602  * \brief Construct a new monitor instance.
02603  * \since 1.8
02604  *
02605  * \param core_id CC core ID.
02606  * \param pri PRI span control structure.
02607  * \param cc_id CC record ID.
02608  * \param device_name Name of device (Asterisk channel name less sequence number).
02609  *
02610  * \note
02611  * Since monitor_instances are refcounted, and this function returns
02612  * a reference to the instance, it is imperative that you decrement
02613  * the refcount of the instance once you have finished using it.
02614  *
02615  * \retval monitor_instance on success.
02616  * \retval NULL on error.
02617  */
02618 static struct sig_pri_cc_monitor_instance *sig_pri_cc_monitor_instance_init(int core_id, struct sig_pri_span *pri, long cc_id, const char *device_name)
02619 {
02620    struct sig_pri_cc_monitor_instance *monitor_instance;
02621 
02622    if (!pri->calls->module_ref || !pri->calls->module_unref) {
02623       return NULL;
02624    }
02625 
02626    monitor_instance = ao2_alloc(sizeof(*monitor_instance) + strlen(device_name),
02627       sig_pri_cc_monitor_instance_destroy);
02628    if (!monitor_instance) {
02629       return NULL;
02630    }
02631 
02632    monitor_instance->cc_id = cc_id;
02633    monitor_instance->pri = pri;
02634    monitor_instance->core_id = core_id;
02635    strcpy(monitor_instance->name, device_name);
02636 
02637    pri->calls->module_ref();
02638 
02639    ao2_link(sig_pri_cc_monitors, monitor_instance);
02640    return monitor_instance;
02641 }
02642 #endif   /* defined(HAVE_PRI_CCSS) */
02643 
02644 #if defined(HAVE_PRI_CCSS)
02645 /*!
02646  * \internal
02647  * \brief Announce to the CC core that protocol CC monitor is available for this call.
02648  * \since 1.8
02649  *
02650  * \param pri PRI span control structure.
02651  * \param chanpos Channel position in the span.
02652  * \param cc_id CC record ID.
02653  * \param service CCBS/CCNR indication.
02654  *
02655  * \note Assumes the pri->lock is already obtained.
02656  * \note Assumes the sig_pri_lock_private(pri->pvts[chanpos]) is already obtained.
02657  * \note Assumes the sig_pri_lock_owner(pri, chanpos) is already obtained.
02658  *
02659  * \retval 0 on success.
02660  * \retval -1 on error.
02661  */
02662 static int sig_pri_cc_available(struct sig_pri_span *pri, int chanpos, long cc_id, enum ast_cc_service_type service)
02663 {
02664    struct sig_pri_chan *pvt;
02665    struct ast_cc_config_params *cc_params;
02666    struct sig_pri_cc_monitor_instance *monitor;
02667    enum ast_cc_monitor_policies monitor_policy;
02668    int core_id;
02669    int res;
02670    char device_name[AST_CHANNEL_NAME];
02671    char dialstring[AST_CHANNEL_NAME];
02672 
02673    pvt = pri->pvts[chanpos];
02674 
02675    core_id = ast_cc_get_current_core_id(pvt->owner);
02676    if (core_id == -1) {
02677       return -1;
02678    }
02679 
02680    cc_params = ast_channel_get_cc_config_params(pvt->owner);
02681    if (!cc_params) {
02682       return -1;
02683    }
02684 
02685    res = -1;
02686    monitor_policy = ast_get_cc_monitor_policy(cc_params);
02687    switch (monitor_policy) {
02688    case AST_CC_MONITOR_NEVER:
02689       /* CCSS is not enabled. */
02690       break;
02691    case AST_CC_MONITOR_NATIVE:
02692    case AST_CC_MONITOR_ALWAYS:
02693       /*
02694        * If it is AST_CC_MONITOR_ALWAYS and native fails we will attempt the fallback
02695        * later in the call to sig_pri_cc_generic_check().
02696        */
02697       ast_channel_get_device_name(pvt->owner, device_name, sizeof(device_name));
02698       sig_pri_make_cc_dialstring(pvt, dialstring, sizeof(dialstring));
02699       monitor = sig_pri_cc_monitor_instance_init(core_id, pri, cc_id, device_name);
02700       if (!monitor) {
02701          break;
02702       }
02703       res = ast_queue_cc_frame(pvt->owner, sig_pri_cc_type_name, dialstring, service,
02704          monitor);
02705       if (res) {
02706          monitor->cc_id = -1;
02707          ao2_unlink(sig_pri_cc_monitors, monitor);
02708          ao2_ref(monitor, -1);
02709       }
02710       break;
02711    case AST_CC_MONITOR_GENERIC:
02712       ast_queue_cc_frame(pvt->owner, AST_CC_GENERIC_MONITOR_TYPE,
02713          sig_pri_get_orig_dialstring(pvt), service, NULL);
02714       /* Say it failed to force caller to cancel native CC. */
02715       break;
02716    }
02717    return res;
02718 }
02719 #endif   /* defined(HAVE_PRI_CCSS) */
02720 
02721 /*!
02722  * \internal
02723  * \brief Check if generic CC monitor is needed and request it.
02724  * \since 1.8
02725  *
02726  * \param pri PRI span control structure.
02727  * \param chanpos Channel position in the span.
02728  * \param service CCBS/CCNR indication.
02729  *
02730  * \note Assumes the pri->lock is already obtained.
02731  * \note Assumes the sig_pri_lock_private(pri->pvts[chanpos]) is already obtained.
02732  *
02733  * \return Nothing
02734  */
02735 static void sig_pri_cc_generic_check(struct sig_pri_span *pri, int chanpos, enum ast_cc_service_type service)
02736 {
02737    struct ast_channel *owner;
02738    struct ast_cc_config_params *cc_params;
02739 #if defined(HAVE_PRI_CCSS)
02740    struct ast_cc_monitor *monitor;
02741    char device_name[AST_CHANNEL_NAME];
02742 #endif   /* defined(HAVE_PRI_CCSS) */
02743    enum ast_cc_monitor_policies monitor_policy;
02744    int core_id;
02745 
02746    if (!pri->pvts[chanpos]->outgoing) {
02747       /* This is not an outgoing call so it cannot be CC monitor. */
02748       return;
02749    }
02750 
02751    sig_pri_lock_owner(pri, chanpos);
02752    owner = pri->pvts[chanpos]->owner;
02753    if (!owner) {
02754       return;
02755    }
02756    core_id = ast_cc_get_current_core_id(owner);
02757    if (core_id == -1) {
02758       /* No CC core setup */
02759       goto done;
02760    }
02761 
02762    cc_params = ast_channel_get_cc_config_params(owner);
02763    if (!cc_params) {
02764       /* Could not get CC config parameters. */
02765       goto done;
02766    }
02767 
02768 #if defined(HAVE_PRI_CCSS)
02769    ast_channel_get_device_name(owner, device_name, sizeof(device_name));
02770    monitor = ast_cc_get_monitor_by_recall_core_id(core_id, device_name);
02771    if (monitor) {
02772       /* CC monitor is already present so no need for generic CC. */
02773       ao2_ref(monitor, -1);
02774       goto done;
02775    }
02776 #endif   /* defined(HAVE_PRI_CCSS) */
02777 
02778    monitor_policy = ast_get_cc_monitor_policy(cc_params);
02779    switch (monitor_policy) {
02780    case AST_CC_MONITOR_NEVER:
02781       /* CCSS is not enabled. */
02782       break;
02783    case AST_CC_MONITOR_NATIVE:
02784       if (pri->sig == SIG_BRI_PTMP && pri->nodetype == PRI_NETWORK) {
02785          /* Request generic CC monitor. */
02786          ast_queue_cc_frame(owner, AST_CC_GENERIC_MONITOR_TYPE,
02787             sig_pri_get_orig_dialstring(pri->pvts[chanpos]), service, NULL);
02788       }
02789       break;
02790    case AST_CC_MONITOR_ALWAYS:
02791       if (pri->sig == SIG_BRI_PTMP && pri->nodetype != PRI_NETWORK) {
02792          /*
02793           * Cannot monitor PTMP TE side since this is not defined.
02794           * We are playing the roll of a phone in this case and
02795           * a phone cannot monitor a party over the network without
02796           * protocol help.
02797           */
02798          break;
02799       }
02800       /*
02801        * We are either falling back or this is a PTMP NT span.
02802        * Request generic CC monitor.
02803        */
02804       ast_queue_cc_frame(owner, AST_CC_GENERIC_MONITOR_TYPE,
02805          sig_pri_get_orig_dialstring(pri->pvts[chanpos]), service, NULL);
02806       break;
02807    case AST_CC_MONITOR_GENERIC:
02808       if (pri->sig == SIG_BRI_PTMP && pri->nodetype == PRI_NETWORK) {
02809          /* Request generic CC monitor. */
02810          ast_queue_cc_frame(owner, AST_CC_GENERIC_MONITOR_TYPE,
02811             sig_pri_get_orig_dialstring(pri->pvts[chanpos]), service, NULL);
02812       }
02813       break;
02814    }
02815 
02816 done:
02817    ast_channel_unlock(owner);
02818 }
02819 
02820 #if defined(HAVE_PRI_CCSS)
02821 /*!
02822  * \internal
02823  * \brief The CC link canceled the CC instance.
02824  * \since 1.8
02825  *
02826  * \param pri PRI span control structure.
02827  * \param cc_id CC record ID.
02828  * \param is_agent TRUE if the cc_id is for an agent.
02829  *
02830  * \return Nothing
02831  */
02832 static void sig_pri_cc_link_canceled(struct sig_pri_span *pri, long cc_id, int is_agent)
02833 {
02834    if (is_agent) {
02835       struct ast_cc_agent *agent;
02836 
02837       agent = sig_pri_find_cc_agent_by_cc_id(pri, cc_id);
02838       if (!agent) {
02839          return;
02840       }
02841       ast_cc_failed(agent->core_id, "%s agent got canceled by link",
02842          sig_pri_cc_type_name);
02843       ao2_ref(agent, -1);
02844    } else {
02845       struct sig_pri_cc_monitor_instance *monitor;
02846 
02847       monitor = sig_pri_find_cc_monitor_by_cc_id(pri, cc_id);
02848       if (!monitor) {
02849          return;
02850       }
02851       monitor->cc_id = -1;
02852       ast_cc_monitor_failed(monitor->core_id, monitor->name,
02853          "%s monitor got canceled by link", sig_pri_cc_type_name);
02854       ao2_ref(monitor, -1);
02855    }
02856 }
02857 #endif   /* defined(HAVE_PRI_CCSS) */
02858 
02859 #if defined(HAVE_PRI_AOC_EVENTS)
02860 /*!
02861  * \internal
02862  * \brief Convert ast_aoc_charged_item to PRI_AOC_CHARGED_ITEM .
02863  * \since 1.8
02864  *
02865  * \param value Value to convert to string.
02866  *
02867  * \return PRI_AOC_CHARGED_ITEM
02868  */
02869 static enum PRI_AOC_CHARGED_ITEM sig_pri_aoc_charged_item_to_pri(enum PRI_AOC_CHARGED_ITEM value)
02870 {
02871    switch (value) {
02872    case AST_AOC_CHARGED_ITEM_NA:
02873       return PRI_AOC_CHARGED_ITEM_NOT_AVAILABLE;
02874    case AST_AOC_CHARGED_ITEM_SPECIAL_ARRANGEMENT:
02875       return PRI_AOC_CHARGED_ITEM_SPECIAL_ARRANGEMENT;
02876    case AST_AOC_CHARGED_ITEM_BASIC_COMMUNICATION:
02877       return PRI_AOC_CHARGED_ITEM_BASIC_COMMUNICATION;
02878    case AST_AOC_CHARGED_ITEM_CALL_ATTEMPT:
02879       return PRI_AOC_CHARGED_ITEM_CALL_ATTEMPT;
02880    case AST_AOC_CHARGED_ITEM_CALL_SETUP:
02881       return PRI_AOC_CHARGED_ITEM_CALL_SETUP;
02882    case AST_AOC_CHARGED_ITEM_USER_USER_INFO:
02883       return PRI_AOC_CHARGED_ITEM_USER_USER_INFO;
02884    case AST_AOC_CHARGED_ITEM_SUPPLEMENTARY_SERVICE:
02885       return PRI_AOC_CHARGED_ITEM_SUPPLEMENTARY_SERVICE;
02886    }
02887    return PRI_AOC_CHARGED_ITEM_NOT_AVAILABLE;
02888 }
02889 #endif   /* defined(HAVE_PRI_AOC_EVENTS) */
02890 
02891 #if defined(HAVE_PRI_AOC_EVENTS)
02892 /*!
02893  * \internal
02894  * \brief Convert PRI_AOC_CHARGED_ITEM to ast_aoc_charged_item.
02895  * \since 1.8
02896  *
02897  * \param value Value to convert to string.
02898  *
02899  * \return ast_aoc_charged_item
02900  */
02901 static enum ast_aoc_s_charged_item sig_pri_aoc_charged_item_to_ast(enum PRI_AOC_CHARGED_ITEM value)
02902 {
02903    switch (value) {
02904    case PRI_AOC_CHARGED_ITEM_NOT_AVAILABLE:
02905       return AST_AOC_CHARGED_ITEM_NA;
02906    case PRI_AOC_CHARGED_ITEM_SPECIAL_ARRANGEMENT:
02907       return AST_AOC_CHARGED_ITEM_SPECIAL_ARRANGEMENT;
02908    case PRI_AOC_CHARGED_ITEM_BASIC_COMMUNICATION:
02909       return AST_AOC_CHARGED_ITEM_BASIC_COMMUNICATION;
02910    case PRI_AOC_CHARGED_ITEM_CALL_ATTEMPT:
02911       return AST_AOC_CHARGED_ITEM_CALL_ATTEMPT;
02912    case PRI_AOC_CHARGED_ITEM_CALL_SETUP:
02913       return AST_AOC_CHARGED_ITEM_CALL_SETUP;
02914    case PRI_AOC_CHARGED_ITEM_USER_USER_INFO:
02915       return AST_AOC_CHARGED_ITEM_USER_USER_INFO;
02916    case PRI_AOC_CHARGED_ITEM_SUPPLEMENTARY_SERVICE:
02917       return AST_AOC_CHARGED_ITEM_SUPPLEMENTARY_SERVICE;
02918    }
02919    return AST_AOC_CHARGED_ITEM_NA;
02920 }
02921 #endif   /* defined(HAVE_PRI_AOC_EVENTS) */
02922 
02923 #if defined(HAVE_PRI_AOC_EVENTS)
02924 /*!
02925  * \internal
02926  * \brief Convert AST_AOC_MULTIPLER to PRI_AOC_MULTIPLIER.
02927  * \since 1.8
02928  *
02929  * \return pri enum equivalent.
02930  */
02931 static int sig_pri_aoc_multiplier_from_ast(enum ast_aoc_currency_multiplier mult)
02932 {
02933    switch (mult) {
02934    case AST_AOC_MULT_ONETHOUSANDTH:
02935       return PRI_AOC_MULTIPLIER_THOUSANDTH;
02936    case AST_AOC_MULT_ONEHUNDREDTH:
02937       return PRI_AOC_MULTIPLIER_HUNDREDTH;
02938    case AST_AOC_MULT_ONETENTH:
02939       return PRI_AOC_MULTIPLIER_TENTH;
02940    case AST_AOC_MULT_ONE:
02941       return PRI_AOC_MULTIPLIER_ONE;
02942    case AST_AOC_MULT_TEN:
02943       return PRI_AOC_MULTIPLIER_TEN;
02944    case AST_AOC_MULT_HUNDRED:
02945       return PRI_AOC_MULTIPLIER_HUNDRED;
02946    case AST_AOC_MULT_THOUSAND:
02947       return PRI_AOC_MULTIPLIER_THOUSAND;
02948    default:
02949       return PRI_AOC_MULTIPLIER_ONE;
02950    }
02951 }
02952 #endif   /* defined(HAVE_PRI_AOC_EVENTS) */
02953 
02954 #if defined(HAVE_PRI_AOC_EVENTS)
02955 /*!
02956  * \internal
02957  * \brief Convert PRI_AOC_MULTIPLIER to AST_AOC_MULTIPLIER
02958  * \since 1.8
02959  *
02960  * \return ast enum equivalent.
02961  */
02962 static int sig_pri_aoc_multiplier_from_pri(const int mult)
02963 {
02964    switch (mult) {
02965    case PRI_AOC_MULTIPLIER_THOUSANDTH:
02966       return AST_AOC_MULT_ONETHOUSANDTH;
02967    case PRI_AOC_MULTIPLIER_HUNDREDTH:
02968       return AST_AOC_MULT_ONEHUNDREDTH;
02969    case PRI_AOC_MULTIPLIER_TENTH:
02970       return AST_AOC_MULT_ONETENTH;
02971    case PRI_AOC_MULTIPLIER_ONE:
02972       return AST_AOC_MULT_ONE;
02973    case PRI_AOC_MULTIPLIER_TEN:
02974       return AST_AOC_MULT_TEN;
02975    case PRI_AOC_MULTIPLIER_HUNDRED:
02976       return AST_AOC_MULT_HUNDRED;
02977    case PRI_AOC_MULTIPLIER_THOUSAND:
02978       return AST_AOC_MULT_THOUSAND;
02979    default:
02980       return AST_AOC_MULT_ONE;
02981    }
02982 }
02983 #endif   /* defined(HAVE_PRI_AOC_EVENTS) */
02984 
02985 #if defined(HAVE_PRI_AOC_EVENTS)
02986 /*!
02987  * \internal
02988  * \brief Convert ast_aoc_time_scale representation to PRI_AOC_TIME_SCALE
02989  * \since 1.8
02990  *
02991  * \param value Value to convert to ast representation
02992  *
02993  * \return PRI_AOC_TIME_SCALE
02994  */
02995 static enum PRI_AOC_TIME_SCALE sig_pri_aoc_scale_to_pri(enum ast_aoc_time_scale value)
02996 {
02997    switch (value) {
02998    default:
02999    case AST_AOC_TIME_SCALE_HUNDREDTH_SECOND:
03000       return PRI_AOC_TIME_SCALE_HUNDREDTH_SECOND;
03001    case AST_AOC_TIME_SCALE_TENTH_SECOND:
03002       return PRI_AOC_TIME_SCALE_TENTH_SECOND;
03003    case AST_AOC_TIME_SCALE_SECOND:
03004       return PRI_AOC_TIME_SCALE_SECOND;
03005    case AST_AOC_TIME_SCALE_TEN_SECOND:
03006       return PRI_AOC_TIME_SCALE_TEN_SECOND;
03007    case AST_AOC_TIME_SCALE_MINUTE:
03008       return PRI_AOC_TIME_SCALE_MINUTE;
03009    case AST_AOC_TIME_SCALE_HOUR:
03010       return PRI_AOC_TIME_SCALE_HOUR;
03011    case AST_AOC_TIME_SCALE_DAY:
03012       return PRI_AOC_TIME_SCALE_DAY;
03013    }
03014 }
03015 #endif   /* defined(HAVE_PRI_AOC_EVENTS) */
03016 
03017 #if defined(HAVE_PRI_AOC_EVENTS)
03018 /*!
03019  * \internal
03020  * \brief Convert PRI_AOC_TIME_SCALE to ast aoc representation
03021  * \since 1.8
03022  *
03023  * \param value Value to convert to ast representation
03024  *
03025  * \return ast aoc time scale
03026  */
03027 static enum ast_aoc_time_scale sig_pri_aoc_scale_to_ast(enum PRI_AOC_TIME_SCALE value)
03028 {
03029    switch (value) {
03030    default:
03031    case PRI_AOC_TIME_SCALE_HUNDREDTH_SECOND:
03032       return AST_AOC_TIME_SCALE_HUNDREDTH_SECOND;
03033    case PRI_AOC_TIME_SCALE_TENTH_SECOND:
03034       return AST_AOC_TIME_SCALE_TENTH_SECOND;
03035    case PRI_AOC_TIME_SCALE_SECOND:
03036       return AST_AOC_TIME_SCALE_SECOND;
03037    case PRI_AOC_TIME_SCALE_TEN_SECOND:
03038       return AST_AOC_TIME_SCALE_TEN_SECOND;
03039    case PRI_AOC_TIME_SCALE_MINUTE:
03040       return AST_AOC_TIME_SCALE_MINUTE;
03041    case PRI_AOC_TIME_SCALE_HOUR:
03042       return AST_AOC_TIME_SCALE_HOUR;
03043    case PRI_AOC_TIME_SCALE_DAY:
03044       return AST_AOC_TIME_SCALE_DAY;
03045    }
03046    return AST_AOC_TIME_SCALE_HUNDREDTH_SECOND;
03047 }
03048 #endif   /* defined(HAVE_PRI_AOC_EVENTS) */
03049 
03050 #if defined(HAVE_PRI_AOC_EVENTS)
03051 /*!
03052  * \internal
03053  * \brief Handle AOC-S control frame
03054  * \since 1.8
03055  *
03056  * \param aoc_s AOC-S event parameters.
03057  * \param owner Asterisk channel associated with the call.
03058  * \param passthrough indicating if this message should be queued on the ast channel
03059  *
03060  * \note Assumes the pri->lock is already obtained.
03061  * \note Assumes the sig_pri private is locked
03062  * \note Assumes the owner channel lock is already obtained.
03063  *
03064  * \return Nothing
03065  */
03066 static void sig_pri_aoc_s_from_pri(const struct pri_subcmd_aoc_s *aoc_s, struct ast_channel *owner, int passthrough)
03067 {
03068    struct ast_aoc_decoded *decoded = NULL;
03069    struct ast_aoc_encoded *encoded = NULL;
03070    size_t encoded_size = 0;
03071    int idx;
03072 
03073    if (!owner || !aoc_s) {
03074       return;
03075    }
03076 
03077    if (!(decoded = ast_aoc_create(AST_AOC_S, 0, 0))) {
03078       return;
03079    }
03080 
03081    for (idx = 0; idx < aoc_s->num_items; ++idx) {
03082       enum ast_aoc_s_charged_item charged_item;
03083 
03084       charged_item = sig_pri_aoc_charged_item_to_ast(aoc_s->item[idx].chargeable);
03085       if (charged_item == AST_AOC_CHARGED_ITEM_NA) {
03086          /* Delete the unknown charged item from the list. */
03087          continue;
03088       }
03089       switch (aoc_s->item[idx].rate_type) {
03090       case PRI_AOC_RATE_TYPE_DURATION:
03091          ast_aoc_s_add_rate_duration(decoded,
03092             charged_item,
03093             aoc_s->item[idx].rate.duration.amount.cost,
03094             sig_pri_aoc_multiplier_from_pri(aoc_s->item[idx].rate.duration.amount.multiplier),
03095             aoc_s->item[idx].rate.duration.currency,
03096             aoc_s->item[idx].rate.duration.time.length,
03097             sig_pri_aoc_scale_to_ast(aoc_s->item[idx].rate.duration.time.scale),
03098             aoc_s->item[idx].rate.duration.granularity.length,
03099             sig_pri_aoc_scale_to_ast(aoc_s->item[idx].rate.duration.granularity.scale),
03100             aoc_s->item[idx].rate.duration.charging_type);
03101          break;
03102       case PRI_AOC_RATE_TYPE_FLAT:
03103          ast_aoc_s_add_rate_flat(decoded,
03104             charged_item,
03105             aoc_s->item[idx].rate.flat.amount.cost,
03106             sig_pri_aoc_multiplier_from_pri(aoc_s->item[idx].rate.flat.amount.multiplier),
03107             aoc_s->item[idx].rate.flat.currency);
03108          break;
03109       case PRI_AOC_RATE_TYPE_VOLUME:
03110          ast_aoc_s_add_rate_volume(decoded,
03111             charged_item,
03112             aoc_s->item[idx].rate.volume.unit,
03113             aoc_s->item[idx].rate.volume.amount.cost,
03114             sig_pri_aoc_multiplier_from_pri(aoc_s->item[idx].rate.volume.amount.multiplier),
03115             aoc_s->item[idx].rate.volume.currency);
03116          break;
03117       case PRI_AOC_RATE_TYPE_SPECIAL_CODE:
03118          ast_aoc_s_add_rate_special_charge_code(decoded,
03119             charged_item,
03120             aoc_s->item[idx].rate.special);
03121          break;
03122       case PRI_AOC_RATE_TYPE_FREE:
03123          ast_aoc_s_add_rate_free(decoded, charged_item, 0);
03124          break;
03125       case PRI_AOC_RATE_TYPE_FREE_FROM_BEGINNING:
03126          ast_aoc_s_add_rate_free(decoded, charged_item, 1);
03127          break;
03128       default:
03129          ast_aoc_s_add_rate_na(decoded, charged_item);
03130          break;
03131       }
03132    }
03133 
03134    if (passthrough && (encoded = ast_aoc_encode(decoded, &encoded_size, owner))) {
03135       ast_queue_control_data(owner, AST_CONTROL_AOC, encoded, encoded_size);
03136    }
03137 
03138    ast_aoc_manager_event(decoded, owner);
03139 
03140    ast_aoc_destroy_decoded(decoded);
03141    ast_aoc_destroy_encoded(encoded);
03142 }
03143 #endif   /* defined(HAVE_PRI_AOC_EVENTS) */
03144 
03145 #if defined(HAVE_PRI_AOC_EVENTS)
03146 /*!
03147  * \internal
03148  * \brief Generate AOC Request Response
03149  * \since 1.8
03150  *
03151  * \param aoc_request
03152  *
03153  * \note Assumes the pri->lock is already obtained.
03154  * \note Assumes the sig_pri private is locked
03155  * \note Assumes the owner channel lock is already obtained.
03156  *
03157  * \return Nothing
03158  */
03159 static void sig_pri_aoc_request_from_pri(const struct pri_subcmd_aoc_request *aoc_request, struct sig_pri_chan *pvt, q931_call *call)
03160 {
03161    int request;
03162 
03163    if (!aoc_request) {
03164       return;
03165    }
03166 
03167    request = aoc_request->charging_request;
03168 
03169    if (request & PRI_AOC_REQUEST_S) {
03170       if (pvt->pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_S) {
03171          /* An AOC-S response must come from the other side, so save off this invoke_id
03172           * and see if an AOC-S message comes in before the call is answered. */
03173          pvt->aoc_s_request_invoke_id = aoc_request->invoke_id;
03174          pvt->aoc_s_request_invoke_id_valid = 1;
03175 
03176       } else {
03177          pri_aoc_s_request_response_send(pvt->pri->pri,
03178             call,
03179             aoc_request->invoke_id,
03180             NULL);
03181       }
03182    }
03183 
03184    if (request & PRI_AOC_REQUEST_D) {
03185       if (pvt->pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_D) {
03186          pri_aoc_de_request_response_send(pvt->pri->pri,
03187             call,
03188             PRI_AOC_REQ_RSP_CHARGING_INFO_FOLLOWS,
03189             aoc_request->invoke_id);
03190       } else {
03191          pri_aoc_de_request_response_send(pvt->pri->pri,
03192             call,
03193             PRI_AOC_REQ_RSP_ERROR_NOT_AVAILABLE,
03194             aoc_request->invoke_id);
03195       }
03196    }
03197 
03198    if (request & PRI_AOC_REQUEST_E) {
03199       if (pvt->pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_E) {
03200          pri_aoc_de_request_response_send(pvt->pri->pri,
03201             call,
03202             PRI_AOC_REQ_RSP_CHARGING_INFO_FOLLOWS,
03203             aoc_request->invoke_id);
03204       } else {
03205          pri_aoc_de_request_response_send(pvt->pri->pri,
03206             call,
03207             PRI_AOC_REQ_RSP_ERROR_NOT_AVAILABLE,
03208             aoc_request->invoke_id);
03209       }
03210    }
03211 }
03212 #endif   /* defined(HAVE_PRI_AOC_EVENTS) */
03213 
03214 #if defined(HAVE_PRI_AOC_EVENTS)
03215 /*!
03216  * \internal
03217  * \brief Generate AOC-D AST_CONTROL_AOC frame
03218  * \since 1.8
03219  *
03220  * \param aoc_e AOC-D event parameters.
03221  * \param owner Asterisk channel associated with the call.
03222  * \param passthrough indicating if this message should be queued on the ast channel
03223  *
03224  * \note Assumes the pri->lock is already obtained.
03225  * \note Assumes the sig_pri private is locked
03226  * \note Assumes the owner channel lock is already obtained.
03227  *
03228  * \return Nothing
03229  */
03230 static void sig_pri_aoc_d_from_pri(const struct pri_subcmd_aoc_d *aoc_d, struct ast_channel *owner, int passthrough)
03231 {
03232    struct ast_aoc_decoded *decoded = NULL;
03233    struct ast_aoc_encoded *encoded = NULL;
03234    size_t encoded_size = 0;
03235    enum ast_aoc_charge_type type;
03236 
03237    if (!owner || !aoc_d) {
03238       return;
03239    }
03240 
03241    switch (aoc_d->charge) {
03242    case PRI_AOC_DE_CHARGE_CURRENCY:
03243       type = AST_AOC_CHARGE_CURRENCY;
03244       break;
03245    case PRI_AOC_DE_CHARGE_UNITS:
03246       type = AST_AOC_CHARGE_UNIT;
03247       break;
03248    case PRI_AOC_DE_CHARGE_FREE:
03249       type = AST_AOC_CHARGE_FREE;
03250       break;
03251    default:
03252       type = AST_AOC_CHARGE_NA;
03253       break;
03254    }
03255 
03256    if (!(decoded = ast_aoc_create(AST_AOC_D, type, 0))) {
03257       return;
03258    }
03259 
03260    switch (aoc_d->billing_accumulation) {
03261    default:
03262       ast_debug(1, "AOC-D billing accumulation has unknown value: %d\n",
03263          aoc_d->billing_accumulation);
03264       /* Fall through */
03265    case 0:/* subTotal */
03266       ast_aoc_set_total_type(decoded, AST_AOC_SUBTOTAL);
03267       break;
03268    case 1:/* total */
03269       ast_aoc_set_total_type(decoded, AST_AOC_TOTAL);
03270       break;
03271    }
03272 
03273    switch (aoc_d->billing_id) {
03274    case PRI_AOC_D_BILLING_ID_NORMAL:
03275       ast_aoc_set_billing_id(decoded, AST_AOC_BILLING_NORMAL);
03276       break;
03277    case PRI_AOC_D_BILLING_ID_REVERSE:
03278       ast_aoc_set_billing_id(decoded, AST_AOC_BILLING_REVERSE_CHARGE);
03279       break;
03280    case PRI_AOC_D_BILLING_ID_CREDIT_CARD:
03281       ast_aoc_set_billing_id(decoded, AST_AOC_BILLING_CREDIT_CARD);
03282       break;
03283    case PRI_AOC_D_BILLING_ID_NOT_AVAILABLE:
03284    default:
03285       ast_aoc_set_billing_id(decoded, AST_AOC_BILLING_NA);
03286       break;
03287    }
03288 
03289    switch (aoc_d->charge) {
03290    case PRI_AOC_DE_CHARGE_CURRENCY:
03291       ast_aoc_set_currency_info(decoded,
03292          aoc_d->recorded.money.amount.cost,
03293          sig_pri_aoc_multiplier_from_pri(aoc_d->recorded.money.amount.multiplier),
03294          aoc_d->recorded.money.currency);
03295       break;
03296    case PRI_AOC_DE_CHARGE_UNITS:
03297       {
03298          int i;
03299          for (i = 0; i < aoc_d->recorded.unit.num_items; ++i) {
03300             /* if type or number are negative, then they are not present */
03301             ast_aoc_add_unit_entry(decoded,
03302                (aoc_d->recorded.unit.item[i].number >= 0 ? 1 : 0),
03303                aoc_d->recorded.unit.item[i].number,
03304                (aoc_d->recorded.unit.item[i].type >= 0 ? 1 : 0),
03305                aoc_d->recorded.unit.item[i].type);
03306          }
03307       }
03308       break;
03309    }
03310 
03311    if (passthrough && (encoded = ast_aoc_encode(decoded, &encoded_size, owner))) {
03312       ast_queue_control_data(owner, AST_CONTROL_AOC, encoded, encoded_size);
03313    }
03314 
03315    ast_aoc_manager_event(decoded, owner);
03316 
03317    ast_aoc_destroy_decoded(decoded);
03318    ast_aoc_destroy_encoded(encoded);
03319 }
03320 #endif   /* defined(HAVE_PRI_AOC_EVENTS) */
03321 
03322 #if defined(HAVE_PRI_AOC_EVENTS)
03323 /*!
03324  * \internal
03325  * \brief Generate AOC-E AST_CONTROL_AOC frame
03326  * \since 1.8
03327  *
03328  * \param aoc_e AOC-E event parameters.
03329  * \param owner Asterisk channel associated with the call.
03330  * \param passthrough indicating if this message should be queued on the ast channel
03331  *
03332  * \note Assumes the pri->lock is already obtained.
03333  * \note Assumes the sig_pri private is locked
03334  * \note Assumes the owner channel lock is already obtained.
03335  * \note owner channel may be NULL. In that case, generate event only
03336  *
03337  * \return Nothing
03338  */
03339 static void sig_pri_aoc_e_from_pri(const struct pri_subcmd_aoc_e *aoc_e, struct ast_channel *owner, int passthrough)
03340 {
03341    struct ast_aoc_decoded *decoded = NULL;
03342    struct ast_aoc_encoded *encoded = NULL;
03343    size_t encoded_size = 0;
03344    enum ast_aoc_charge_type type;
03345 
03346    if (!aoc_e) {
03347       return;
03348    }
03349 
03350    switch (aoc_e->charge) {
03351    case PRI_AOC_DE_CHARGE_CURRENCY:
03352       type = AST_AOC_CHARGE_CURRENCY;
03353       break;
03354    case PRI_AOC_DE_CHARGE_UNITS:
03355       type = AST_AOC_CHARGE_UNIT;
03356       break;
03357    case PRI_AOC_DE_CHARGE_FREE:
03358       type = AST_AOC_CHARGE_FREE;
03359       break;
03360    default:
03361       type = AST_AOC_CHARGE_NA;
03362       break;
03363    }
03364 
03365    if (!(decoded = ast_aoc_create(AST_AOC_E, type, 0))) {
03366       return;
03367    }
03368 
03369    switch (aoc_e->associated.charging_type) {
03370    case PRI_AOC_E_CHARGING_ASSOCIATION_NUMBER:
03371       if (!aoc_e->associated.charge.number.valid) {
03372          break;
03373       }
03374       ast_aoc_set_association_number(decoded, aoc_e->associated.charge.number.str, aoc_e->associated.charge.number.plan);
03375       break;
03376    case PRI_AOC_E_CHARGING_ASSOCIATION_ID:
03377       ast_aoc_set_association_id(decoded, aoc_e->associated.charge.id);
03378       break;
03379    default:
03380       break;
03381    }
03382 
03383    switch (aoc_e->billing_id) {
03384    case PRI_AOC_E_BILLING_ID_NORMAL:
03385       ast_aoc_set_billing_id(decoded, AST_AOC_BILLING_NORMAL);
03386       break;
03387    case PRI_AOC_E_BILLING_ID_REVERSE:
03388       ast_aoc_set_billing_id(decoded, AST_AOC_BILLING_REVERSE_CHARGE);
03389       break;
03390    case PRI_AOC_E_BILLING_ID_CREDIT_CARD:
03391       ast_aoc_set_billing_id(decoded, AST_AOC_BILLING_CREDIT_CARD);
03392       break;
03393    case PRI_AOC_E_BILLING_ID_CALL_FORWARDING_UNCONDITIONAL:
03394       ast_aoc_set_billing_id(decoded, AST_AOC_BILLING_CALL_FWD_UNCONDITIONAL);
03395       break;
03396    case PRI_AOC_E_BILLING_ID_CALL_FORWARDING_BUSY:
03397       ast_aoc_set_billing_id(decoded, AST_AOC_BILLING_CALL_FWD_BUSY);
03398       break;
03399    case PRI_AOC_E_BILLING_ID_CALL_FORWARDING_NO_REPLY:
03400       ast_aoc_set_billing_id(decoded, AST_AOC_BILLING_CALL_FWD_NO_REPLY);
03401       break;
03402    case PRI_AOC_E_BILLING_ID_CALL_DEFLECTION:
03403       ast_aoc_set_billing_id(decoded, AST_AOC_BILLING_CALL_DEFLECTION);
03404       break;
03405    case PRI_AOC_E_BILLING_ID_CALL_TRANSFER:
03406       ast_aoc_set_billing_id(decoded, AST_AOC_BILLING_CALL_TRANSFER);
03407       break;
03408    case PRI_AOC_E_BILLING_ID_NOT_AVAILABLE:
03409    default:
03410       ast_aoc_set_billing_id(decoded, AST_AOC_BILLING_NA);
03411       break;
03412    }
03413 
03414    switch (aoc_e->charge) {
03415    case PRI_AOC_DE_CHARGE_CURRENCY:
03416       ast_aoc_set_currency_info(decoded,
03417          aoc_e->recorded.money.amount.cost,
03418          sig_pri_aoc_multiplier_from_pri(aoc_e->recorded.money.amount.multiplier),
03419          aoc_e->recorded.money.currency);
03420       break;
03421    case PRI_AOC_DE_CHARGE_UNITS:
03422       {
03423          int i;
03424          for (i = 0; i < aoc_e->recorded.unit.num_items; ++i) {
03425             /* if type or number are negative, then they are not present */
03426             ast_aoc_add_unit_entry(decoded,
03427                (aoc_e->recorded.unit.item[i].number >= 0 ? 1 : 0),
03428                aoc_e->recorded.unit.item[i].number,
03429                (aoc_e->recorded.unit.item[i].type >= 0 ? 1 : 0),
03430                aoc_e->recorded.unit.item[i].type);
03431          }
03432       }
03433    }
03434 
03435    if (passthrough && owner && (encoded = ast_aoc_encode(decoded, &encoded_size, owner))) {
03436       ast_queue_control_data(owner, AST_CONTROL_AOC, encoded, encoded_size);
03437    }
03438 
03439    ast_aoc_manager_event(decoded, owner);
03440 
03441    ast_aoc_destroy_decoded(decoded);
03442    ast_aoc_destroy_encoded(encoded);
03443 }
03444 #endif   /* defined(HAVE_PRI_AOC_EVENTS) */
03445 
03446 #if defined(HAVE_PRI_AOC_EVENTS)
03447 /*!
03448  * \internal
03449  * \brief send an AOC-S message on the current call
03450  *
03451  * \param pvt sig_pri private channel structure.
03452  * \param generic decoded ast AOC message
03453  *
03454  * \return Nothing
03455  *
03456  * \note Assumes that the PRI lock is already obtained.
03457  */
03458 static void sig_pri_aoc_s_from_ast(struct sig_pri_chan *pvt, struct ast_aoc_decoded *decoded)
03459 {
03460    struct pri_subcmd_aoc_s aoc_s = { 0, };
03461    const struct ast_aoc_s_entry *entry;
03462    int idx;
03463 
03464    for (idx = 0; idx < ast_aoc_s_get_count(decoded); idx++) {
03465       if (!(entry = ast_aoc_s_get_rate_info(decoded, idx))) {
03466          break;
03467       }
03468 
03469       aoc_s.item[idx].chargeable = sig_pri_aoc_charged_item_to_pri(entry->charged_item);
03470 
03471       switch (entry->rate_type) {
03472       case AST_AOC_RATE_TYPE_DURATION:
03473          aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_DURATION;
03474          aoc_s.item[idx].rate.duration.amount.cost = entry->rate.duration.amount;
03475          aoc_s.item[idx].rate.duration.amount.multiplier =
03476             sig_pri_aoc_multiplier_from_ast(entry->rate.duration.multiplier);
03477          aoc_s.item[idx].rate.duration.time.length = entry->rate.duration.time;
03478          aoc_s.item[idx].rate.duration.time.scale =
03479             sig_pri_aoc_scale_to_pri(entry->rate.duration.time_scale);
03480          aoc_s.item[idx].rate.duration.granularity.length = entry->rate.duration.granularity_time;
03481          aoc_s.item[idx].rate.duration.granularity.scale =
03482             sig_pri_aoc_scale_to_pri(entry->rate.duration.granularity_time_scale);
03483          aoc_s.item[idx].rate.duration.charging_type = entry->rate.duration.charging_type;
03484 
03485          if (!ast_strlen_zero(entry->rate.duration.currency_name)) {
03486             ast_copy_string(aoc_s.item[idx].rate.duration.currency,
03487                entry->rate.duration.currency_name,
03488                sizeof(aoc_s.item[idx].rate.duration.currency));
03489          }
03490          break;
03491       case AST_AOC_RATE_TYPE_FLAT:
03492          aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_FLAT;
03493          aoc_s.item[idx].rate.flat.amount.cost = entry->rate.flat.amount;
03494          aoc_s.item[idx].rate.flat.amount.multiplier =
03495             sig_pri_aoc_multiplier_from_ast(entry->rate.flat.multiplier);
03496 
03497          if (!ast_strlen_zero(entry->rate.flat.currency_name)) {
03498             ast_copy_string(aoc_s.item[idx].rate.flat.currency,
03499                entry->rate.flat.currency_name,
03500                sizeof(aoc_s.item[idx].rate.flat.currency));
03501          }
03502          break;
03503       case AST_AOC_RATE_TYPE_VOLUME:
03504          aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_VOLUME;
03505          aoc_s.item[idx].rate.volume.unit = entry->rate.volume.volume_unit;
03506          aoc_s.item[idx].rate.volume.amount.cost = entry->rate.volume.amount;
03507          aoc_s.item[idx].rate.volume.amount.multiplier =
03508             sig_pri_aoc_multiplier_from_ast(entry->rate.volume.multiplier);
03509 
03510          if (!ast_strlen_zero(entry->rate.volume.currency_name)) {
03511             ast_copy_string(aoc_s.item[idx].rate.volume.currency,
03512                entry->rate.volume.currency_name,
03513                sizeof(aoc_s.item[idx].rate.volume.currency));
03514          }
03515          break;
03516       case AST_AOC_RATE_TYPE_SPECIAL_CODE:
03517          aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_SPECIAL_CODE;
03518          aoc_s.item[idx].rate.special = entry->rate.special_code;
03519          break;
03520       case AST_AOC_RATE_TYPE_FREE:
03521          aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_FREE;
03522          break;
03523       case AST_AOC_RATE_TYPE_FREE_FROM_BEGINNING:
03524          aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_FREE_FROM_BEGINNING;
03525          break;
03526       default:
03527       case AST_AOC_RATE_TYPE_NA:
03528          aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_NOT_AVAILABLE;
03529          break;
03530       }
03531    }
03532    aoc_s.num_items = idx;
03533 
03534    /* if this rate should be sent as a response to an AOC-S request we will
03535     * have an aoc_s_request_invoke_id associated with this pvt */
03536    if (pvt->aoc_s_request_invoke_id_valid) {
03537       pri_aoc_s_request_response_send(pvt->pri->pri, pvt->call, pvt->aoc_s_request_invoke_id, &aoc_s);
03538       pvt->aoc_s_request_invoke_id_valid = 0;
03539    } else {
03540       pri_aoc_s_send(pvt->pri->pri, pvt->call, &aoc_s);
03541    }
03542 }
03543 #endif   /* defined(HAVE_PRI_AOC_EVENTS) */
03544 
03545 #if defined(HAVE_PRI_AOC_EVENTS)
03546 /*!
03547  * \internal
03548  * \brief send an AOC-D message on the current call
03549  *
03550  * \param pvt sig_pri private channel structure.
03551  * \param generic decoded ast AOC message
03552  *
03553  * \return Nothing
03554  *
03555  * \note Assumes that the PRI lock is already obtained.
03556  */
03557 static void sig_pri_aoc_d_from_ast(struct sig_pri_chan *pvt, struct ast_aoc_decoded *decoded)
03558 {
03559    struct pri_subcmd_aoc_d aoc_d = { 0, };
03560 
03561    aoc_d.billing_accumulation = (ast_aoc_get_total_type(decoded) == AST_AOC_TOTAL) ? 1 : 0;
03562 
03563    switch (ast_aoc_get_billing_id(decoded)) {
03564    case AST_AOC_BILLING_NORMAL:
03565       aoc_d.billing_id = PRI_AOC_D_BILLING_ID_NORMAL;
03566       break;
03567    case AST_AOC_BILLING_REVERSE_CHARGE:
03568       aoc_d.billing_id = PRI_AOC_D_BILLING_ID_REVERSE;
03569       break;
03570    case AST_AOC_BILLING_CREDIT_CARD:
03571       aoc_d.billing_id = PRI_AOC_D_BILLING_ID_CREDIT_CARD;
03572       break;
03573    case AST_AOC_BILLING_NA:
03574    default:
03575       aoc_d.billing_id = PRI_AOC_D_BILLING_ID_NOT_AVAILABLE;
03576       break;
03577    }
03578 
03579    switch (ast_aoc_get_charge_type(decoded)) {
03580    case AST_AOC_CHARGE_FREE:
03581       aoc_d.charge = PRI_AOC_DE_CHARGE_FREE;
03582       break;
03583    case AST_AOC_CHARGE_CURRENCY:
03584       {
03585          const char *currency_name = ast_aoc_get_currency_name(decoded);
03586          aoc_d.charge = PRI_AOC_DE_CHARGE_CURRENCY;
03587          aoc_d.recorded.money.amount.cost = ast_aoc_get_currency_amount(decoded);
03588          aoc_d.recorded.money.amount.multiplier = sig_pri_aoc_multiplier_from_ast(ast_aoc_get_currency_multiplier(decoded));
03589          if (!ast_strlen_zero(currency_name)) {
03590             ast_copy_string(aoc_d.recorded.money.currency, currency_name, sizeof(aoc_d.recorded.money.currency));
03591          }
03592       }
03593       break;
03594    case AST_AOC_CHARGE_UNIT:
03595       {
03596          const struct ast_aoc_unit_entry *entry;
03597          int i;
03598          aoc_d.charge = PRI_AOC_DE_CHARGE_UNITS;
03599          for (i = 0; i < ast_aoc_get_unit_count(decoded); i++) {
03600             if ((entry = ast_aoc_get_unit_info(decoded, i)) && i < ARRAY_LEN(aoc_d.recorded.unit.item)) {
03601                if (entry->valid_amount) {
03602                   aoc_d.recorded.unit.item[i].number = entry->amount;
03603                } else {
03604                   aoc_d.recorded.unit.item[i].number = -1;
03605                }
03606                if (entry->valid_type) {
03607                   aoc_d.recorded.unit.item[i].type = entry->type;
03608                } else {
03609                   aoc_d.recorded.unit.item[i].type = -1;
03610                }
03611                aoc_d.recorded.unit.num_items++;
03612             } else {
03613                break;
03614             }
03615          }
03616       }
03617       break;
03618    case AST_AOC_CHARGE_NA:
03619    default:
03620       aoc_d.charge = PRI_AOC_DE_CHARGE_NOT_AVAILABLE;
03621       break;
03622    }
03623 
03624    pri_aoc_d_send(pvt->pri->pri, pvt->call, &aoc_d);
03625 }
03626 #endif   /* defined(HAVE_PRI_AOC_EVENTS) */
03627 
03628 #if defined(HAVE_PRI_AOC_EVENTS)
03629 /*!
03630  * \internal
03631  * \brief send an AOC-E message on the current call
03632  *
03633  * \param pvt sig_pri private channel structure.
03634  * \param generic decoded ast AOC message
03635  *
03636  * \return Nothing
03637  *
03638  * \note Assumes that the PRI lock is already obtained.
03639  */
03640 static void sig_pri_aoc_e_from_ast(struct sig_pri_chan *pvt, struct ast_aoc_decoded *decoded)
03641 {
03642    struct pri_subcmd_aoc_e *aoc_e = &pvt->aoc_e;
03643    const struct ast_aoc_charging_association *ca = ast_aoc_get_association_info(decoded);
03644 
03645    memset(aoc_e, 0, sizeof(*aoc_e));
03646    pvt->holding_aoce = 1;
03647 
03648    switch (ca->charging_type) {
03649    case AST_AOC_CHARGING_ASSOCIATION_NUMBER:
03650       aoc_e->associated.charge.number.valid = 1;
03651       ast_copy_string(aoc_e->associated.charge.number.str,
03652          ca->charge.number.number,
03653          sizeof(aoc_e->associated.charge.number.str));
03654       aoc_e->associated.charge.number.plan = ca->charge.number.plan;
03655       aoc_e->associated.charging_type = PRI_AOC_E_CHARGING_ASSOCIATION_NUMBER;
03656       break;
03657    case AST_AOC_CHARGING_ASSOCIATION_ID:
03658       aoc_e->associated.charge.id = ca->charge.id;
03659       aoc_e->associated.charging_type = PRI_AOC_E_CHARGING_ASSOCIATION_ID;
03660       break;
03661    case AST_AOC_CHARGING_ASSOCIATION_NA:
03662    default:
03663       break;
03664    }
03665 
03666    switch (ast_aoc_get_billing_id(decoded)) {
03667    case AST_AOC_BILLING_NORMAL:
03668       aoc_e->billing_id = PRI_AOC_E_BILLING_ID_NORMAL;
03669       break;
03670    case AST_AOC_BILLING_REVERSE_CHARGE:
03671       aoc_e->billing_id = PRI_AOC_E_BILLING_ID_REVERSE;
03672       break;
03673    case AST_AOC_BILLING_CREDIT_CARD:
03674       aoc_e->billing_id = PRI_AOC_E_BILLING_ID_CREDIT_CARD;
03675       break;
03676    case AST_AOC_BILLING_CALL_FWD_UNCONDITIONAL:
03677       aoc_e->billing_id = PRI_AOC_E_BILLING_ID_CALL_FORWARDING_UNCONDITIONAL;
03678       break;
03679    case AST_AOC_BILLING_CALL_FWD_BUSY:
03680       aoc_e->billing_id = PRI_AOC_E_BILLING_ID_CALL_FORWARDING_BUSY;
03681       break;
03682    case AST_AOC_BILLING_CALL_FWD_NO_REPLY:
03683       aoc_e->billing_id = PRI_AOC_E_BILLING_ID_CALL_FORWARDING_NO_REPLY;
03684       break;
03685    case AST_AOC_BILLING_CALL_DEFLECTION:
03686       aoc_e->billing_id = PRI_AOC_E_BILLING_ID_CALL_DEFLECTION;
03687       break;
03688    case AST_AOC_BILLING_CALL_TRANSFER:
03689       aoc_e->billing_id = PRI_AOC_E_BILLING_ID_CALL_TRANSFER;
03690       break;
03691    case AST_AOC_BILLING_NA:
03692    default:
03693       aoc_e->billing_id = PRI_AOC_E_BILLING_ID_NOT_AVAILABLE;
03694       break;
03695    }
03696 
03697    switch (ast_aoc_get_charge_type(decoded)) {
03698    case AST_AOC_CHARGE_FREE:
03699       aoc_e->charge = PRI_AOC_DE_CHARGE_FREE;
03700       break;
03701    case AST_AOC_CHARGE_CURRENCY:
03702       {
03703          const char *currency_name = ast_aoc_get_currency_name(decoded);
03704          aoc_e->charge = PRI_AOC_DE_CHARGE_CURRENCY;
03705          aoc_e->recorded.money.amount.cost = ast_aoc_get_currency_amount(decoded);
03706          aoc_e->recorded.money.amount.multiplier = sig_pri_aoc_multiplier_from_ast(ast_aoc_get_currency_multiplier(decoded));
03707          if (!ast_strlen_zero(currency_name)) {
03708             ast_copy_string(aoc_e->recorded.money.currency, currency_name, sizeof(aoc_e->recorded.money.currency));
03709          }
03710       }
03711       break;
03712    case AST_AOC_CHARGE_UNIT:
03713       {
03714          const struct ast_aoc_unit_entry *entry;
03715          int i;
03716          aoc_e->charge = PRI_AOC_DE_CHARGE_UNITS;
03717          for (i = 0; i < ast_aoc_get_unit_count(decoded); i++) {
03718             if ((entry = ast_aoc_get_unit_info(decoded, i)) && i < ARRAY_LEN(aoc_e->recorded.unit.item)) {
03719                if (entry->valid_amount) {
03720                   aoc_e->recorded.unit.item[i].number = entry->amount;
03721                } else {
03722                   aoc_e->recorded.unit.item[i].number = -1;
03723                }
03724                if (entry->valid_type) {
03725                   aoc_e->recorded.unit.item[i].type = entry->type;
03726                } else {
03727                   aoc_e->recorded.unit.item[i].type = -1;
03728                }
03729                aoc_e->recorded.unit.num_items++;
03730             }
03731          }
03732       }
03733       break;
03734    case AST_AOC_CHARGE_NA:
03735    default:
03736       aoc_e->charge = PRI_AOC_DE_CHARGE_NOT_AVAILABLE;
03737       break;
03738    }
03739 }
03740 #endif   /* defined(HAVE_PRI_AOC_EVENTS) */
03741 
03742 #if defined(HAVE_PRI_AOC_EVENTS)
03743 /*!
03744  * \internal
03745  * \brief send an AOC-E termination request on ast_channel and set
03746  * hangup delay.
03747  *
03748  * \param pri PRI span control structure.
03749  * \param chanpos Channel position in the span.
03750  * \param ms to delay hangup
03751  *
03752  * \note Assumes the pri->lock is already obtained.
03753  * \note Assumes the sig_pri_lock_private(pri->pvts[chanpos]) is already obtained.
03754  *
03755  * \return Nothing
03756  */
03757 static void sig_pri_send_aoce_termination_request(struct sig_pri_span *pri, int chanpos, unsigned int ms)
03758 {
03759    struct sig_pri_chan *pvt;
03760    struct ast_aoc_decoded *decoded = NULL;
03761    struct ast_aoc_encoded *encoded = NULL;
03762    size_t encoded_size;
03763    struct timeval whentohangup = { 0, };
03764 
03765    sig_pri_lock_owner(pri, chanpos);
03766    pvt = pri->pvts[chanpos];
03767    if (!pvt->owner) {
03768       return;
03769    }
03770 
03771    if (!(decoded = ast_aoc_create(AST_AOC_REQUEST, 0, AST_AOC_REQUEST_E))) {
03772       ast_softhangup_nolock(pvt->owner, AST_SOFTHANGUP_DEV);
03773       goto cleanup_termination_request;
03774    }
03775 
03776    ast_aoc_set_termination_request(decoded);
03777 
03778    if (!(encoded = ast_aoc_encode(decoded, &encoded_size, pvt->owner))) {
03779       ast_softhangup_nolock(pvt->owner, AST_SOFTHANGUP_DEV);
03780       goto cleanup_termination_request;
03781    }
03782 
03783    /* convert ms to timeval */
03784    whentohangup.tv_usec = (ms % 1000) * 1000;
03785    whentohangup.tv_sec = ms / 1000;
03786 
03787    if (ast_queue_control_data(pvt->owner, AST_CONTROL_AOC, encoded, encoded_size)) {
03788       ast_softhangup_nolock(pvt->owner, AST_SOFTHANGUP_DEV);
03789       goto cleanup_termination_request;
03790    }
03791 
03792    pvt->waiting_for_aoce = 1;
03793    ast_channel_setwhentohangup_tv(pvt->owner, whentohangup);
03794    ast_log(LOG_DEBUG, "Delaying hangup on %s for aoc-e msg\n", pvt->owner->name);
03795 
03796 cleanup_termination_request:
03797    ast_channel_unlock(pvt->owner);
03798    ast_aoc_destroy_decoded(decoded);
03799    ast_aoc_destroy_encoded(encoded);
03800 }
03801 #endif   /* defined(HAVE_PRI_AOC_EVENTS) */
03802 
03803 /*!
03804  * \internal
03805  * \brief TRUE if PRI event came in on a CIS call.
03806  * \since 1.8
03807  *
03808  * \param channel PRI encoded span/channel
03809  *
03810  * \retval non-zero if CIS call.
03811  */
03812 static int sig_pri_is_cis_call(int channel)
03813 {
03814    return channel != -1 && (channel & PRI_CIS_CALL);
03815 }
03816 
03817 /*!
03818  * \internal
03819  * \brief Handle the CIS associated PRI subcommand events.
03820  * \since 1.8
03821  *
03822  * \param pri PRI span control structure.
03823  * \param event_id PRI event id
03824  * \param subcmds Subcommands to process if any. (Could be NULL).
03825  * \param call_rsp libpri opaque call structure to send any responses toward.
03826  * Could be NULL either because it is not available or the call is for the
03827  * dummy call reference.  However, this should not be NULL in the cases that
03828  * need to use the pointer to send a response message back.
03829  *
03830  * \note Assumes the pri->lock is already obtained.
03831  *
03832  * \return Nothing
03833  */
03834 static void sig_pri_handle_cis_subcmds(struct sig_pri_span *pri, int event_id,
03835    const struct pri_subcommands *subcmds, q931_call *call_rsp)
03836 {
03837    int index;
03838 #if defined(HAVE_PRI_CCSS)
03839    struct ast_cc_agent *agent;
03840    struct sig_pri_cc_agent_prv *agent_prv;
03841    struct sig_pri_cc_monitor_instance *monitor;
03842 #endif   /* defined(HAVE_PRI_CCSS) */
03843 
03844    if (!subcmds) {
03845       return;
03846    }
03847    for (index = 0; index < subcmds->counter_subcmd; ++index) {
03848       const struct pri_subcommand *subcmd = &subcmds->subcmd[index];
03849 
03850       switch (subcmd->cmd) {
03851 #if defined(STATUS_REQUEST_PLACE_HOLDER)
03852       case PRI_SUBCMD_STATUS_REQ:
03853       case PRI_SUBCMD_STATUS_REQ_RSP:
03854          /* Ignore for now. */
03855          break;
03856 #endif   /* defined(STATUS_REQUEST_PLACE_HOLDER) */
03857 #if defined(HAVE_PRI_CCSS)
03858       case PRI_SUBCMD_CC_REQ:
03859          agent = sig_pri_find_cc_agent_by_cc_id(pri, subcmd->u.cc_request.cc_id);
03860          if (!agent) {
03861             pri_cc_cancel(pri->pri, subcmd->u.cc_request.cc_id);
03862             break;
03863          }
03864          if (!ast_cc_request_is_within_limits()) {
03865             if (pri_cc_req_rsp(pri->pri, subcmd->u.cc_request.cc_id,
03866                5/* queue_full */)) {
03867                pri_cc_cancel(pri->pri, subcmd->u.cc_request.cc_id);
03868             }
03869             ast_cc_failed(agent->core_id, "%s agent system CC queue full",
03870                sig_pri_cc_type_name);
03871             ao2_ref(agent, -1);
03872             break;
03873          }
03874          agent_prv = agent->private_data;
03875          agent_prv->cc_request_response_pending = 1;
03876          if (ast_cc_agent_accept_request(agent->core_id,
03877             "%s caller accepted CC offer.", sig_pri_cc_type_name)) {
03878             agent_prv->cc_request_response_pending = 0;
03879             if (pri_cc_req_rsp(pri->pri, subcmd->u.cc_request.cc_id,
03880                2/* short_term_denial */)) {
03881                pri_cc_cancel(pri->pri, subcmd->u.cc_request.cc_id);
03882             }
03883             ast_cc_failed(agent->core_id, "%s agent CC core request accept failed",
03884                sig_pri_cc_type_name);
03885          }
03886          ao2_ref(agent, -1);
03887          break;
03888 #endif   /* defined(HAVE_PRI_CCSS) */
03889 #if defined(HAVE_PRI_CCSS)
03890       case PRI_SUBCMD_CC_REQ_RSP:
03891          monitor = sig_pri_find_cc_monitor_by_cc_id(pri,
03892             subcmd->u.cc_request_rsp.cc_id);
03893          if (!monitor) {
03894             pri_cc_cancel(pri->pri, subcmd->u.cc_request_rsp.cc_id);
03895             break;
03896          }
03897          switch (subcmd->u.cc_request_rsp.status) {
03898          case 0:/* success */
03899             ast_cc_monitor_request_acked(monitor->core_id,
03900                "%s far end accepted CC request", sig_pri_cc_type_name);
03901             break;
03902          case 1:/* timeout */
03903             ast_verb(2, "core_id:%d %s CC request timeout\n", monitor->core_id,
03904                sig_pri_cc_type_name);
03905             ast_cc_monitor_failed(monitor->core_id, monitor->name,
03906                "%s CC request timeout", sig_pri_cc_type_name);
03907             break;
03908          case 2:/* error */
03909             ast_verb(2, "core_id:%d %s CC request error: %s\n", monitor->core_id,
03910                sig_pri_cc_type_name,
03911                pri_facility_error2str(subcmd->u.cc_request_rsp.fail_code));
03912             ast_cc_monitor_failed(monitor->core_id, monitor->name,
03913                "%s CC request error", sig_pri_cc_type_name);
03914             break;
03915          case 3:/* reject */
03916             ast_verb(2, "core_id:%d %s CC request reject: %s\n", monitor->core_id,
03917                sig_pri_cc_type_name,
03918                pri_facility_reject2str(subcmd->u.cc_request_rsp.fail_code));
03919             ast_cc_monitor_failed(monitor->core_id, monitor->name,
03920                "%s CC request reject", sig_pri_cc_type_name);
03921             break;
03922          default:
03923             ast_verb(2, "core_id:%d %s CC request unknown status %d\n",
03924                monitor->core_id, sig_pri_cc_type_name,
03925                subcmd->u.cc_request_rsp.status);
03926             ast_cc_monitor_failed(monitor->core_id, monitor->name,
03927                "%s CC request unknown status", sig_pri_cc_type_name);
03928             break;
03929          }
03930          ao2_ref(monitor, -1);
03931          break;
03932 #endif   /* defined(HAVE_PRI_CCSS) */
03933 #if defined(HAVE_PRI_CCSS)
03934       case PRI_SUBCMD_CC_REMOTE_USER_FREE:
03935          monitor = sig_pri_find_cc_monitor_by_cc_id(pri,
03936             subcmd->u.cc_remote_user_free.cc_id);
03937          if (!monitor) {
03938             pri_cc_cancel(pri->pri, subcmd->u.cc_remote_user_free.cc_id);
03939             break;
03940          }
03941          ast_cc_monitor_callee_available(monitor->core_id,
03942             "%s callee has become available", sig_pri_cc_type_name);
03943          ao2_ref(monitor, -1);
03944          break;
03945 #endif   /* defined(HAVE_PRI_CCSS) */
03946 #if defined(HAVE_PRI_CCSS)
03947       case PRI_SUBCMD_CC_B_FREE:
03948          monitor = sig_pri_find_cc_monitor_by_cc_id(pri,
03949             subcmd->u.cc_b_free.cc_id);
03950          if (!monitor) {
03951             pri_cc_cancel(pri->pri, subcmd->u.cc_b_free.cc_id);
03952             break;
03953          }
03954          ast_cc_monitor_party_b_free(monitor->core_id);
03955          ao2_ref(monitor, -1);
03956          break;
03957 #endif   /* defined(HAVE_PRI_CCSS) */
03958 #if defined(HAVE_PRI_CCSS)
03959       case PRI_SUBCMD_CC_STATUS_REQ:
03960          monitor = sig_pri_find_cc_monitor_by_cc_id(pri,
03961             subcmd->u.cc_status_req.cc_id);
03962          if (!monitor) {
03963             pri_cc_cancel(pri->pri, subcmd->u.cc_status_req.cc_id);
03964             break;
03965          }
03966          ast_cc_monitor_status_request(monitor->core_id);
03967          ao2_ref(monitor, -1);
03968          break;
03969 #endif   /* defined(HAVE_PRI_CCSS) */
03970 #if defined(HAVE_PRI_CCSS)
03971       case PRI_SUBCMD_CC_STATUS_REQ_RSP:
03972          agent = sig_pri_find_cc_agent_by_cc_id(pri, subcmd->u.cc_status_req_rsp.cc_id);
03973          if (!agent) {
03974             pri_cc_cancel(pri->pri, subcmd->u.cc_status_req_rsp.cc_id);
03975             break;
03976          }
03977          ast_cc_agent_status_response(agent->core_id,
03978             subcmd->u.cc_status_req_rsp.status ? AST_DEVICE_INUSE
03979             : AST_DEVICE_NOT_INUSE);
03980          ao2_ref(agent, -1);
03981          break;
03982 #endif   /* defined(HAVE_PRI_CCSS) */
03983 #if defined(HAVE_PRI_CCSS)
03984       case PRI_SUBCMD_CC_STATUS:
03985          agent = sig_pri_find_cc_agent_by_cc_id(pri, subcmd->u.cc_status.cc_id);
03986          if (!agent) {
03987             pri_cc_cancel(pri->pri, subcmd->u.cc_status.cc_id);
03988             break;
03989          }
03990          if (subcmd->u.cc_status.status) {
03991             ast_cc_agent_caller_busy(agent->core_id, "%s agent caller is busy",
03992                sig_pri_cc_type_name);
03993          } else {
03994             ast_cc_agent_caller_available(agent->core_id,
03995                "%s agent caller is available", sig_pri_cc_type_name);
03996          }
03997          ao2_ref(agent, -1);
03998          break;
03999 #endif   /* defined(HAVE_PRI_CCSS) */
04000 #if defined(HAVE_PRI_CCSS)
04001       case PRI_SUBCMD_CC_CANCEL:
04002          sig_pri_cc_link_canceled(pri, subcmd->u.cc_cancel.cc_id,
04003             subcmd->u.cc_cancel.is_agent);
04004          break;
04005 #endif   /* defined(HAVE_PRI_CCSS) */
04006 #if defined(HAVE_PRI_CCSS)
04007       case PRI_SUBCMD_CC_STOP_ALERTING:
04008          monitor = sig_pri_find_cc_monitor_by_cc_id(pri,
04009             subcmd->u.cc_stop_alerting.cc_id);
04010          if (!monitor) {
04011             pri_cc_cancel(pri->pri, subcmd->u.cc_stop_alerting.cc_id);
04012             break;
04013          }
04014          ast_cc_monitor_stop_ringing(monitor->core_id);
04015          ao2_ref(monitor, -1);
04016          break;
04017 #endif   /* defined(HAVE_PRI_CCSS) */
04018 #if defined(HAVE_PRI_AOC_EVENTS)
04019       case PRI_SUBCMD_AOC_E:
04020          /* Queue AST_CONTROL_AOC frame */
04021          sig_pri_aoc_e_from_pri(&subcmd->u.aoc_e, NULL, 0);
04022          break;
04023 #endif   /* defined(HAVE_PRI_AOC_EVENTS) */
04024       default:
04025          ast_debug(2,
04026             "Unknown CIS subcommand(%d) in %s event on span %d.\n",
04027             subcmd->cmd, pri_event2str(event_id), pri->span);
04028          break;
04029       }
04030    }
04031 }
04032 
04033 #if defined(HAVE_PRI_AOC_EVENTS)
04034 /*!
04035  * \internal
04036  * \brief detect if AOC-S subcmd is present.
04037  * \since 1.8
04038  *
04039  * \param subcmds Subcommands to process if any. (Could be NULL).
04040  *
04041  * \note Knowing whether or not an AOC-E subcmd is present on certain
04042  * PRI hangup events is necessary to determine what method to use to hangup
04043  * the ast_channel.  If an AOC-E subcmd just came in, then a new AOC-E was queued
04044  * on the ast_channel.  If a soft hangup is used, the AOC-E msg will never make it
04045  * across the bridge, but if a AST_CONTROL_HANGUP frame is queued behind it
04046  * we can ensure the AOC-E frame makes it to it's destination before the hangup
04047  * frame is read.
04048  *
04049  *
04050  * \retval 0 AOC-E is not present in subcmd list
04051  * \retval 1 AOC-E is present in subcmd list
04052  */
04053 static int detect_aoc_e_subcmd(const struct pri_subcommands *subcmds)
04054 {
04055    int i;
04056 
04057    if (!subcmds) {
04058       return 0;
04059    }
04060    for (i = 0; i < subcmds->counter_subcmd; ++i) {
04061       const struct pri_subcommand *subcmd = &subcmds->subcmd[i];
04062       if (subcmd->cmd == PRI_SUBCMD_AOC_E) {
04063          return 1;
04064       }
04065    }
04066    return 0;
04067 }
04068 #endif   /* defined(HAVE_PRI_AOC_EVENTS) */
04069 
04070 /*!
04071  * \internal
04072  * \brief Handle the call associated PRI subcommand events.
04073  * \since 1.8
04074  *
04075  * \param pri PRI span control structure.
04076  * \param chanpos Channel position in the span.
04077  * \param event_id PRI event id
04078  * \param channel PRI encoded span/channel
04079  * \param subcmds Subcommands to process if any. (Could be NULL).
04080  * \param call_rsp libpri opaque call structure to send any responses toward.
04081  * Could be NULL either because it is not available or the call is for the
04082  * dummy call reference.  However, this should not be NULL in the cases that
04083  * need to use the pointer to send a response message back.
04084  *
04085  * \note Assumes the pri->lock is already obtained.
04086  * \note Assumes the sig_pri_lock_private(pri->pvts[chanpos]) is already obtained.
04087  *
04088  * \return Nothing
04089  */
04090 static void sig_pri_handle_subcmds(struct sig_pri_span *pri, int chanpos, int event_id,
04091    int channel, const struct pri_subcommands *subcmds, q931_call *call_rsp)
04092 {
04093    int index;
04094    struct ast_channel *owner;
04095    struct ast_party_redirecting ast_redirecting;
04096 #if defined(HAVE_PRI_TRANSFER)
04097    struct xfer_rsp_data xfer_rsp;
04098 #endif   /* defined(HAVE_PRI_TRANSFER) */
04099 
04100    if (!subcmds) {
04101       return;
04102    }
04103    for (index = 0; index < subcmds->counter_subcmd; ++index) {
04104       const struct pri_subcommand *subcmd = &subcmds->subcmd[index];
04105 
04106       switch (subcmd->cmd) {
04107       case PRI_SUBCMD_CONNECTED_LINE:
04108          sig_pri_lock_owner(pri, chanpos);
04109          owner = pri->pvts[chanpos]->owner;
04110          if (owner) {
04111             struct ast_party_connected_line ast_connected;
04112             int caller_id_update;
04113 
04114             /* Extract the connected line information */
04115             ast_party_connected_line_init(&ast_connected);
04116             sig_pri_party_id_convert(&ast_connected.id, &subcmd->u.connected_line.id,
04117                pri);
04118             ast_connected.id.tag = ast_strdup(pri->pvts[chanpos]->user_tag);
04119 
04120             caller_id_update = 0;
04121             if (ast_connected.id.name.str) {
04122                /* Save name for Caller-ID update */
04123                ast_copy_string(pri->pvts[chanpos]->cid_name,
04124                   ast_connected.id.name.str, sizeof(pri->pvts[chanpos]->cid_name));
04125                caller_id_update = 1;
04126             }
04127             if (ast_connected.id.number.str) {
04128                /* Save number for Caller-ID update */
04129                ast_copy_string(pri->pvts[chanpos]->cid_num,
04130                   ast_connected.id.number.str, sizeof(pri->pvts[chanpos]->cid_num));
04131                pri->pvts[chanpos]->cid_ton = ast_connected.id.number.plan;
04132                caller_id_update = 1;
04133             }
04134             ast_connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
04135 
04136             pri->pvts[chanpos]->cid_subaddr[0] = '\0';
04137 #if defined(HAVE_PRI_SUBADDR)
04138             if (ast_connected.id.subaddress.valid) {
04139                ast_party_subaddress_set(&owner->caller.id.subaddress,
04140                   &ast_connected.id.subaddress);
04141                if (ast_connected.id.subaddress.str) {
04142                   ast_copy_string(pri->pvts[chanpos]->cid_subaddr,
04143                      ast_connected.id.subaddress.str,
04144                      sizeof(pri->pvts[chanpos]->cid_subaddr));
04145                }
04146             }
04147 #endif   /* defined(HAVE_PRI_SUBADDR) */
04148             if (caller_id_update) {
04149                struct ast_party_caller ast_caller;
04150 
04151                pri->pvts[chanpos]->callingpres =
04152                   ast_party_id_presentation(&ast_connected.id);
04153                sig_pri_set_caller_id(pri->pvts[chanpos]);
04154 
04155                ast_party_caller_set_init(&ast_caller, &owner->caller);
04156                ast_caller.id = ast_connected.id;
04157                ast_caller.ani = ast_connected.id;
04158                ast_channel_set_caller_event(owner, &ast_caller, NULL);
04159             }
04160 
04161             /* Update the connected line information on the other channel */
04162             if (event_id != PRI_EVENT_RING) {
04163                /* This connected_line update was not from a SETUP message. */
04164                ast_channel_queue_connected_line_update(owner, &ast_connected, NULL);
04165             }
04166 
04167             ast_party_connected_line_free(&ast_connected);
04168             ast_channel_unlock(owner);
04169          }
04170          break;
04171       case PRI_SUBCMD_REDIRECTING:
04172          sig_pri_lock_owner(pri, chanpos);
04173          owner = pri->pvts[chanpos]->owner;
04174          if (owner) {
04175             sig_pri_redirecting_convert(&ast_redirecting, &subcmd->u.redirecting,
04176                &owner->redirecting, pri);
04177             ast_redirecting.from.tag = ast_strdup(pri->pvts[chanpos]->user_tag);
04178             ast_redirecting.to.tag = ast_strdup(pri->pvts[chanpos]->user_tag);
04179 
04180 /*! \todo XXX Original called data can be put in a channel data store that is inherited. */
04181 
04182             ast_channel_set_redirecting(owner, &ast_redirecting, NULL);
04183             if (event_id != PRI_EVENT_RING) {
04184                /* This redirection was not from a SETUP message. */
04185                ast_channel_queue_redirecting_update(owner, &ast_redirecting, NULL);
04186             }
04187             ast_party_redirecting_free(&ast_redirecting);
04188 
04189             ast_channel_unlock(owner);
04190          }
04191          break;
04192 #if defined(HAVE_PRI_CALL_REROUTING)
04193       case PRI_SUBCMD_REROUTING:
04194          sig_pri_lock_owner(pri, chanpos);
04195          owner = pri->pvts[chanpos]->owner;
04196          if (owner) {
04197             struct pri_party_redirecting pri_deflection;
04198 
04199             if (!call_rsp) {
04200                ast_log(LOG_WARNING,
04201                   "Span %d: %s tried CallRerouting/CallDeflection to '%s' without call!\n",
04202                   pri->span, owner->name, subcmd->u.rerouting.deflection.to.number.str);
04203                ast_channel_unlock(owner);
04204                break;
04205             }
04206             if (ast_strlen_zero(subcmd->u.rerouting.deflection.to.number.str)) {
04207                ast_log(LOG_WARNING,
04208                   "Span %d: %s tried CallRerouting/CallDeflection to empty number!\n",
04209                   pri->span, owner->name);
04210                pri_rerouting_rsp(pri->pri, call_rsp, subcmd->u.rerouting.invoke_id,
04211                   PRI_REROUTING_RSP_INVALID_NUMBER);
04212                ast_channel_unlock(owner);
04213                break;
04214             }
04215 
04216             ast_verb(3, "Span %d: %s is CallRerouting/CallDeflection to '%s'.\n",
04217                pri->span, owner->name, subcmd->u.rerouting.deflection.to.number.str);
04218 
04219             /*
04220              * Send back positive ACK to CallRerouting/CallDeflection.
04221              *
04222              * Note:  This call will be hungup by the core when it processes
04223              * the call_forward string.
04224              */
04225             pri_rerouting_rsp(pri->pri, call_rsp, subcmd->u.rerouting.invoke_id,
04226                PRI_REROUTING_RSP_OK_CLEAR);
04227 
04228             pri_deflection = subcmd->u.rerouting.deflection;
04229 
04230             /* Adjust the deflecting to number based upon the subscription option. */
04231             switch (subcmd->u.rerouting.subscription_option) {
04232             case 0:  /* noNotification */
04233             case 1:  /* notificationWithoutDivertedToNr */
04234                /* Delete the number because the far end is not supposed to see it. */
04235                pri_deflection.to.number.presentation =
04236                   PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_UNSCREENED;
04237                pri_deflection.to.number.plan =
04238                   (PRI_TON_UNKNOWN << 4) | PRI_NPI_E163_E164;
04239                pri_deflection.to.number.str[0] = '\0';
04240                break;
04241             case 2:  /* notificationWithDivertedToNr */
04242                break;
04243             case 3:  /* notApplicable */
04244             default:
04245                break;
04246             }
04247             sig_pri_redirecting_convert(&ast_redirecting, &pri_deflection,
04248                &owner->redirecting, pri);
04249             ast_redirecting.from.tag = ast_strdup(pri->pvts[chanpos]->user_tag);
04250             ast_redirecting.to.tag = ast_strdup(pri->pvts[chanpos]->user_tag);
04251             ast_channel_set_redirecting(owner, &ast_redirecting, NULL);
04252             ast_party_redirecting_free(&ast_redirecting);
04253 
04254             /* Request the core to forward to the new number. */
04255             ast_string_field_set(owner, call_forward,
04256                subcmd->u.rerouting.deflection.to.number.str);
04257 
04258             /* Wake up the channel. */
04259             ast_queue_frame(owner, &ast_null_frame);
04260 
04261             ast_channel_unlock(owner);
04262          }
04263          break;
04264 #endif   /* defined(HAVE_PRI_CALL_REROUTING) */
04265 #if defined(HAVE_PRI_CCSS)
04266       case PRI_SUBCMD_CC_AVAILABLE:
04267          sig_pri_lock_owner(pri, chanpos);
04268          owner = pri->pvts[chanpos]->owner;
04269          if (owner) {
04270             enum ast_cc_service_type service;
04271 
04272             switch (event_id) {
04273             case PRI_EVENT_RINGING:
04274                service = AST_CC_CCNR;
04275                break;
04276             case PRI_EVENT_HANGUP_REQ:
04277                /* We will assume that the cause was busy/congestion. */
04278                service = AST_CC_CCBS;
04279                break;
04280             default:
04281                service = AST_CC_NONE;
04282                break;
04283             }
04284             if (service == AST_CC_NONE
04285                || sig_pri_cc_available(pri, chanpos, subcmd->u.cc_available.cc_id,
04286                service)) {
04287                pri_cc_cancel(pri->pri, subcmd->u.cc_available.cc_id);
04288             }
04289             ast_channel_unlock(owner);
04290          } else {
04291             /* No asterisk channel. */
04292             pri_cc_cancel(pri->pri, subcmd->u.cc_available.cc_id);
04293          }
04294          break;
04295 #endif   /* defined(HAVE_PRI_CCSS) */
04296 #if defined(HAVE_PRI_CCSS)
04297       case PRI_SUBCMD_CC_CALL:
04298          sig_pri_lock_owner(pri, chanpos);
04299          owner = pri->pvts[chanpos]->owner;
04300          if (owner) {
04301             struct ast_cc_agent *agent;
04302 
04303             agent = sig_pri_find_cc_agent_by_cc_id(pri, subcmd->u.cc_call.cc_id);
04304             if (agent) {
04305                ast_setup_cc_recall_datastore(owner, agent->core_id);
04306                ast_cc_agent_set_interfaces_chanvar(owner);
04307                ast_cc_agent_recalling(agent->core_id,
04308                   "%s caller is attempting recall", sig_pri_cc_type_name);
04309                ao2_ref(agent, -1);
04310             }
04311 
04312             ast_channel_unlock(owner);
04313          }
04314          break;
04315 #endif   /* defined(HAVE_PRI_CCSS) */
04316 #if defined(HAVE_PRI_CCSS)
04317       case PRI_SUBCMD_CC_CANCEL:
04318          sig_pri_cc_link_canceled(pri, subcmd->u.cc_cancel.cc_id,
04319             subcmd->u.cc_cancel.is_agent);
04320          break;
04321 #endif   /* defined(HAVE_PRI_CCSS) */
04322 #if defined(HAVE_PRI_TRANSFER)
04323       case PRI_SUBCMD_TRANSFER_CALL:
04324          if (!call_rsp) {
04325             /* Should never happen. */
04326             ast_log(LOG_ERROR,
04327                "Call transfer subcommand without call to send response!\n");
04328             break;
04329          }
04330 
04331          sig_pri_unlock_private(pri->pvts[chanpos]);
04332          xfer_rsp.pri = pri;
04333          xfer_rsp.call = call_rsp;
04334          xfer_rsp.invoke_id = subcmd->u.transfer.invoke_id;
04335          sig_pri_attempt_transfer(pri,
04336             subcmd->u.transfer.call_1, subcmd->u.transfer.is_call_1_held,
04337             subcmd->u.transfer.call_2, subcmd->u.transfer.is_call_2_held,
04338             sig_pri_transfer_rsp, &xfer_rsp);
04339          sig_pri_lock_private(pri->pvts[chanpos]);
04340          break;
04341 #endif   /* defined(HAVE_PRI_TRANSFER) */
04342 #if defined(HAVE_PRI_AOC_EVENTS)
04343       case PRI_SUBCMD_AOC_S:
04344          sig_pri_lock_owner(pri, chanpos);
04345          owner = pri->pvts[chanpos]->owner;
04346          if (owner) {
04347             sig_pri_aoc_s_from_pri(&subcmd->u.aoc_s, owner,
04348                (pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_S));
04349             ast_channel_unlock(owner);
04350          }
04351          break;
04352 #endif   /* defined(HAVE_PRI_AOC_EVENTS) */
04353 #if defined(HAVE_PRI_AOC_EVENTS)
04354       case PRI_SUBCMD_AOC_D:
04355          sig_pri_lock_owner(pri, chanpos);
04356          owner = pri->pvts[chanpos]->owner;
04357          if (owner) {
04358             /* Queue AST_CONTROL_AOC frame on channel */
04359             sig_pri_aoc_d_from_pri(&subcmd->u.aoc_d, owner,
04360                (pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_D));
04361             ast_channel_unlock(owner);
04362          }
04363          break;
04364 #endif   /* defined(HAVE_PRI_AOC_EVENTS) */
04365 #if defined(HAVE_PRI_AOC_EVENTS)
04366       case PRI_SUBCMD_AOC_E:
04367          sig_pri_lock_owner(pri, chanpos);
04368          owner = pri->pvts[chanpos]->owner;
04369          /* Queue AST_CONTROL_AOC frame */
04370          sig_pri_aoc_e_from_pri(&subcmd->u.aoc_e, owner,
04371             (pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_E));
04372          if (owner) {
04373             ast_channel_unlock(owner);
04374          }
04375          break;
04376 #endif   /* defined(HAVE_PRI_AOC_EVENTS) */
04377 #if defined(HAVE_PRI_AOC_EVENTS)
04378       case PRI_SUBCMD_AOC_CHARGING_REQ:
04379          sig_pri_lock_owner(pri, chanpos);
04380          owner = pri->pvts[chanpos]->owner;
04381          if (owner) {
04382             sig_pri_aoc_request_from_pri(&subcmd->u.aoc_request, pri->pvts[chanpos],
04383                call_rsp);
04384             ast_channel_unlock(owner);
04385          }
04386          break;
04387 #endif   /* defined(HAVE_PRI_AOC_EVENTS) */
04388 #if defined(HAVE_PRI_AOC_EVENTS)
04389       case PRI_SUBCMD_AOC_CHARGING_REQ_RSP:
04390          /*
04391           * An AOC request response may contain an AOC-S rate list.
04392           * If this is the case handle this just like we
04393           * would an incoming AOC-S msg.
04394           */
04395          if (subcmd->u.aoc_request_response.valid_aoc_s) {
04396             sig_pri_lock_owner(pri, chanpos);
04397             owner = pri->pvts[chanpos]->owner;
04398             if (owner) {
04399                sig_pri_aoc_s_from_pri(&subcmd->u.aoc_request_response.aoc_s, owner,
04400                   (pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_S));
04401                ast_channel_unlock(owner);
04402             }
04403          }
04404          break;
04405 #endif   /* defined(HAVE_PRI_AOC_EVENTS) */
04406 #if defined(HAVE_PRI_MCID)
04407       case PRI_SUBCMD_MCID_REQ:
04408          sig_pri_lock_owner(pri, chanpos);
04409          owner = pri->pvts[chanpos]->owner;
04410          sig_pri_mcid_event(pri, &subcmd->u.mcid_req, owner);
04411          if (owner) {
04412             ast_channel_unlock(owner);
04413          }
04414          break;
04415 #endif   /* defined(HAVE_PRI_MCID) */
04416 #if defined(HAVE_PRI_MCID)
04417       case PRI_SUBCMD_MCID_RSP:
04418          /* Ignore for now. */
04419          break;
04420 #endif   /* defined(HAVE_PRI_MCID) */
04421       default:
04422          ast_debug(2,
04423             "Unknown call subcommand(%d) in %s event on channel %d/%d on span %d.\n",
04424             subcmd->cmd, pri_event2str(event_id), PRI_SPAN(channel),
04425             PRI_CHANNEL(channel), pri->span);
04426          break;
04427       }
04428    }
04429 }
04430 
04431 #if defined(HAVE_PRI_CALL_HOLD)
04432 /*!
04433  * \internal
04434  * \brief Handle the hold event from libpri.
04435  * \since 1.8
04436  *
04437  * \param pri PRI span control structure.
04438  * \param ev Hold event received.
04439  *
04440  * \note Assumes the pri->lock is already obtained.
04441  *
04442  * \retval 0 on success.
04443  * \retval -1 on error.
04444  */
04445 static int sig_pri_handle_hold(struct sig_pri_span *pri, pri_event *ev)
04446 {
04447    int retval;
04448    int chanpos_old;
04449    int chanpos_new;
04450    struct ast_channel *owner;
04451 
04452    chanpos_old = pri_find_principle_by_call(pri, ev->hold.call);
04453    if (chanpos_old < 0) {
04454       ast_log(LOG_WARNING, "Span %d: Received HOLD for unknown call.\n", pri->span);
04455       return -1;
04456    }
04457    if (pri->pvts[chanpos_old]->no_b_channel) {
04458       /* Call is already on hold or is call waiting call. */
04459       return -1;
04460    }
04461 
04462    chanpos_new = -1;
04463 
04464    sig_pri_lock_private(pri->pvts[chanpos_old]);
04465    sig_pri_lock_owner(pri, chanpos_old);
04466    owner = pri->pvts[chanpos_old]->owner;
04467    if (!owner) {
04468       goto done_with_private;
04469    }
04470    if (pri->pvts[chanpos_old]->call_level != SIG_PRI_CALL_LEVEL_CONNECT) {
04471       /*
04472        * Make things simple.  Don't allow placing a call on hold that
04473        * is not connected.
04474        */
04475       goto done_with_owner;
04476    }
04477    chanpos_new = pri_find_empty_nobch(pri);
04478    if (chanpos_new < 0) {
04479       /* No hold channel available. */
04480       goto done_with_owner;
04481    }
04482    sig_pri_handle_subcmds(pri, chanpos_old, ev->e, ev->hold.channel, ev->hold.subcmds,
04483       ev->hold.call);
04484    chanpos_new = pri_fixup_principle(pri, chanpos_new, ev->hold.call);
04485    if (chanpos_new < 0) {
04486       /* Should never happen. */
04487    } else {
04488       struct ast_frame f = { AST_FRAME_CONTROL, };
04489 
04490       /*
04491        * Things are in an odd state here so we cannot use pri_queue_control().
04492        * However, we already have the owner lock so we can simply queue the frame.
04493        */
04494       f.subclass.integer = AST_CONTROL_HOLD;
04495       ast_queue_frame(owner, &f);
04496    }
04497 
04498 done_with_owner:;
04499    ast_channel_unlock(owner);
04500 done_with_private:;
04501    sig_pri_unlock_private(pri->pvts[chanpos_old]);
04502 
04503    if (chanpos_new < 0) {
04504       retval = -1;
04505    } else {
04506       sig_pri_span_devstate_changed(pri);
04507       retval = 0;
04508    }
04509 
04510    return retval;
04511 }
04512 #endif   /* defined(HAVE_PRI_CALL_HOLD) */
04513 
04514 #if defined(HAVE_PRI_CALL_HOLD)
04515 /*!
04516  * \internal
04517  * \brief Handle the retrieve event from libpri.
04518  * \since 1.8
04519  *
04520  * \param pri PRI span control structure.
04521  * \param ev Retrieve event received.
04522  *
04523  * \note Assumes the pri->lock is already obtained.
04524  *
04525  * \return Nothing
04526  */
04527 static void sig_pri_handle_retrieve(struct sig_pri_span *pri, pri_event *ev)
04528 {
04529    int chanpos;
04530 
04531    if (!(ev->retrieve.channel & PRI_HELD_CALL)) {
04532       /* The call is not currently held. */
04533       pri_retrieve_rej(pri->pri, ev->retrieve.call,
04534          PRI_CAUSE_RESOURCE_UNAVAIL_UNSPECIFIED);
04535       return;
04536    }
04537    if (pri_find_principle_by_call(pri, ev->retrieve.call) < 0) {
04538       ast_log(LOG_WARNING, "Span %d: Received RETRIEVE for unknown call.\n", pri->span);
04539       pri_retrieve_rej(pri->pri, ev->retrieve.call,
04540          PRI_CAUSE_RESOURCE_UNAVAIL_UNSPECIFIED);
04541       return;
04542    }
04543    if (PRI_CHANNEL(ev->retrieve.channel) == 0xFF) {
04544       chanpos = pri_find_empty_chan(pri, 1);
04545    } else {
04546       chanpos = pri_find_principle(pri,
04547          ev->retrieve.channel & ~PRI_HELD_CALL, ev->retrieve.call);
04548       if (ev->retrieve.flexible
04549          && (chanpos < 0 || !sig_pri_is_chan_available(pri->pvts[chanpos]))) {
04550          /*
04551           * Channel selection is flexible and the requested channel
04552           * is bad or not available.  Pick another channel.
04553           */
04554          chanpos = pri_find_empty_chan(pri, 1);
04555       }
04556    }
04557    if (chanpos < 0) {
04558       pri_retrieve_rej(pri->pri, ev->retrieve.call,
04559          ev->retrieve.flexible ? PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION
04560          : PRI_CAUSE_REQUESTED_CHAN_UNAVAIL);
04561       return;
04562    }
04563    chanpos = pri_fixup_principle(pri, chanpos, ev->retrieve.call);
04564    if (chanpos < 0) {
04565       /* Channel is already in use. */
04566       pri_retrieve_rej(pri->pri, ev->retrieve.call,
04567          PRI_CAUSE_REQUESTED_CHAN_UNAVAIL);
04568       return;
04569    }
04570    sig_pri_lock_private(pri->pvts[chanpos]);
04571    sig_pri_handle_subcmds(pri, chanpos, ev->e, ev->retrieve.channel,
04572       ev->retrieve.subcmds, ev->retrieve.call);
04573    pri_queue_control(pri, chanpos, AST_CONTROL_UNHOLD);
04574    sig_pri_unlock_private(pri->pvts[chanpos]);
04575    pri_retrieve_ack(pri->pri, ev->retrieve.call,
04576       PVT_TO_CHANNEL(pri->pvts[chanpos]));
04577    sig_pri_span_devstate_changed(pri);
04578 }
04579 #endif   /* defined(HAVE_PRI_CALL_HOLD) */
04580 
04581 static void *pri_dchannel(void *vpri)
04582 {
04583    struct sig_pri_span *pri = vpri;
04584    pri_event *e;
04585    struct pollfd fds[SIG_PRI_NUM_DCHANS];
04586    int res;
04587    int chanpos = 0;
04588    int x;
04589    int law;
04590    struct ast_channel *c;
04591    struct timeval tv, lowest, *next;
04592    int doidling=0;
04593    char *cc;
04594    time_t t;
04595    int i, which=-1;
04596    int numdchans;
04597    pthread_t threadid;
04598    char ani2str[6];
04599    char plancallingnum[AST_MAX_EXTENSION];
04600    char plancallingani[AST_MAX_EXTENSION];
04601    char calledtonstr[10];
04602    struct timeval lastidle = { 0, 0 };
04603    pthread_t p;
04604    struct ast_channel *idle;
04605    char idlen[80];
04606    int nextidle = -1;
04607    int haveidles;
04608    int activeidles;
04609    unsigned int len;
04610 
04611    gettimeofday(&lastidle, NULL);
04612    pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
04613 
04614    if (!ast_strlen_zero(pri->idledial) && !ast_strlen_zero(pri->idleext)) {
04615       /* Need to do idle dialing, check to be sure though */
04616       cc = strchr(pri->idleext, '@');
04617       if (cc) {
04618          *cc = '\0';
04619          cc++;
04620          ast_copy_string(pri->idlecontext, cc, sizeof(pri->idlecontext));
04621 #if 0
04622          /* Extensions may not be loaded yet */
04623          if (!ast_exists_extension(NULL, pri->idlecontext, pri->idleext, 1, NULL))
04624             ast_log(LOG_WARNING, "Extension '%s @ %s' does not exist\n", pri->idleext, pri->idlecontext);
04625          else
04626 #endif
04627             doidling = 1;
04628       } else
04629          ast_log(LOG_WARNING, "Idle dial string '%s' lacks '@context'\n", pri->idleext);
04630    }
04631    for (;;) {
04632       for (i = 0; i < SIG_PRI_NUM_DCHANS; i++) {
04633          if (!pri->dchans[i])
04634             break;
04635          fds[i].fd = pri->fds[i];
04636          fds[i].events = POLLIN | POLLPRI;
04637          fds[i].revents = 0;
04638       }
04639       numdchans = i;
04640       time(&t);
04641       ast_mutex_lock(&pri->lock);
04642       if (pri->switchtype != PRI_SWITCH_GR303_TMC && (pri->sig != SIG_BRI_PTMP) && (pri->resetinterval > 0)) {
04643          if (pri->resetting && pri_is_up(pri)) {
04644             if (pri->resetpos < 0) {
04645                pri_check_restart(pri);
04646                if (pri->resetting) {
04647                   sig_pri_span_devstate_changed(pri);
04648                }
04649             }
04650          } else {
04651             if (!pri->resetting  && (t - pri->lastreset) >= pri->resetinterval) {
04652                pri->resetting = 1;
04653                pri->resetpos = -1;
04654             }
04655          }
04656       }
04657       /* Look for any idle channels if appropriate */
04658       if (doidling && pri_is_up(pri)) {
04659          nextidle = -1;
04660          haveidles = 0;
04661          activeidles = 0;
04662          for (x = pri->numchans; x >= 0; x--) {
04663             if (pri->pvts[x] && !pri->pvts[x]->no_b_channel) {
04664                if (sig_pri_is_chan_available(pri->pvts[x])) {
04665                   if (haveidles < pri->minunused) {
04666                      haveidles++;
04667                   } else {
04668                      nextidle = x;
04669                      break;
04670                   }
04671                } else if (pri->pvts[x]->owner && pri->pvts[x]->isidlecall) {
04672                   activeidles++;
04673                }
04674             }
04675          }
04676          if (nextidle > -1) {
04677             if (ast_tvdiff_ms(ast_tvnow(), lastidle) > 1000) {
04678                /* Don't create a new idle call more than once per second */
04679                snprintf(idlen, sizeof(idlen), "%d/%s", pri->pvts[nextidle]->channel, pri->idledial);
04680                pri->pvts[nextidle]->allocated = 1;
04681                /*
04682                 * Release the PRI lock while we create the channel so other
04683                 * threads can send D channel messages.
04684                 */
04685                ast_mutex_unlock(&pri->lock);
04686                /*
04687                 * We already have the B channel reserved for this call.  We
04688                 * just need to make sure that sig_pri_hangup() has completed
04689                 * cleaning up before continuing.
04690                 */
04691                sig_pri_lock_private(pri->pvts[nextidle]);
04692                sig_pri_unlock_private(pri->pvts[nextidle]);
04693                idle = sig_pri_request(pri->pvts[nextidle], AST_FORMAT_ULAW, NULL, 0);
04694                ast_mutex_lock(&pri->lock);
04695                if (idle) {
04696                   pri->pvts[nextidle]->isidlecall = 1;
04697                   if (ast_pthread_create_background(&p, NULL, do_idle_thread, pri->pvts[nextidle])) {
04698                      ast_log(LOG_WARNING, "Unable to start new thread for idle channel '%s'\n", idle->name);
04699                      ast_mutex_unlock(&pri->lock);
04700                      ast_hangup(idle);
04701                      ast_mutex_lock(&pri->lock);
04702                   }
04703                } else {
04704                   pri->pvts[nextidle]->allocated = 0;
04705                   ast_log(LOG_WARNING, "Unable to request channel 'DAHDI/%s' for idle call\n", idlen);
04706                }
04707                gettimeofday(&lastidle, NULL);
04708             }
04709          } else if ((haveidles < pri->minunused) &&
04710             (activeidles > pri->minidle)) {
04711             /* Mark something for hangup if there is something
04712                that can be hungup */
04713             for (x = pri->numchans; x >= 0; x--) {
04714                /* find a candidate channel */
04715                if (pri->pvts[x] && pri->pvts[x]->owner && pri->pvts[x]->isidlecall) {
04716                   pri->pvts[x]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
04717                   haveidles++;
04718                   /* Stop if we have enough idle channels or
04719                     can't spare any more active idle ones */
04720                   if ((haveidles >= pri->minunused) ||
04721                      (activeidles <= pri->minidle))
04722                      break;
04723                }
04724             }
04725          }
04726       }
04727       /* Start with reasonable max */
04728       if (doidling || pri->resetting) {
04729          /*
04730           * Make sure we stop at least once per second if we're
04731           * monitoring idle channels
04732           */
04733          lowest = ast_tv(1, 0);
04734       } else {
04735          /* Don't poll for more than 60 seconds */
04736          lowest = ast_tv(60, 0);
04737       }
04738       for (i = 0; i < SIG_PRI_NUM_DCHANS; i++) {
04739          if (!pri->dchans[i]) {
04740             /* We scanned all D channels on this span. */
04741             break;
04742          }
04743          next = pri_schedule_next(pri->dchans[i]);
04744          if (next) {
04745             /* We need relative time here */
04746             tv = ast_tvsub(*next, ast_tvnow());
04747             if (tv.tv_sec < 0) {
04748                /*
04749                 * A timer has already expired.
04750                 * By definition zero time is the lowest so we can quit early.
04751                 */
04752                lowest = ast_tv(0, 0);
04753                break;
04754             }
04755             if (ast_tvcmp(tv, lowest) < 0) {
04756                lowest = tv;
04757             }
04758          }
04759       }
04760       ast_mutex_unlock(&pri->lock);
04761 
04762       pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
04763       pthread_testcancel();
04764       e = NULL;
04765       res = poll(fds, numdchans, lowest.tv_sec * 1000 + lowest.tv_usec / 1000);
04766       pthread_testcancel();
04767       pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
04768 
04769       ast_mutex_lock(&pri->lock);
04770       if (!res) {
04771          for (which = 0; which < SIG_PRI_NUM_DCHANS; which++) {
04772             if (!pri->dchans[which])
04773                break;
04774             /* Just a timeout, run the scheduler */
04775             e = pri_schedule_run(pri->dchans[which]);
04776             if (e)
04777                break;
04778          }
04779       } else if (res > -1) {
04780          for (which = 0; which < SIG_PRI_NUM_DCHANS; which++) {
04781             if (!pri->dchans[which])
04782                break;
04783             if (fds[which].revents & POLLPRI) {
04784                sig_pri_handle_dchan_exception(pri, which);
04785             } else if (fds[which].revents & POLLIN) {
04786                e = pri_check_event(pri->dchans[which]);
04787             }
04788             if (e)
04789                break;
04790          }
04791       } else if (errno != EINTR)
04792          ast_log(LOG_WARNING, "pri_event returned error %d (%s)\n", errno, strerror(errno));
04793 
04794       if (e) {
04795          if (pri->debug) {
04796             ast_verbose("Span %d: Processing event %s\n",
04797                pri->span, pri_event2str(e->e));
04798          }
04799 
04800          if (e->e != PRI_EVENT_DCHAN_DOWN) {
04801             if (!(pri->dchanavail[which] & DCHAN_UP)) {
04802                ast_verb(2, "%s D-Channel on span %d up\n", pri_order(which), pri->span);
04803             }
04804             pri->dchanavail[which] |= DCHAN_UP;
04805          } else {
04806             if (pri->dchanavail[which] & DCHAN_UP) {
04807                ast_verb(2, "%s D-Channel on span %d down\n", pri_order(which), pri->span);
04808             }
04809             pri->dchanavail[which] &= ~DCHAN_UP;
04810          }
04811 
04812          if ((e->e != PRI_EVENT_DCHAN_UP) && (e->e != PRI_EVENT_DCHAN_DOWN) && (pri->pri != pri->dchans[which]))
04813             /* Must be an NFAS group that has the secondary dchan active */
04814             pri->pri = pri->dchans[which];
04815 
04816          switch (e->e) {
04817          case PRI_EVENT_DCHAN_UP:
04818             pri->no_d_channels = 0;
04819             if (!pri->pri) {
04820                pri_find_dchan(pri);
04821             }
04822 
04823             /* Note presense of D-channel */
04824             time(&pri->lastreset);
04825 
04826             /* Restart in 5 seconds */
04827             if (pri->resetinterval > -1) {
04828                pri->lastreset -= pri->resetinterval;
04829                pri->lastreset += 5;
04830             }
04831             /* Take the channels from inalarm condition */
04832             pri->resetting = 0;
04833             for (i = 0; i < pri->numchans; i++) {
04834                if (pri->pvts[i]) {
04835                   sig_pri_set_alarm(pri->pvts[i], 0);
04836                }
04837             }
04838             sig_pri_span_devstate_changed(pri);
04839             break;
04840          case PRI_EVENT_DCHAN_DOWN:
04841             pri_find_dchan(pri);
04842             if (!pri_is_up(pri)) {
04843                if (pri->sig == SIG_BRI_PTMP) {
04844                   /*
04845                    * For PTMP connections with non-persistent layer 2 we want to
04846                    * *not* declare inalarm unless there actually is an alarm.
04847                    */
04848                   break;
04849                }
04850                /* Hangup active channels and put them in alarm mode */
04851                pri->resetting = 0;
04852                for (i = 0; i < pri->numchans; i++) {
04853                   struct sig_pri_chan *p = pri->pvts[i];
04854 
04855                   if (p) {
04856                      if (pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0) {
04857                         /* T309 is not enabled : destroy calls when alarm occurs */
04858                         if (p->call) {
04859                            pri_destroycall(p->pri->pri, p->call);
04860                            p->call = NULL;
04861                         }
04862                         if (p->owner)
04863                            p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
04864                      }
04865                      sig_pri_set_alarm(p, 1);
04866                   }
04867                }
04868                sig_pri_span_devstate_changed(pri);
04869             }
04870             break;
04871          case PRI_EVENT_RESTART:
04872             if (e->restart.channel > -1 && PRI_CHANNEL(e->restart.channel) != 0xFF) {
04873                chanpos = pri_find_principle(pri, e->restart.channel, NULL);
04874                if (chanpos < 0)
04875                   ast_log(LOG_WARNING,
04876                      "Span %d: Restart requested on odd/unavailable channel number %d/%d\n",
04877                      pri->span, PRI_SPAN(e->restart.channel),
04878                      PRI_CHANNEL(e->restart.channel));
04879                else {
04880                   int skipit = 0;
04881 #if defined(HAVE_PRI_SERVICE_MESSAGES)
04882                   unsigned why;
04883 
04884                   why = pri->pvts[chanpos]->service_status;
04885                   if (why) {
04886                      ast_log(LOG_NOTICE,
04887                         "Span %d: Channel %d/%d out-of-service (reason: %s), ignoring RESTART\n",
04888                         pri->span, PRI_SPAN(e->restart.channel),
04889                         PRI_CHANNEL(e->restart.channel),
04890                         (why & SRVST_FAREND) ? (why & SRVST_NEAREND) ? "both ends" : "far end" : "near end");
04891                      skipit = 1;
04892                   }
04893 #endif   /* defined(HAVE_PRI_SERVICE_MESSAGES) */
04894                   sig_pri_lock_private(pri->pvts[chanpos]);
04895                   if (!skipit) {
04896                      ast_verb(3, "Span %d: Channel %d/%d restarted\n", pri->span,
04897                         PRI_SPAN(e->restart.channel),
04898                         PRI_CHANNEL(e->restart.channel));
04899                      if (pri->pvts[chanpos]->call) {
04900                         pri_destroycall(pri->pri, pri->pvts[chanpos]->call);
04901                         pri->pvts[chanpos]->call = NULL;
04902                      }
04903                   }
04904                   /* Force soft hangup if appropriate */
04905                   if (pri->pvts[chanpos]->owner)
04906                      pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
04907                   sig_pri_unlock_private(pri->pvts[chanpos]);
04908                }
04909             } else {
04910                ast_verb(3, "Restart requested on entire span %d\n", pri->span);
04911                for (x = 0; x < pri->numchans; x++)
04912                   if (pri->pvts[x]) {
04913                      sig_pri_lock_private(pri->pvts[x]);
04914                      if (pri->pvts[x]->call) {
04915                         pri_destroycall(pri->pri, pri->pvts[x]->call);
04916                         pri->pvts[x]->call = NULL;
04917                      }
04918                      if (pri->pvts[x]->owner)
04919                         pri->pvts[x]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
04920                      sig_pri_unlock_private(pri->pvts[x]);
04921                   }
04922             }
04923             sig_pri_span_devstate_changed(pri);
04924             break;
04925          case PRI_EVENT_KEYPAD_DIGIT:
04926             if (sig_pri_is_cis_call(e->digit.channel)) {
04927                sig_pri_handle_cis_subcmds(pri, e->e, e->digit.subcmds,
04928                   e->digit.call);
04929                break;
04930             }
04931             chanpos = pri_find_principle_by_call(pri, e->digit.call);
04932             if (chanpos < 0) {
04933                ast_log(LOG_WARNING,
04934                   "Span %d: Received keypad digits for unknown call.\n", pri->span);
04935                break;
04936             }
04937             sig_pri_lock_private(pri->pvts[chanpos]);
04938             sig_pri_handle_subcmds(pri, chanpos, e->e, e->digit.channel,
04939                e->digit.subcmds, e->digit.call);
04940             /* queue DTMF frame if the PBX for this call was already started (we're forwarding KEYPAD_DIGITs further on */
04941             if ((pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)
04942                && pri->pvts[chanpos]->owner) {
04943                /* how to do that */
04944                int digitlen = strlen(e->digit.digits);
04945                int i;
04946 
04947                for (i = 0; i < digitlen; i++) {
04948                   struct ast_frame f = { AST_FRAME_DTMF, .subclass.integer = e->digit.digits[i], };
04949 
04950                   pri_queue_frame(pri, chanpos, &f);
04951                }
04952             }
04953             sig_pri_unlock_private(pri->pvts[chanpos]);
04954             break;
04955 
04956          case PRI_EVENT_INFO_RECEIVED:
04957             if (sig_pri_is_cis_call(e->ring.channel)) {
04958                sig_pri_handle_cis_subcmds(pri, e->e, e->ring.subcmds,
04959                   e->ring.call);
04960                break;
04961             }
04962             chanpos = pri_find_principle_by_call(pri, e->ring.call);
04963             if (chanpos < 0) {
04964                ast_log(LOG_WARNING,
04965                   "Span %d: Received INFORMATION for unknown call.\n", pri->span);
04966                break;
04967             }
04968             sig_pri_lock_private(pri->pvts[chanpos]);
04969             sig_pri_handle_subcmds(pri, chanpos, e->e, e->ring.channel,
04970                e->ring.subcmds, e->ring.call);
04971             /* queue DTMF frame if the PBX for this call was already started (we're forwarding INFORMATION further on */
04972             if ((pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)
04973                && pri->pvts[chanpos]->owner) {
04974                /* how to do that */
04975                int digitlen = strlen(e->ring.callednum);
04976                int i;
04977 
04978                for (i = 0; i < digitlen; i++) {
04979                   struct ast_frame f = { AST_FRAME_DTMF, .subclass.integer = e->ring.callednum[i], };
04980 
04981                   pri_queue_frame(pri, chanpos, &f);
04982                }
04983             }
04984             sig_pri_unlock_private(pri->pvts[chanpos]);
04985             break;
04986 #if defined(HAVE_PRI_SERVICE_MESSAGES)
04987          case PRI_EVENT_SERVICE:
04988             chanpos = pri_find_principle(pri, e->service.channel, NULL);
04989             if (chanpos < 0) {
04990                ast_log(LOG_WARNING, "Received service change status %d on unconfigured channel %d/%d span %d\n",
04991                   e->service_ack.changestatus, PRI_SPAN(e->service_ack.channel), PRI_CHANNEL(e->service_ack.channel), pri->span);
04992             } else {
04993                char db_chan_name[20];
04994                char db_answer[5];
04995                int ch;
04996                unsigned *why;
04997 
04998                ch = pri->pvts[chanpos]->channel;
04999                snprintf(db_chan_name, sizeof(db_chan_name), "%s/%d:%d", dahdi_db, pri->span, ch);
05000                why = &pri->pvts[chanpos]->service_status;
05001                switch (e->service.changestatus) {
05002                case 0: /* in-service */
05003                   /* Far end wants to be in service now. */
05004                   ast_db_del(db_chan_name, SRVST_DBKEY);
05005                   *why &= ~SRVST_FAREND;
05006                   if (*why) {
05007                      snprintf(db_answer, sizeof(db_answer), "%s:%u",
05008                         SRVST_TYPE_OOS, *why);
05009                      ast_db_put(db_chan_name, SRVST_DBKEY, db_answer);
05010                   } else {
05011                      sig_pri_span_devstate_changed(pri);
05012                   }
05013                   break;
05014                case 2: /* out-of-service */
05015                   /* Far end wants to be out-of-service now. */
05016                   ast_db_del(db_chan_name, SRVST_DBKEY);
05017                   *why |= SRVST_FAREND;
05018                   snprintf(db_answer, sizeof(db_answer), "%s:%u", SRVST_TYPE_OOS,
05019                      *why);
05020                   ast_db_put(db_chan_name, SRVST_DBKEY, db_answer);
05021                   sig_pri_span_devstate_changed(pri);
05022                   break;
05023                default:
05024                   ast_log(LOG_ERROR, "Huh?  changestatus is: %d\n", e->service.changestatus);
05025                   break;
05026                }
05027                ast_log(LOG_NOTICE, "Channel %d/%d span %d (logical: %d) received a change of service message, status '%d'\n",
05028                   PRI_SPAN(e->service.channel), PRI_CHANNEL(e->service.channel), pri->span, ch, e->service.changestatus);
05029             }
05030             break;
05031          case PRI_EVENT_SERVICE_ACK:
05032             chanpos = pri_find_principle(pri, e->service_ack.channel, NULL);
05033             if (chanpos < 0) {
05034                ast_log(LOG_WARNING, "Received service acknowledge change status '%d' on unconfigured channel %d/%d span %d\n",
05035                   e->service_ack.changestatus, PRI_SPAN(e->service_ack.channel), PRI_CHANNEL(e->service_ack.channel), pri->span);
05036             } else {
05037                ast_debug(2, "Channel %d/%d span %d received a change os service acknowledgement message, status '%d'\n",
05038                   PRI_SPAN(e->service_ack.channel), PRI_CHANNEL(e->service_ack.channel), pri->span, e->service_ack.changestatus);
05039             }
05040             break;
05041 #endif   /* defined(HAVE_PRI_SERVICE_MESSAGES) */
05042          case PRI_EVENT_RING:
05043             if (!ast_strlen_zero(pri->msn_list)
05044                && !sig_pri_msn_match(pri->msn_list, e->ring.callednum)) {
05045                /* The call is not for us so ignore it. */
05046                ast_verb(3,
05047                   "Ignoring call to '%s' on span %d.  Its not in the MSN list: %s\n",
05048                   e->ring.callednum, pri->span, pri->msn_list);
05049                pri_destroycall(pri->pri, e->ring.call);
05050                break;
05051             }
05052             if (sig_pri_is_cis_call(e->ring.channel)) {
05053                sig_pri_handle_cis_subcmds(pri, e->e, e->ring.subcmds,
05054                   e->ring.call);
05055                break;
05056             }
05057             chanpos = pri_find_principle_by_call(pri, e->ring.call);
05058             if (-1 < chanpos) {
05059                /* Libpri has already filtered out duplicate SETUPs. */
05060                ast_log(LOG_WARNING,
05061                   "Span %d: Got SETUP with duplicate call ptr (%p).  Dropping call.\n",
05062                   pri->span, e->ring.call);
05063                pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_NORMAL_TEMPORARY_FAILURE);
05064                break;
05065             }
05066             if (e->ring.channel == -1 || PRI_CHANNEL(e->ring.channel) == 0xFF) {
05067                /* Any channel requested. */
05068                chanpos = pri_find_empty_chan(pri, 1);
05069             } else if (PRI_CHANNEL(e->ring.channel) == 0x00) {
05070                /* No channel specified. */
05071 #if defined(HAVE_PRI_CALL_WAITING)
05072                if (!pri->allow_call_waiting_calls)
05073 #endif   /* defined(HAVE_PRI_CALL_WAITING) */
05074                {
05075                   /* We will not accept incoming call waiting calls. */
05076                   pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION);
05077                   break;
05078                }
05079 #if defined(HAVE_PRI_CALL_WAITING)
05080                chanpos = pri_find_empty_nobch(pri);
05081                if (chanpos < 0) {
05082                   /* We could not find/create a call interface. */
05083                   pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION);
05084                   break;
05085                }
05086                /* Setup the call interface to use. */
05087                sig_pri_init_config(pri->pvts[chanpos], pri);
05088 #endif   /* defined(HAVE_PRI_CALL_WAITING) */
05089             } else {
05090                /* A channel is specified. */
05091                chanpos = pri_find_principle(pri, e->ring.channel, e->ring.call);
05092                if (chanpos < 0) {
05093                   ast_log(LOG_WARNING,
05094                      "Span %d: SETUP on unconfigured channel %d/%d\n",
05095                      pri->span, PRI_SPAN(e->ring.channel),
05096                      PRI_CHANNEL(e->ring.channel));
05097                } else if (!sig_pri_is_chan_available(pri->pvts[chanpos])) {
05098                   /* This is where we handle initial glare */
05099                   ast_debug(1,
05100                      "Span %d: SETUP requested unavailable channel %d/%d.  Attempting to renegotiate.\n",
05101                      pri->span, PRI_SPAN(e->ring.channel),
05102                      PRI_CHANNEL(e->ring.channel));
05103                   chanpos = -1;
05104                }
05105 #if defined(ALWAYS_PICK_CHANNEL)
05106                if (e->ring.flexible) {
05107                   chanpos = -1;
05108                }
05109 #endif   /* defined(ALWAYS_PICK_CHANNEL) */
05110                if (chanpos < 0 && e->ring.flexible) {
05111                   /* We can try to pick another channel. */
05112                   chanpos = pri_find_empty_chan(pri, 1);
05113                }
05114             }
05115             if (chanpos < 0) {
05116                if (e->ring.flexible) {
05117                   pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION);
05118                } else {
05119                   pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_REQUESTED_CHAN_UNAVAIL);
05120                }
05121                break;
05122             }
05123 
05124             sig_pri_lock_private(pri->pvts[chanpos]);
05125 
05126             /* Mark channel as in use so noone else will steal it. */
05127             pri->pvts[chanpos]->call = e->ring.call;
05128 
05129             /* Use plancallingnum as a scratch buffer since it is initialized next. */
05130             apply_plan_to_existing_number(plancallingnum, sizeof(plancallingnum), pri,
05131                e->ring.redirectingnum, e->ring.callingplanrdnis);
05132             sig_pri_set_rdnis(pri->pvts[chanpos], plancallingnum);
05133 
05134             /* Setup caller-id info */
05135             apply_plan_to_existing_number(plancallingnum, sizeof(plancallingnum), pri,
05136                e->ring.callingnum, e->ring.callingplan);
05137             pri->pvts[chanpos]->cid_ani2 = 0;
05138             if (pri->pvts[chanpos]->use_callerid) {
05139                ast_shrink_phone_number(plancallingnum);
05140                ast_copy_string(pri->pvts[chanpos]->cid_num, plancallingnum, sizeof(pri->pvts[chanpos]->cid_num));
05141 #ifdef PRI_ANI
05142                apply_plan_to_existing_number(plancallingani, sizeof(plancallingani),
05143                   pri, e->ring.callingani, e->ring.callingplanani);
05144                ast_shrink_phone_number(plancallingani);
05145                ast_copy_string(pri->pvts[chanpos]->cid_ani, plancallingani,
05146                   sizeof(pri->pvts[chanpos]->cid_ani));
05147 #endif
05148                pri->pvts[chanpos]->cid_subaddr[0] = '\0';
05149 #if defined(HAVE_PRI_SUBADDR)
05150                if (e->ring.calling.subaddress.valid) {
05151                   struct ast_party_subaddress calling_subaddress;
05152 
05153                   ast_party_subaddress_init(&calling_subaddress);
05154                   sig_pri_set_subaddress(&calling_subaddress,
05155                      &e->ring.calling.subaddress);
05156                   if (calling_subaddress.str) {
05157                      ast_copy_string(pri->pvts[chanpos]->cid_subaddr,
05158                         calling_subaddress.str,
05159                         sizeof(pri->pvts[chanpos]->cid_subaddr));
05160                   }
05161                   ast_party_subaddress_free(&calling_subaddress);
05162                }
05163 #endif /* defined(HAVE_PRI_SUBADDR) */
05164                ast_copy_string(pri->pvts[chanpos]->cid_name, e->ring.callingname, sizeof(pri->pvts[chanpos]->cid_name));
05165                pri->pvts[chanpos]->cid_ton = e->ring.callingplan; /* this is the callingplan (TON/NPI), e->ring.callingplan>>4 would be the TON */
05166                pri->pvts[chanpos]->callingpres = e->ring.callingpres;
05167                if (e->ring.ani2 >= 0) {
05168                   pri->pvts[chanpos]->cid_ani2 = e->ring.ani2;
05169                }
05170             } else {
05171                pri->pvts[chanpos]->cid_num[0] = '\0';
05172                pri->pvts[chanpos]->cid_subaddr[0] = '\0';
05173                pri->pvts[chanpos]->cid_ani[0] = '\0';
05174                pri->pvts[chanpos]->cid_name[0] = '\0';
05175                pri->pvts[chanpos]->cid_ton = 0;
05176                pri->pvts[chanpos]->callingpres = 0;
05177             }
05178 
05179             /* Setup the user tag for party id's from this device for this call. */
05180             if (pri->append_msn_to_user_tag) {
05181                snprintf(pri->pvts[chanpos]->user_tag,
05182                   sizeof(pri->pvts[chanpos]->user_tag), "%s_%s",
05183                   pri->initial_user_tag,
05184                   pri->nodetype == PRI_NETWORK
05185                      ? plancallingnum : e->ring.callednum);
05186             } else {
05187                ast_copy_string(pri->pvts[chanpos]->user_tag,
05188                   pri->initial_user_tag, sizeof(pri->pvts[chanpos]->user_tag));
05189             }
05190 
05191             sig_pri_set_caller_id(pri->pvts[chanpos]);
05192 
05193             /* Set DNID on all incoming calls -- even immediate */
05194             sig_pri_set_dnid(pri->pvts[chanpos], e->ring.callednum);
05195 
05196             /* If immediate=yes go to s|1 */
05197             if (pri->pvts[chanpos]->immediate) {
05198                ast_verb(3, "Going to extension s|1 because of immediate=yes\n");
05199                pri->pvts[chanpos]->exten[0] = 's';
05200                pri->pvts[chanpos]->exten[1] = '\0';
05201             }
05202             /* Get called number */
05203             else if (!ast_strlen_zero(e->ring.callednum)) {
05204                ast_copy_string(pri->pvts[chanpos]->exten, e->ring.callednum, sizeof(pri->pvts[chanpos]->exten));
05205             } else if (pri->overlapdial)
05206                pri->pvts[chanpos]->exten[0] = '\0';
05207             else {
05208                /* Some PRI circuits are set up to send _no_ digits.  Handle them as 's'. */
05209                pri->pvts[chanpos]->exten[0] = 's';
05210                pri->pvts[chanpos]->exten[1] = '\0';
05211             }
05212             /* No number yet, but received "sending complete"? */
05213             if (e->ring.complete && (ast_strlen_zero(e->ring.callednum))) {
05214                ast_verb(3, "Going to extension s|1 because of Complete received\n");
05215                pri->pvts[chanpos]->exten[0] = 's';
05216                pri->pvts[chanpos]->exten[1] = '\0';
05217             }
05218 
05219             /* Make sure extension exists (or in overlap dial mode, can exist) */
05220             if (((pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING) && ast_canmatch_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) ||
05221                ast_exists_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) {
05222                /* Select audio companding mode. */
05223                switch (e->ring.layer1) {
05224                case PRI_LAYER_1_ALAW:
05225                   law = SIG_PRI_ALAW;
05226                   break;
05227                case PRI_LAYER_1_ULAW:
05228                   law = SIG_PRI_ULAW;
05229                   break;
05230                default:
05231                   /* This is a data call to us. */
05232                   law = SIG_PRI_DEFLAW;
05233                   break;
05234                }
05235 
05236                if (e->ring.complete || !(pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)) {
05237                   /* Just announce proceeding */
05238                   pri->pvts[chanpos]->call_level = SIG_PRI_CALL_LEVEL_PROCEEDING;
05239                   pri_proceeding(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 0);
05240                } else if (pri->switchtype == PRI_SWITCH_GR303_TMC) {
05241                   pri->pvts[chanpos]->call_level = SIG_PRI_CALL_LEVEL_CONNECT;
05242                   pri_answer(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 1);
05243                } else {
05244                   pri->pvts[chanpos]->call_level = SIG_PRI_CALL_LEVEL_OVERLAP;
05245                   pri_need_more_info(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 1);
05246                }
05247 
05248                /* Start PBX */
05249                if (!e->ring.complete
05250                   && (pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)
05251                   && ast_matchmore_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) {
05252                   /*
05253                    * Release the PRI lock while we create the channel so other
05254                    * threads can send D channel messages.  We must also release
05255                    * the private lock to prevent deadlock while creating the
05256                    * channel.
05257                    */
05258                   sig_pri_unlock_private(pri->pvts[chanpos]);
05259                   ast_mutex_unlock(&pri->lock);
05260                   c = sig_pri_new_ast_channel(pri->pvts[chanpos],
05261                      AST_STATE_RESERVED, law, e->ring.ctype,
05262                      pri->pvts[chanpos]->exten, NULL);
05263                   ast_mutex_lock(&pri->lock);
05264                   sig_pri_lock_private(pri->pvts[chanpos]);
05265                   if (c) {
05266 #if defined(HAVE_PRI_SUBADDR)
05267                      if (e->ring.calling.subaddress.valid) {
05268                         /* Set Calling Subaddress */
05269                         sig_pri_lock_owner(pri, chanpos);
05270                         sig_pri_set_subaddress(
05271                            &pri->pvts[chanpos]->owner->caller.id.subaddress,
05272                            &e->ring.calling.subaddress);
05273                         if (!e->ring.calling.subaddress.type
05274                            && !ast_strlen_zero(
05275                               (char *) e->ring.calling.subaddress.data)) {
05276                            /* NSAP */
05277                            pbx_builtin_setvar_helper(c, "CALLINGSUBADDR",
05278                               (char *) e->ring.calling.subaddress.data);
05279                         }
05280                         ast_channel_unlock(c);
05281                      }
05282                      if (e->ring.called_subaddress.valid) {
05283                         /* Set Called Subaddress */
05284                         sig_pri_lock_owner(pri, chanpos);
05285                         sig_pri_set_subaddress(
05286                            &pri->pvts[chanpos]->owner->dialed.subaddress,
05287                            &e->ring.called_subaddress);
05288                         if (!e->ring.called_subaddress.type
05289                            && !ast_strlen_zero(
05290                               (char *) e->ring.called_subaddress.data)) {
05291                            /* NSAP */
05292                            pbx_builtin_setvar_helper(c, "CALLEDSUBADDR",
05293                               (char *) e->ring.called_subaddress.data);
05294                         }
05295                         ast_channel_unlock(c);
05296                      }
05297 #else
05298                      if (!ast_strlen_zero(e->ring.callingsubaddr)) {
05299                         pbx_builtin_setvar_helper(c, "CALLINGSUBADDR", e->ring.callingsubaddr);
05300                      }
05301 #endif /* !defined(HAVE_PRI_SUBADDR) */
05302                      if (e->ring.ani2 >= 0) {
05303                         snprintf(ani2str, sizeof(ani2str), "%d", e->ring.ani2);
05304                         pbx_builtin_setvar_helper(c, "ANI2", ani2str);
05305                      }
05306 
05307 #ifdef SUPPORT_USERUSER
05308                      if (!ast_strlen_zero(e->ring.useruserinfo)) {
05309                         pbx_builtin_setvar_helper(c, "USERUSERINFO", e->ring.useruserinfo);
05310                      }
05311 #endif
05312 
05313                      snprintf(calledtonstr, sizeof(calledtonstr), "%d", e->ring.calledplan);
05314                      pbx_builtin_setvar_helper(c, "CALLEDTON", calledtonstr);
05315                      if (e->ring.redirectingreason >= 0) {
05316                         /* This is now just a status variable.  Use REDIRECTING() dialplan function. */
05317                         pbx_builtin_setvar_helper(c, "PRIREDIRECTREASON", redirectingreason2str(e->ring.redirectingreason));
05318                      }
05319 #if defined(HAVE_PRI_REVERSE_CHARGE)
05320                      pri->pvts[chanpos]->reverse_charging_indication = e->ring.reversecharge;
05321 #endif
05322 #if defined(HAVE_PRI_SETUP_KEYPAD)
05323                      ast_copy_string(pri->pvts[chanpos]->keypad_digits,
05324                         e->ring.keypad_digits,
05325                         sizeof(pri->pvts[chanpos]->keypad_digits));
05326 #endif   /* defined(HAVE_PRI_SETUP_KEYPAD) */
05327 
05328                      sig_pri_handle_subcmds(pri, chanpos, e->e, e->ring.channel,
05329                         e->ring.subcmds, e->ring.call);
05330 
05331                      if (!pri->pvts[chanpos]->digital
05332                         && !pri->pvts[chanpos]->no_b_channel) {
05333                         /*
05334                          * Call has a channel.
05335                          * Indicate that we are providing dialtone.
05336                          */
05337                         pri->pvts[chanpos]->progress = 1;/* No need to send plain PROGRESS again. */
05338 #ifdef HAVE_PRI_PROG_W_CAUSE
05339                         pri_progress_with_cause(pri->pri, e->ring.call,
05340                            PVT_TO_CHANNEL(pri->pvts[chanpos]), 1, -1);/* no cause at all */
05341 #else
05342                         pri_progress(pri->pri, e->ring.call,
05343                            PVT_TO_CHANNEL(pri->pvts[chanpos]), 1);
05344 #endif
05345                      }
05346                   }
05347                   if (c && !ast_pthread_create_detached(&threadid, NULL, pri_ss_thread, pri->pvts[chanpos])) {
05348                      ast_verb(3, "Accepting overlap call from '%s' to '%s' on channel %d/%d, span %d\n",
05349                         plancallingnum, S_OR(pri->pvts[chanpos]->exten, "<unspecified>"),
05350                         pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
05351                   } else {
05352                      ast_log(LOG_WARNING, "Unable to start PBX on channel %d/%d, span %d\n",
05353                         pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
05354                      if (c) {
05355                         /* Avoid deadlock while destroying channel */
05356                         sig_pri_unlock_private(pri->pvts[chanpos]);
05357                         ast_mutex_unlock(&pri->lock);
05358                         ast_hangup(c);
05359                         ast_mutex_lock(&pri->lock);
05360                      } else {
05361                         pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_SWITCH_CONGESTION);
05362                         pri->pvts[chanpos]->call = NULL;
05363                         sig_pri_unlock_private(pri->pvts[chanpos]);
05364                         sig_pri_span_devstate_changed(pri);
05365                      }
05366                      break;
05367                   }
05368                } else {
05369                   /*
05370                    * Release the PRI lock while we create the channel so other
05371                    * threads can send D channel messages.  We must also release
05372                    * the private lock to prevent deadlock while creating the
05373                    * channel.
05374                    */
05375                   sig_pri_unlock_private(pri->pvts[chanpos]);
05376                   ast_mutex_unlock(&pri->lock);
05377                   c = sig_pri_new_ast_channel(pri->pvts[chanpos],
05378                      AST_STATE_RING, law, e->ring.ctype,
05379                      pri->pvts[chanpos]->exten, NULL);
05380                   ast_mutex_lock(&pri->lock);
05381                   sig_pri_lock_private(pri->pvts[chanpos]);
05382                   if (c) {
05383                      /*
05384                       * It is reasonably safe to set the following
05385                       * channel variables while the PRI and DAHDI private
05386                       * structures are locked.  The PBX has not been
05387                       * started yet and it is unlikely that any other task
05388                       * will do anything with the channel we have just
05389                       * created.
05390                       */
05391 #if defined(HAVE_PRI_SUBADDR)
05392                      if (e->ring.calling.subaddress.valid) {
05393                         /* Set Calling Subaddress */
05394                         sig_pri_lock_owner(pri, chanpos);
05395                         sig_pri_set_subaddress(
05396                            &pri->pvts[chanpos]->owner->caller.id.subaddress,
05397                            &e->ring.calling.subaddress);
05398                         if (!e->ring.calling.subaddress.type
05399                            && !ast_strlen_zero(
05400                               (char *) e->ring.calling.subaddress.data)) {
05401                            /* NSAP */
05402                            pbx_builtin_setvar_helper(c, "CALLINGSUBADDR",
05403                               (char *) e->ring.calling.subaddress.data);
05404                         }
05405                         ast_channel_unlock(c);
05406                      }
05407                      if (e->ring.called_subaddress.valid) {
05408                         /* Set Called Subaddress */
05409                         sig_pri_lock_owner(pri, chanpos);
05410                         sig_pri_set_subaddress(
05411                            &pri->pvts[chanpos]->owner->dialed.subaddress,
05412                            &e->ring.called_subaddress);
05413                         if (!e->ring.called_subaddress.type
05414                            && !ast_strlen_zero(
05415                               (char *) e->ring.called_subaddress.data)) {
05416                            /* NSAP */
05417                            pbx_builtin_setvar_helper(c, "CALLEDSUBADDR",
05418                               (char *) e->ring.called_subaddress.data);
05419                         }
05420                         ast_channel_unlock(c);
05421                      }
05422 #else
05423                      if (!ast_strlen_zero(e->ring.callingsubaddr)) {
05424                         pbx_builtin_setvar_helper(c, "CALLINGSUBADDR", e->ring.callingsubaddr);
05425                      }
05426 #endif /* !defined(HAVE_PRI_SUBADDR) */
05427                      if (e->ring.ani2 >= 0) {
05428                         snprintf(ani2str, sizeof(ani2str), "%d", e->ring.ani2);
05429                         pbx_builtin_setvar_helper(c, "ANI2", ani2str);
05430                      }
05431 
05432 #ifdef SUPPORT_USERUSER
05433                      if (!ast_strlen_zero(e->ring.useruserinfo)) {
05434                         pbx_builtin_setvar_helper(c, "USERUSERINFO", e->ring.useruserinfo);
05435                      }
05436 #endif
05437 
05438                      if (e->ring.redirectingreason >= 0) {
05439                         /* This is now just a status variable.  Use REDIRECTING() dialplan function. */
05440                         pbx_builtin_setvar_helper(c, "PRIREDIRECTREASON", redirectingreason2str(e->ring.redirectingreason));
05441                      }
05442 #if defined(HAVE_PRI_REVERSE_CHARGE)
05443                      pri->pvts[chanpos]->reverse_charging_indication = e->ring.reversecharge;
05444 #endif
05445 #if defined(HAVE_PRI_SETUP_KEYPAD)
05446                      ast_copy_string(pri->pvts[chanpos]->keypad_digits,
05447                         e->ring.keypad_digits,
05448                         sizeof(pri->pvts[chanpos]->keypad_digits));
05449 #endif   /* defined(HAVE_PRI_SETUP_KEYPAD) */
05450 
05451                      snprintf(calledtonstr, sizeof(calledtonstr), "%d", e->ring.calledplan);
05452                      pbx_builtin_setvar_helper(c, "CALLEDTON", calledtonstr);
05453 
05454                      sig_pri_handle_subcmds(pri, chanpos, e->e, e->ring.channel,
05455                         e->ring.subcmds, e->ring.call);
05456 
05457                   }
05458                   if (c && !ast_pbx_start(c)) {
05459                      ast_verb(3, "Accepting call from '%s' to '%s' on channel %d/%d, span %d\n",
05460                         plancallingnum, pri->pvts[chanpos]->exten,
05461                         pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
05462                      sig_pri_set_echocanceller(pri->pvts[chanpos], 1);
05463                   } else {
05464                      ast_log(LOG_WARNING, "Unable to start PBX on channel %d/%d, span %d\n",
05465                         pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
05466                      if (c) {
05467                         /* Avoid deadlock while destroying channel */
05468                         sig_pri_unlock_private(pri->pvts[chanpos]);
05469                         ast_mutex_unlock(&pri->lock);
05470                         ast_hangup(c);
05471                         ast_mutex_lock(&pri->lock);
05472                      } else {
05473                         pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_SWITCH_CONGESTION);
05474                         pri->pvts[chanpos]->call = NULL;
05475                         sig_pri_unlock_private(pri->pvts[chanpos]);
05476                         sig_pri_span_devstate_changed(pri);
05477                      }
05478                      break;
05479                   }
05480                }
05481             } else {
05482                ast_verb(3,
05483                   "Span %d: Extension %s@%s does not exist.  Rejecting call from '%s'.\n",
05484                   pri->span, pri->pvts[chanpos]->exten, pri->pvts[chanpos]->context,
05485                   pri->pvts[chanpos]->cid_num);
05486                pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_UNALLOCATED);
05487                pri->pvts[chanpos]->call = NULL;
05488                pri->pvts[chanpos]->exten[0] = '\0';
05489                sig_pri_unlock_private(pri->pvts[chanpos]);
05490                sig_pri_span_devstate_changed(pri);
05491                break;
05492             }
05493             sig_pri_unlock_private(pri->pvts[chanpos]);
05494             break;
05495          case PRI_EVENT_RINGING:
05496             if (sig_pri_is_cis_call(e->ringing.channel)) {
05497                sig_pri_handle_cis_subcmds(pri, e->e, e->ringing.subcmds,
05498                   e->ringing.call);
05499                break;
05500             }
05501             chanpos = pri_find_fixup_principle(pri, e->ringing.channel,
05502                e->ringing.call);
05503             if (chanpos < 0) {
05504                break;
05505             }
05506             sig_pri_lock_private(pri->pvts[chanpos]);
05507 
05508             sig_pri_handle_subcmds(pri, chanpos, e->e, e->ringing.channel,
05509                e->ringing.subcmds, e->ringing.call);
05510             sig_pri_cc_generic_check(pri, chanpos, AST_CC_CCNR);
05511             sig_pri_set_echocanceller(pri->pvts[chanpos], 1);
05512             sig_pri_lock_owner(pri, chanpos);
05513             if (pri->pvts[chanpos]->owner) {
05514                ast_setstate(pri->pvts[chanpos]->owner, AST_STATE_RINGING);
05515                ast_channel_unlock(pri->pvts[chanpos]->owner);
05516             }
05517             pri_queue_control(pri, chanpos, AST_CONTROL_RINGING);
05518             if (pri->pvts[chanpos]->call_level < SIG_PRI_CALL_LEVEL_ALERTING) {
05519                pri->pvts[chanpos]->call_level = SIG_PRI_CALL_LEVEL_ALERTING;
05520             }
05521 
05522             if (!pri->pvts[chanpos]->progress
05523                && !pri->pvts[chanpos]->no_b_channel
05524 #ifdef PRI_PROGRESS_MASK
05525                && (e->ringing.progressmask
05526                   & (PRI_PROG_CALL_NOT_E2E_ISDN | PRI_PROG_INBAND_AVAILABLE))
05527 #else
05528                && e->ringing.progress == 8
05529 #endif
05530                ) {
05531                /* Bring voice path up */
05532                pri_queue_control(pri, chanpos, AST_CONTROL_PROGRESS);
05533                pri->pvts[chanpos]->progress = 1;
05534                sig_pri_set_dialing(pri->pvts[chanpos], 0);
05535                sig_pri_open_media(pri->pvts[chanpos]);
05536             }
05537 
05538 #ifdef SUPPORT_USERUSER
05539             if (!ast_strlen_zero(e->ringing.useruserinfo)) {
05540                struct ast_channel *owner;
05541 
05542                sig_pri_lock_owner(pri, chanpos);
05543                owner = pri->pvts[chanpos]->owner;
05544                if (owner) {
05545                   pbx_builtin_setvar_helper(owner, "USERUSERINFO",
05546                      e->ringing.useruserinfo);
05547                   ast_channel_unlock(owner);
05548                }
05549             }
05550 #endif
05551 
05552             sig_pri_unlock_private(pri->pvts[chanpos]);
05553             break;
05554          case PRI_EVENT_PROGRESS:
05555             if (sig_pri_is_cis_call(e->proceeding.channel)) {
05556                sig_pri_handle_cis_subcmds(pri, e->e, e->proceeding.subcmds,
05557                   e->proceeding.call);
05558                break;
05559             }
05560             chanpos = pri_find_fixup_principle(pri, e->proceeding.channel,
05561                e->proceeding.call);
05562             if (chanpos < 0) {
05563                break;
05564             }
05565             sig_pri_lock_private(pri->pvts[chanpos]);
05566             sig_pri_handle_subcmds(pri, chanpos, e->e, e->proceeding.channel,
05567                e->proceeding.subcmds, e->proceeding.call);
05568 
05569             if (e->proceeding.cause > -1) {
05570                ast_verb(3, "PROGRESS with cause code %d received\n", e->proceeding.cause);
05571 
05572                /* Work around broken, out of spec USER_BUSY cause in a progress message */
05573                if (e->proceeding.cause == AST_CAUSE_USER_BUSY) {
05574                   if (pri->pvts[chanpos]->owner) {
05575                      ast_verb(3, "PROGRESS with 'user busy' received, signaling AST_CONTROL_BUSY instead of AST_CONTROL_PROGRESS\n");
05576 
05577                      pri->pvts[chanpos]->owner->hangupcause = e->proceeding.cause;
05578                      pri_queue_control(pri, chanpos, AST_CONTROL_BUSY);
05579                   }
05580                }
05581             }
05582 
05583             if (!pri->pvts[chanpos]->progress
05584                && !pri->pvts[chanpos]->no_b_channel
05585 #ifdef PRI_PROGRESS_MASK
05586                && (e->proceeding.progressmask
05587                   & (PRI_PROG_CALL_NOT_E2E_ISDN | PRI_PROG_INBAND_AVAILABLE))
05588 #else
05589                && e->proceeding.progress == 8
05590 #endif
05591                ) {
05592                /* Bring voice path up */
05593                ast_debug(1,
05594                   "Queuing frame from PRI_EVENT_PROGRESS on channel %d/%d span %d\n",
05595                   pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset,
05596                   pri->span);
05597                pri_queue_control(pri, chanpos, AST_CONTROL_PROGRESS);
05598                pri->pvts[chanpos]->progress = 1;
05599                sig_pri_set_dialing(pri->pvts[chanpos], 0);
05600                sig_pri_open_media(pri->pvts[chanpos]);
05601             }
05602             sig_pri_unlock_private(pri->pvts[chanpos]);
05603             break;
05604          case PRI_EVENT_PROCEEDING:
05605             if (sig_pri_is_cis_call(e->proceeding.channel)) {
05606                sig_pri_handle_cis_subcmds(pri, e->e, e->proceeding.subcmds,
05607                   e->proceeding.call);
05608                break;
05609             }
05610             chanpos = pri_find_fixup_principle(pri, e->proceeding.channel,
05611                e->proceeding.call);
05612             if (chanpos < 0) {
05613                break;
05614             }
05615             sig_pri_lock_private(pri->pvts[chanpos]);
05616             sig_pri_handle_subcmds(pri, chanpos, e->e, e->proceeding.channel,
05617                e->proceeding.subcmds, e->proceeding.call);
05618             if (pri->pvts[chanpos]->call_level < SIG_PRI_CALL_LEVEL_PROCEEDING) {
05619                pri->pvts[chanpos]->call_level = SIG_PRI_CALL_LEVEL_PROCEEDING;
05620                ast_debug(1,
05621                   "Queuing frame from PRI_EVENT_PROCEEDING on channel %d/%d span %d\n",
05622                   pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset,
05623                   pri->span);
05624                pri_queue_control(pri, chanpos, AST_CONTROL_PROCEEDING);
05625             }
05626             if (!pri->pvts[chanpos]->progress
05627                && !pri->pvts[chanpos]->no_b_channel
05628 #ifdef PRI_PROGRESS_MASK
05629                && (e->proceeding.progressmask
05630                   & (PRI_PROG_CALL_NOT_E2E_ISDN | PRI_PROG_INBAND_AVAILABLE))
05631 #else
05632                && e->proceeding.progress == 8
05633 #endif
05634                ) {
05635                /* Bring voice path up */
05636                pri_queue_control(pri, chanpos, AST_CONTROL_PROGRESS);
05637                pri->pvts[chanpos]->progress = 1;
05638                sig_pri_open_media(pri->pvts[chanpos]);
05639             }
05640             sig_pri_set_dialing(pri->pvts[chanpos], 0);
05641             sig_pri_unlock_private(pri->pvts[chanpos]);
05642             break;
05643          case PRI_EVENT_FACILITY:
05644             if (!e->facility.call || sig_pri_is_cis_call(e->facility.channel)) {
05645                /* Event came in on the dummy channel or a CIS call. */
05646 #if defined(HAVE_PRI_CALL_REROUTING)
05647                sig_pri_handle_cis_subcmds(pri, e->e, e->facility.subcmds,
05648                   e->facility.subcall);
05649 #else
05650                sig_pri_handle_cis_subcmds(pri, e->e, e->facility.subcmds,
05651                   e->facility.call);
05652 #endif   /* !defined(HAVE_PRI_CALL_REROUTING) */
05653                break;
05654             }
05655             chanpos = pri_find_principle_by_call(pri, e->facility.call);
05656             if (chanpos < 0) {
05657                ast_log(LOG_WARNING, "Span %d: Received facility for unknown call.\n",
05658                   pri->span);
05659                break;
05660             }
05661             sig_pri_lock_private(pri->pvts[chanpos]);
05662 #if defined(HAVE_PRI_CALL_REROUTING)
05663             sig_pri_handle_subcmds(pri, chanpos, e->e, e->facility.channel,
05664                e->facility.subcmds, e->facility.subcall);
05665 #else
05666             sig_pri_handle_subcmds(pri, chanpos, e->e, e->facility.channel,
05667                e->facility.subcmds, e->facility.call);
05668 #endif   /* !defined(HAVE_PRI_CALL_REROUTING) */
05669             sig_pri_unlock_private(pri->pvts[chanpos]);
05670             break;
05671          case PRI_EVENT_ANSWER:
05672             if (sig_pri_is_cis_call(e->answer.channel)) {
05673 #if defined(HAVE_PRI_CALL_WAITING)
05674                /* Call is CIS so do normal CONNECT_ACKNOWLEDGE. */
05675                pri_connect_ack(pri->pri, e->answer.call, 0);
05676 #endif   /* defined(HAVE_PRI_CALL_WAITING) */
05677                sig_pri_handle_cis_subcmds(pri, e->e, e->answer.subcmds,
05678                   e->answer.call);
05679                break;
05680             }
05681             chanpos = pri_find_fixup_principle(pri, e->answer.channel, e->answer.call);
05682             if (chanpos < 0) {
05683                break;
05684             }
05685 #if defined(HAVE_PRI_CALL_WAITING)
05686             if (pri->pvts[chanpos]->is_call_waiting) {
05687                if (pri->pvts[chanpos]->no_b_channel) {
05688                   int new_chanpos;
05689 
05690                   /*
05691                    * Need to find a free channel now or
05692                    * kill the call with PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION.
05693                    */
05694                   new_chanpos = pri_find_empty_chan(pri, 1);
05695                   if (0 <= new_chanpos) {
05696                      new_chanpos = pri_fixup_principle(pri, new_chanpos,
05697                         e->answer.call);
05698                   }
05699                   if (new_chanpos < 0) {
05700                      /*
05701                       * Either no channel was available or someone stole
05702                       * the channel!
05703                       */
05704                      ast_verb(3,
05705                         "Span %d: Channel not available for call waiting call.\n",
05706                         pri->span);
05707                      sig_pri_lock_private(pri->pvts[chanpos]);
05708                      sig_pri_handle_subcmds(pri, chanpos, e->e, e->answer.channel,
05709                         e->answer.subcmds, e->answer.call);
05710                      sig_pri_cc_generic_check(pri, chanpos, AST_CC_CCBS);
05711                      sig_pri_lock_owner(pri, chanpos);
05712                      if (pri->pvts[chanpos]->owner) {
05713                         pri->pvts[chanpos]->owner->hangupcause = PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION;
05714                         switch (pri->pvts[chanpos]->owner->_state) {
05715                         case AST_STATE_BUSY:
05716                         case AST_STATE_UP:
05717                            ast_softhangup_nolock(pri->pvts[chanpos]->owner, AST_SOFTHANGUP_DEV);
05718                            break;
05719                         default:
05720                            pri_queue_control(pri, chanpos, AST_CONTROL_CONGESTION);
05721                            break;
05722                         }
05723                         ast_channel_unlock(pri->pvts[chanpos]->owner);
05724                      } else {
05725                         pri->pvts[chanpos]->is_call_waiting = 0;
05726                         ast_atomic_fetchadd_int(&pri->num_call_waiting_calls, -1);
05727                         pri_hangup(pri->pri, e->answer.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION);
05728                         pri->pvts[chanpos]->call = NULL;
05729                      }
05730                      sig_pri_unlock_private(pri->pvts[chanpos]);
05731                      sig_pri_span_devstate_changed(pri);
05732                      break;
05733                   }
05734                   chanpos = new_chanpos;
05735                }
05736                pri_connect_ack(pri->pri, e->answer.call, PVT_TO_CHANNEL(pri->pvts[chanpos]));
05737                sig_pri_span_devstate_changed(pri);
05738             } else {
05739                /* Call is normal so do normal CONNECT_ACKNOWLEDGE. */
05740                pri_connect_ack(pri->pri, e->answer.call, 0);
05741             }
05742 #endif   /* defined(HAVE_PRI_CALL_WAITING) */
05743             sig_pri_lock_private(pri->pvts[chanpos]);
05744 
05745 #if defined(HAVE_PRI_CALL_WAITING)
05746             if (pri->pvts[chanpos]->is_call_waiting) {
05747                pri->pvts[chanpos]->is_call_waiting = 0;
05748                ast_atomic_fetchadd_int(&pri->num_call_waiting_calls, -1);
05749             }
05750 #endif   /* defined(HAVE_PRI_CALL_WAITING) */
05751             sig_pri_handle_subcmds(pri, chanpos, e->e, e->answer.channel,
05752                e->answer.subcmds, e->answer.call);
05753             if (!ast_strlen_zero(pri->pvts[chanpos]->deferred_digits)) {
05754                /* We have some 'w' deferred digits to dial now. */
05755                ast_verb(3,
05756                   "Span %d: Channel %d/%d dialing deferred digit string: %s\n",
05757                   pri->span, pri->pvts[chanpos]->logicalspan,
05758                   pri->pvts[chanpos]->prioffset,
05759                   pri->pvts[chanpos]->deferred_digits);
05760                if (pri->pvts[chanpos]->call_level < SIG_PRI_CALL_LEVEL_DEFER_DIAL) {
05761                   pri->pvts[chanpos]->call_level = SIG_PRI_CALL_LEVEL_DEFER_DIAL;
05762                }
05763                sig_pri_dial_digits(pri->pvts[chanpos],
05764                   pri->pvts[chanpos]->deferred_digits);
05765             } else {
05766                if (pri->pvts[chanpos]->call_level < SIG_PRI_CALL_LEVEL_CONNECT) {
05767                   pri->pvts[chanpos]->call_level = SIG_PRI_CALL_LEVEL_CONNECT;
05768                }
05769                sig_pri_open_media(pri->pvts[chanpos]);
05770                pri_queue_control(pri, chanpos, AST_CONTROL_ANSWER);
05771                sig_pri_set_dialing(pri->pvts[chanpos], 0);
05772                /* Enable echo cancellation if it's not on already */
05773                sig_pri_set_echocanceller(pri->pvts[chanpos], 1);
05774             }
05775 
05776 #ifdef SUPPORT_USERUSER
05777             if (!ast_strlen_zero(e->answer.useruserinfo)) {
05778                struct ast_channel *owner;
05779 
05780                sig_pri_lock_owner(pri, chanpos);
05781                owner = pri->pvts[chanpos]->owner;
05782                if (owner) {
05783                   pbx_builtin_setvar_helper(owner, "USERUSERINFO",
05784                      e->answer.useruserinfo);
05785                   ast_channel_unlock(owner);
05786                }
05787             }
05788 #endif
05789 
05790             sig_pri_unlock_private(pri->pvts[chanpos]);
05791             break;
05792 #if defined(HAVE_PRI_CALL_WAITING)
05793          case PRI_EVENT_CONNECT_ACK:
05794             if (sig_pri_is_cis_call(e->connect_ack.channel)) {
05795                sig_pri_handle_cis_subcmds(pri, e->e, e->connect_ack.subcmds,
05796                   e->connect_ack.call);
05797                break;
05798             }
05799             chanpos = pri_find_fixup_principle(pri, e->connect_ack.channel,
05800                e->connect_ack.call);
05801             if (chanpos < 0) {
05802                break;
05803             }
05804 
05805             sig_pri_lock_private(pri->pvts[chanpos]);
05806             sig_pri_handle_subcmds(pri, chanpos, e->e, e->connect_ack.channel,
05807                e->connect_ack.subcmds, e->connect_ack.call);
05808             sig_pri_open_media(pri->pvts[chanpos]);
05809             sig_pri_unlock_private(pri->pvts[chanpos]);
05810             sig_pri_span_devstate_changed(pri);
05811             break;
05812 #endif   /* defined(HAVE_PRI_CALL_WAITING) */
05813          case PRI_EVENT_HANGUP:
05814             if (sig_pri_is_cis_call(e->hangup.channel)) {
05815                sig_pri_handle_cis_subcmds(pri, e->e, e->hangup.subcmds,
05816                   e->hangup.call);
05817                pri_hangup(pri->pri, e->hangup.call, e->hangup.cause);
05818                break;
05819             }
05820             chanpos = pri_find_principle_by_call(pri, e->hangup.call);
05821             if (chanpos < 0) {
05822                /*
05823                 * Continue hanging up the call even though
05824                 * we do not remember it (if we ever did).
05825                 */
05826                pri_hangup(pri->pri, e->hangup.call, e->hangup.cause);
05827                break;
05828             }
05829             sig_pri_lock_private(pri->pvts[chanpos]);
05830             sig_pri_handle_subcmds(pri, chanpos, e->e, e->hangup.channel,
05831                e->hangup.subcmds, e->hangup.call);
05832             switch (e->hangup.cause) {
05833             case PRI_CAUSE_INVALID_CALL_REFERENCE:
05834                /*
05835                 * The peer denies the existence of this call so we must
05836                 * continue hanging it up and forget about it.
05837                 */
05838                pri_hangup(pri->pri, e->hangup.call, e->hangup.cause);
05839                pri->pvts[chanpos]->call = NULL;
05840                break;
05841             default:
05842                break;
05843             }
05844             if (!pri->pvts[chanpos]->alreadyhungup) {
05845                /* we're calling here dahdi_hangup so once we get there we need to clear p->call after calling pri_hangup */
05846                pri->pvts[chanpos]->alreadyhungup = 1;
05847                switch (e->hangup.cause) {
05848                case PRI_CAUSE_USER_BUSY:
05849                case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
05850                   sig_pri_cc_generic_check(pri, chanpos, AST_CC_CCBS);
05851                   break;
05852                default:
05853                   break;
05854                }
05855                if (pri->pvts[chanpos]->owner) {
05856                   int do_hangup = 0;
05857 
05858                   /* Queue a BUSY instead of a hangup if our cause is appropriate */
05859                   pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause;
05860                   switch (pri->pvts[chanpos]->owner->_state) {
05861                   case AST_STATE_BUSY:
05862                   case AST_STATE_UP:
05863                      do_hangup = 1;
05864                      break;
05865                   default:
05866                      if (!pri->pvts[chanpos]->outgoing) {
05867                         /*
05868                          * The incoming call leg hung up before getting
05869                          * connected so just hangup the call.
05870                          */
05871                         do_hangup = 1;
05872                         break;
05873                      }
05874                      switch (e->hangup.cause) {
05875                      case PRI_CAUSE_USER_BUSY:
05876                         pri_queue_control(pri, chanpos, AST_CONTROL_BUSY);
05877                         break;
05878                      case PRI_CAUSE_CALL_REJECTED:
05879                      case PRI_CAUSE_NETWORK_OUT_OF_ORDER:
05880                      case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
05881                      case PRI_CAUSE_SWITCH_CONGESTION:
05882                      case PRI_CAUSE_DESTINATION_OUT_OF_ORDER:
05883                      case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE:
05884                         pri_queue_control(pri, chanpos, AST_CONTROL_CONGESTION);
05885                         break;
05886                      default:
05887                         do_hangup = 1;
05888                         break;
05889                      }
05890                      break;
05891                   }
05892 
05893                   if (do_hangup) {
05894 #if defined(HAVE_PRI_AOC_EVENTS)
05895                      if (detect_aoc_e_subcmd(e->hangup.subcmds)) {
05896                         /* If a AOC-E msg was sent during the release, we must use a
05897                          * AST_CONTROL_HANGUP frame to guarantee that frame gets read before hangup */
05898                         pri_queue_control(pri, chanpos, AST_CONTROL_HANGUP);
05899                      } else {
05900                         pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
05901                      }
05902 #else
05903                      pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
05904 #endif   /* defined(HAVE_PRI_AOC_EVENTS) */
05905                   }
05906                } else {
05907                   /*
05908                    * Continue hanging up the call even though
05909                    * we do not have an owner.
05910                    */
05911                   pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause);
05912                   pri->pvts[chanpos]->call = NULL;
05913                }
05914                ast_verb(3, "Span %d: Channel %d/%d got hangup, cause %d\n",
05915                   pri->span, pri->pvts[chanpos]->logicalspan,
05916                   pri->pvts[chanpos]->prioffset, e->hangup.cause);
05917             } else {
05918                /* Continue hanging up the call. */
05919                pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause);
05920                pri->pvts[chanpos]->call = NULL;
05921             }
05922 #if defined(FORCE_RESTART_UNAVAIL_CHANS)
05923             if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL
05924                && pri->sig != SIG_BRI_PTMP && !pri->resetting
05925                && !pri->pvts[chanpos]->resetting) {
05926                ast_verb(3,
05927                   "Span %d: Forcing restart of channel %d/%d since channel reported in use\n",
05928                   pri->span, pri->pvts[chanpos]->logicalspan,
05929                   pri->pvts[chanpos]->prioffset);
05930                pri->pvts[chanpos]->resetting = 1;
05931                pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos]));
05932             }
05933 #endif   /* defined(FORCE_RESTART_UNAVAIL_CHANS) */
05934             if (e->hangup.aoc_units > -1)
05935                ast_verb(3, "Channel %d/%d, span %d received AOC-E charging %d unit%s\n",
05936                   pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s");
05937 
05938 #ifdef SUPPORT_USERUSER
05939             if (!ast_strlen_zero(e->hangup.useruserinfo)) {
05940                struct ast_channel *owner;
05941 
05942                sig_pri_lock_owner(pri, chanpos);
05943                owner = pri->pvts[chanpos]->owner;
05944                if (owner) {
05945                   pbx_builtin_setvar_helper(owner, "USERUSERINFO",
05946                      e->hangup.useruserinfo);
05947                   ast_channel_unlock(owner);
05948                }
05949             }
05950 #endif
05951 
05952             sig_pri_unlock_private(pri->pvts[chanpos]);
05953             sig_pri_span_devstate_changed(pri);
05954             break;
05955          case PRI_EVENT_HANGUP_REQ:
05956             if (sig_pri_is_cis_call(e->hangup.channel)) {
05957                sig_pri_handle_cis_subcmds(pri, e->e, e->hangup.subcmds,
05958                   e->hangup.call);
05959                pri_hangup(pri->pri, e->hangup.call, e->hangup.cause);
05960                break;
05961             }
05962             chanpos = pri_find_principle_by_call(pri, e->hangup.call);
05963             if (chanpos < 0) {
05964                /*
05965                 * Continue hanging up the call even though
05966                 * we do not remember it (if we ever did).
05967                 */
05968                pri_hangup(pri->pri, e->hangup.call, e->hangup.cause);
05969                break;
05970             }
05971             sig_pri_lock_private(pri->pvts[chanpos]);
05972             sig_pri_handle_subcmds(pri, chanpos, e->e, e->hangup.channel,
05973                e->hangup.subcmds, e->hangup.call);
05974 #if defined(HAVE_PRI_CALL_HOLD)
05975             if (e->hangup.call_active && e->hangup.call_held
05976                && pri->hold_disconnect_transfer) {
05977                /* We are to transfer the call instead of simply hanging up. */
05978                sig_pri_unlock_private(pri->pvts[chanpos]);
05979                if (!sig_pri_attempt_transfer(pri, e->hangup.call_held, 1,
05980                   e->hangup.call_active, 0, NULL, NULL)) {
05981                   break;
05982                }
05983                sig_pri_lock_private(pri->pvts[chanpos]);
05984             }
05985 #endif   /* defined(HAVE_PRI_CALL_HOLD) */
05986             switch (e->hangup.cause) {
05987             case PRI_CAUSE_USER_BUSY:
05988             case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
05989                sig_pri_cc_generic_check(pri, chanpos, AST_CC_CCBS);
05990                break;
05991             case PRI_CAUSE_INVALID_CALL_REFERENCE:
05992                /*
05993                 * The peer denies the existence of this call so we must
05994                 * continue hanging it up and forget about it.  We should not
05995                 * get this cause here, but for completeness we will handle it
05996                 * anyway.
05997                 */
05998                pri_hangup(pri->pri, e->hangup.call, e->hangup.cause);
05999                pri->pvts[chanpos]->call = NULL;
06000                break;
06001             default:
06002                break;
06003             }
06004             if (pri->pvts[chanpos]->owner) {
06005                int do_hangup = 0;
06006 
06007                pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause;
06008                switch (pri->pvts[chanpos]->owner->_state) {
06009                case AST_STATE_BUSY:
06010                case AST_STATE_UP:
06011                   do_hangup = 1;
06012                   break;
06013                default:
06014                   if (!pri->pvts[chanpos]->outgoing) {
06015                      /*
06016                       * The incoming call leg hung up before getting
06017                       * connected so just hangup the call.
06018                       */
06019                      do_hangup = 1;
06020                      break;
06021                   }
06022                   switch (e->hangup.cause) {
06023                   case PRI_CAUSE_USER_BUSY:
06024                      pri_queue_control(pri, chanpos, AST_CONTROL_BUSY);
06025                      break;
06026                   case PRI_CAUSE_CALL_REJECTED:
06027                   case PRI_CAUSE_NETWORK_OUT_OF_ORDER:
06028                   case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
06029                   case PRI_CAUSE_SWITCH_CONGESTION:
06030                   case PRI_CAUSE_DESTINATION_OUT_OF_ORDER:
06031                   case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE:
06032                      pri_queue_control(pri, chanpos, AST_CONTROL_CONGESTION);
06033                      break;
06034                   default:
06035                      do_hangup = 1;
06036                      break;
06037                   }
06038                   break;
06039                }
06040 
06041                if (do_hangup) {
06042 #if defined(HAVE_PRI_AOC_EVENTS)
06043                   if (!pri->pvts[chanpos]->holding_aoce
06044                      && pri->aoce_delayhangup
06045                      && ast_bridged_channel(pri->pvts[chanpos]->owner)) {
06046                      sig_pri_send_aoce_termination_request(pri, chanpos,
06047                         pri_get_timer(pri->pri, PRI_TIMER_T305) / 2);
06048                   } else if (detect_aoc_e_subcmd(e->hangup.subcmds)) {
06049                      /* If a AOC-E msg was sent during the Disconnect, we must use a AST_CONTROL_HANGUP frame
06050                       * to guarantee that frame gets read before hangup */
06051                      pri_queue_control(pri, chanpos, AST_CONTROL_HANGUP);
06052                   } else {
06053                      pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
06054                   }
06055 #else
06056                   pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
06057 #endif   /* defined(HAVE_PRI_AOC_EVENTS) */
06058                }
06059                ast_verb(3, "Span %d: Channel %d/%d got hangup request, cause %d\n",
06060                   pri->span, pri->pvts[chanpos]->logicalspan,
06061                   pri->pvts[chanpos]->prioffset, e->hangup.cause);
06062             } else {
06063                /*
06064                 * Continue hanging up the call even though
06065                 * we do not have an owner.
06066                 */
06067                pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause);
06068                pri->pvts[chanpos]->call = NULL;
06069             }
06070 #if defined(FORCE_RESTART_UNAVAIL_CHANS)
06071             if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL
06072                && pri->sig != SIG_BRI_PTMP && !pri->resetting
06073                && !pri->pvts[chanpos]->resetting) {
06074                ast_verb(3,
06075                   "Span %d: Forcing restart of channel %d/%d since channel reported in use\n",
06076                   pri->span, pri->pvts[chanpos]->logicalspan,
06077                   pri->pvts[chanpos]->prioffset);
06078                pri->pvts[chanpos]->resetting = 1;
06079                pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos]));
06080             }
06081 #endif   /* defined(FORCE_RESTART_UNAVAIL_CHANS) */
06082 
06083 #ifdef SUPPORT_USERUSER
06084             if (!ast_strlen_zero(e->hangup.useruserinfo)) {
06085                struct ast_channel *owner;
06086 
06087                sig_pri_lock_owner(pri, chanpos);
06088                owner = pri->pvts[chanpos]->owner;
06089                if (owner) {
06090                   pbx_builtin_setvar_helper(owner, "USERUSERINFO",
06091                      e->hangup.useruserinfo);
06092                   ast_channel_unlock(owner);
06093                }
06094             }
06095 #endif
06096 
06097             sig_pri_unlock_private(pri->pvts[chanpos]);
06098             sig_pri_span_devstate_changed(pri);
06099             break;
06100          case PRI_EVENT_HANGUP_ACK:
06101             if (sig_pri_is_cis_call(e->hangup.channel)) {
06102                sig_pri_handle_cis_subcmds(pri, e->e, e->hangup.subcmds,
06103                   e->hangup.call);
06104                break;
06105             }
06106             chanpos = pri_find_principle_by_call(pri, e->hangup.call);
06107             if (chanpos < 0) {
06108                break;
06109             }
06110             sig_pri_lock_private(pri->pvts[chanpos]);
06111             pri->pvts[chanpos]->call = NULL;
06112             if (pri->pvts[chanpos]->owner) {
06113                ast_verb(3, "Span %d: Channel %d/%d got hangup ACK\n", pri->span,
06114                   pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset);
06115             }
06116 #ifdef SUPPORT_USERUSER
06117             if (!ast_strlen_zero(e->hangup.useruserinfo)) {
06118                struct ast_channel *owner;
06119 
06120                sig_pri_lock_owner(pri, chanpos);
06121                owner = pri->pvts[chanpos]->owner;
06122                if (owner) {
06123                   pbx_builtin_setvar_helper(owner, "USERUSERINFO",
06124                      e->hangup.useruserinfo);
06125                   ast_channel_unlock(owner);
06126                }
06127             }
06128 #endif
06129             sig_pri_unlock_private(pri->pvts[chanpos]);
06130             sig_pri_span_devstate_changed(pri);
06131             break;
06132          case PRI_EVENT_CONFIG_ERR:
06133             ast_log(LOG_WARNING, "PRI Error on span %d: %s\n", pri->span, e->err.err);
06134             break;
06135          case PRI_EVENT_RESTART_ACK:
06136             chanpos = pri_find_principle(pri, e->restartack.channel, NULL);
06137             if (chanpos < 0) {
06138                /* Sometime switches (e.g. I421 / British Telecom) don't give us the
06139                   channel number, so we have to figure it out...  This must be why
06140                   everybody resets exactly a channel at a time. */
06141                for (x = 0; x < pri->numchans; x++) {
06142                   if (pri->pvts[x] && pri->pvts[x]->resetting) {
06143                      chanpos = x;
06144                      sig_pri_lock_private(pri->pvts[chanpos]);
06145                      ast_debug(1,
06146                         "Span %d: Assuming restart ack is for channel %d/%d\n",
06147                         pri->span, pri->pvts[chanpos]->logicalspan,
06148                         pri->pvts[chanpos]->prioffset);
06149                      if (pri->pvts[chanpos]->owner) {
06150                         ast_log(LOG_WARNING,
06151                            "Span %d: Got restart ack on channel %d/%d with owner\n",
06152                            pri->span, pri->pvts[chanpos]->logicalspan,
06153                            pri->pvts[chanpos]->prioffset);
06154                         pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
06155                      }
06156                      pri->pvts[chanpos]->resetting = 0;
06157                      ast_verb(3,
06158                         "Span %d: Channel %d/%d successfully restarted\n",
06159                         pri->span, pri->pvts[chanpos]->logicalspan,
06160                         pri->pvts[chanpos]->prioffset);
06161                      sig_pri_unlock_private(pri->pvts[chanpos]);
06162                      if (pri->resetting)
06163                         pri_check_restart(pri);
06164                      break;
06165                   }
06166                }
06167                if (chanpos < 0) {
06168                   ast_log(LOG_WARNING,
06169                      "Span %d: Restart ACK on strange channel %d/%d\n",
06170                      pri->span, PRI_SPAN(e->restartack.channel),
06171                      PRI_CHANNEL(e->restartack.channel));
06172                }
06173             } else {
06174                sig_pri_lock_private(pri->pvts[chanpos]);
06175                if (pri->pvts[chanpos]->owner) {
06176                   ast_log(LOG_WARNING,
06177                      "Span %d: Got restart ack on channel %d/%d with owner\n",
06178                      pri->span, pri->pvts[chanpos]->logicalspan,
06179                      pri->pvts[chanpos]->prioffset);
06180                   pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
06181                }
06182                pri->pvts[chanpos]->resetting = 0;
06183                ast_verb(3,
06184                   "Span %d: Channel %d/%d successfully restarted\n",
06185                   pri->span, pri->pvts[chanpos]->logicalspan,
06186                   pri->pvts[chanpos]->prioffset);
06187                sig_pri_unlock_private(pri->pvts[chanpos]);
06188                if (pri->resetting)
06189                   pri_check_restart(pri);
06190             }
06191             break;
06192          case PRI_EVENT_SETUP_ACK:
06193             if (sig_pri_is_cis_call(e->setup_ack.channel)) {
06194                sig_pri_handle_cis_subcmds(pri, e->e, e->setup_ack.subcmds,
06195                   e->setup_ack.call);
06196                break;
06197             }
06198             chanpos = pri_find_fixup_principle(pri, e->setup_ack.channel,
06199                e->setup_ack.call);
06200             if (chanpos < 0) {
06201                break;
06202             }
06203             sig_pri_lock_private(pri->pvts[chanpos]);
06204             sig_pri_handle_subcmds(pri, chanpos, e->e, e->setup_ack.channel,
06205                e->setup_ack.subcmds, e->setup_ack.call);
06206             if (pri->pvts[chanpos]->call_level < SIG_PRI_CALL_LEVEL_OVERLAP) {
06207                pri->pvts[chanpos]->call_level = SIG_PRI_CALL_LEVEL_OVERLAP;
06208             }
06209 
06210             /* Send any queued digits */
06211             len = strlen(pri->pvts[chanpos]->dialdest);
06212             for (x = 0; x < len; ++x) {
06213                ast_debug(1, "Sending pending digit '%c'\n", pri->pvts[chanpos]->dialdest[x]);
06214                pri_information(pri->pri, pri->pvts[chanpos]->call,
06215                   pri->pvts[chanpos]->dialdest[x]);
06216             }
06217 
06218             if (!pri->pvts[chanpos]->progress
06219                && (pri->overlapdial & DAHDI_OVERLAPDIAL_OUTGOING)
06220                && !pri->pvts[chanpos]->digital
06221                && !pri->pvts[chanpos]->no_b_channel) {
06222                /*
06223                 * Call has a channel.
06224                 * Indicate for overlap dialing that dialtone may be present.
06225                 */
06226                pri_queue_control(pri, chanpos, AST_CONTROL_PROGRESS);
06227                pri->pvts[chanpos]->progress = 1;/* Claim to have seen inband-information */
06228                sig_pri_set_dialing(pri->pvts[chanpos], 0);
06229                sig_pri_open_media(pri->pvts[chanpos]);
06230             }
06231             sig_pri_unlock_private(pri->pvts[chanpos]);
06232             break;
06233          case PRI_EVENT_NOTIFY:
06234             if (sig_pri_is_cis_call(e->notify.channel)) {
06235 #if defined(HAVE_PRI_CALL_HOLD)
06236                sig_pri_handle_cis_subcmds(pri, e->e, e->notify.subcmds,
06237                   e->notify.call);
06238 #else
06239                sig_pri_handle_cis_subcmds(pri, e->e, e->notify.subcmds, NULL);
06240 #endif   /* !defined(HAVE_PRI_CALL_HOLD) */
06241                break;
06242             }
06243 #if defined(HAVE_PRI_CALL_HOLD)
06244             chanpos = pri_find_principle_by_call(pri, e->notify.call);
06245             if (chanpos < 0) {
06246                ast_log(LOG_WARNING, "Span %d: Received NOTIFY for unknown call.\n",
06247                   pri->span);
06248                break;
06249             }
06250 #else
06251             /*
06252              * This version of libpri does not supply a call pointer for
06253              * this message.  We are just going to have to trust that the
06254              * correct principle is found.
06255              */
06256             chanpos = pri_find_principle(pri, e->notify.channel, NULL);
06257             if (chanpos < 0) {
06258                ast_log(LOG_WARNING, "Received NOTIFY on unconfigured channel %d/%d span %d\n",
06259                   PRI_SPAN(e->notify.channel), PRI_CHANNEL(e->notify.channel), pri->span);
06260                break;
06261             }
06262 #endif   /* !defined(HAVE_PRI_CALL_HOLD) */
06263             sig_pri_lock_private(pri->pvts[chanpos]);
06264 #if defined(HAVE_PRI_CALL_HOLD)
06265             sig_pri_handle_subcmds(pri, chanpos, e->e, e->notify.channel,
06266                e->notify.subcmds, e->notify.call);
06267 #else
06268             sig_pri_handle_subcmds(pri, chanpos, e->e, e->notify.channel,
06269                e->notify.subcmds, NULL);
06270 #endif   /* !defined(HAVE_PRI_CALL_HOLD) */
06271             switch (e->notify.info) {
06272             case PRI_NOTIFY_REMOTE_HOLD:
06273                if (!pri->discardremoteholdretrieval) {
06274                   pri_queue_control(pri, chanpos, AST_CONTROL_HOLD);
06275                }
06276                break;
06277             case PRI_NOTIFY_REMOTE_RETRIEVAL:
06278                if (!pri->discardremoteholdretrieval) {
06279                   pri_queue_control(pri, chanpos, AST_CONTROL_UNHOLD);
06280                }
06281                break;
06282             }
06283             sig_pri_unlock_private(pri->pvts[chanpos]);
06284             break;
06285 #if defined(HAVE_PRI_CALL_HOLD)
06286          case PRI_EVENT_HOLD:
06287             /* We should not be getting any CIS calls with this message type. */
06288             if (sig_pri_handle_hold(pri, e)) {
06289                pri_hold_rej(pri->pri, e->hold.call,
06290                   PRI_CAUSE_RESOURCE_UNAVAIL_UNSPECIFIED);
06291             } else {
06292                pri_hold_ack(pri->pri, e->hold.call);
06293             }
06294             break;
06295 #endif   /* defined(HAVE_PRI_CALL_HOLD) */
06296 #if defined(HAVE_PRI_CALL_HOLD)
06297          case PRI_EVENT_HOLD_ACK:
06298             ast_debug(1, "Event: HOLD_ACK\n");
06299             break;
06300 #endif   /* defined(HAVE_PRI_CALL_HOLD) */
06301 #if defined(HAVE_PRI_CALL_HOLD)
06302          case PRI_EVENT_HOLD_REJ:
06303             ast_debug(1, "Event: HOLD_REJ\n");
06304             break;
06305 #endif   /* defined(HAVE_PRI_CALL_HOLD) */
06306 #if defined(HAVE_PRI_CALL_HOLD)
06307          case PRI_EVENT_RETRIEVE:
06308             /* We should not be getting any CIS calls with this message type. */
06309             sig_pri_handle_retrieve(pri, e);
06310             break;
06311 #endif   /* defined(HAVE_PRI_CALL_HOLD) */
06312 #if defined(HAVE_PRI_CALL_HOLD)
06313          case PRI_EVENT_RETRIEVE_ACK:
06314             ast_debug(1, "Event: RETRIEVE_ACK\n");
06315             break;
06316 #endif   /* defined(HAVE_PRI_CALL_HOLD) */
06317 #if defined(HAVE_PRI_CALL_HOLD)
06318          case PRI_EVENT_RETRIEVE_REJ:
06319             ast_debug(1, "Event: RETRIEVE_REJ\n");
06320             break;
06321 #endif   /* defined(HAVE_PRI_CALL_HOLD) */
06322          default:
06323             ast_debug(1, "Event: %d\n", e->e);
06324             break;
06325          }
06326       }
06327       ast_mutex_unlock(&pri->lock);
06328    }
06329    /* Never reached */
06330    return NULL;
06331 }
06332 
06333 void sig_pri_init_pri(struct sig_pri_span *pri)
06334 {
06335    int i;
06336 
06337    memset(pri, 0, sizeof(*pri));
06338 
06339    ast_mutex_init(&pri->lock);
06340 
06341    pri->master = AST_PTHREADT_NULL;
06342    for (i = 0; i < SIG_PRI_NUM_DCHANS; i++)
06343       pri->fds[i] = -1;
06344 }
06345 
06346 int sig_pri_hangup(struct sig_pri_chan *p, struct ast_channel *ast)
06347 {
06348    ast_debug(1, "%s %d\n", __FUNCTION__, p->channel);
06349    if (!ast->tech_pvt) {
06350       ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
06351       return 0;
06352    }
06353 
06354    sig_pri_set_outgoing(p, 0);
06355    sig_pri_set_digital(p, 0); /* push up to parent for EC*/
06356 #if defined(HAVE_PRI_CALL_WAITING)
06357    if (p->is_call_waiting) {
06358       p->is_call_waiting = 0;
06359       ast_atomic_fetchadd_int(&p->pri->num_call_waiting_calls, -1);
06360    }
06361 #endif   /* defined(HAVE_PRI_CALL_WAITING) */
06362    p->call_level = SIG_PRI_CALL_LEVEL_IDLE;
06363    p->progress = 0;
06364    p->cid_num[0] = '\0';
06365    p->cid_subaddr[0] = '\0';
06366    p->cid_name[0] = '\0';
06367    p->user_tag[0] = '\0';
06368    p->exten[0] = '\0';
06369    sig_pri_set_dialing(p, 0);
06370 
06371    /* Make sure we really have a call */
06372    pri_grab(p, p->pri);
06373    if (p->call) {
06374 #if defined(SUPPORT_USERUSER)
06375       const char *useruser = pbx_builtin_getvar_helper(ast, "USERUSERINFO");
06376 
06377       if (!ast_strlen_zero(useruser)) {
06378          pri_call_set_useruser(p->call, useruser);
06379       }
06380 #endif   /* defined(SUPPORT_USERUSER) */
06381 
06382 #if defined(HAVE_PRI_AOC_EVENTS)
06383       if (p->holding_aoce) {
06384          pri_aoc_e_send(p->pri->pri, p->call, &p->aoc_e);
06385       }
06386 #endif   /* defined(HAVE_PRI_AOC_EVENTS) */
06387 
06388       if (p->alreadyhungup) {
06389          ast_debug(1, "Already hungup...  Calling hangup once, and clearing call\n");
06390 
06391          pri_hangup(p->pri->pri, p->call, -1);
06392          p->call = NULL;
06393       } else {
06394          const char *cause = pbx_builtin_getvar_helper(ast,"PRI_CAUSE");
06395          int icause = ast->hangupcause ? ast->hangupcause : -1;
06396 
06397          p->alreadyhungup = 1;
06398          if (!ast_strlen_zero(cause)) {
06399             if (atoi(cause)) {
06400                icause = atoi(cause);
06401             }
06402          }
06403          ast_debug(1,
06404             "Not yet hungup...  Calling hangup with cause %d, and clearing call\n",
06405             icause);
06406 
06407          pri_hangup(p->pri->pri, p->call, icause);
06408       }
06409    }
06410 #if defined(HAVE_PRI_AOC_EVENTS)
06411    p->aoc_s_request_invoke_id_valid = 0;
06412    p->holding_aoce = 0;
06413    p->waiting_for_aoce = 0;
06414 #endif   /* defined(HAVE_PRI_AOC_EVENTS) */
06415 
06416    p->allocated = 0;
06417    p->owner = NULL;
06418 
06419    sig_pri_span_devstate_changed(p->pri);
06420    pri_rel(p->pri);
06421    return 0;
06422 }
06423 
06424 /*!
06425  * \brief Extract the called number and subaddress from the dial string.
06426  * \since 1.8
06427  *
06428  * \param p sig_pri channel structure.
06429  * \param rdest Dial string buffer to extract called number and subaddress.
06430  * \param called Buffer to fill with extracted <number>[:<subaddress>]
06431  * \param called_buff_size Size of buffer to fill.
06432  *
06433  * \note Parsing must remain in sync with sig_pri_call().
06434  *
06435  * \return Nothing
06436  */
06437 void sig_pri_extract_called_num_subaddr(struct sig_pri_chan *p, const char *rdest, char *called, size_t called_buff_size)
06438 {
06439    char *dial;
06440    char *number;
06441    char *subaddr;
06442    AST_DECLARE_APP_ARGS(args,
06443       AST_APP_ARG(group);  /* channel/group token */
06444       AST_APP_ARG(ext); /* extension token */
06445       //AST_APP_ARG(opts); /* options token */
06446       AST_APP_ARG(other);  /* Any remining unused arguments */
06447    );
06448 
06449    /* Get private copy of dial string and break it up. */
06450    dial = ast_strdupa(rdest);
06451    AST_NONSTANDARD_APP_ARGS(args, dial, '/');
06452 
06453    number = args.ext;
06454    if (!number) {
06455       number = "";
06456    }
06457 
06458    /* Find and extract dialed_subaddress */
06459    subaddr = strchr(number, ':');
06460    if (subaddr) {
06461       *subaddr++ = '\0';
06462 
06463       /* Skip subaddress type prefix. */
06464       switch (*subaddr) {
06465       case 'U':
06466       case 'u':
06467       case 'N':
06468       case 'n':
06469          ++subaddr;
06470          break;
06471       default:
06472          break;
06473       }
06474    }
06475 
06476    /* Skip type-of-number/dial-plan prefix characters. */
06477    if (strlen(number) < p->stripmsd) {
06478       number = "";
06479    } else {
06480       char *deferred;
06481 
06482       number += p->stripmsd;
06483       deferred = strchr(number, 'w');
06484       if (deferred) {
06485          /* Remove any 'w' deferred digits. */
06486          *deferred = '\0';
06487       }
06488       while (isalpha(*number)) {
06489          ++number;
06490       }
06491    }
06492 
06493    /* Fill buffer with extracted number and subaddress. */
06494    if (ast_strlen_zero(subaddr)) {
06495       /* Put in called number only since there is no subaddress. */
06496       snprintf(called, called_buff_size, "%s", number);
06497    } else {
06498       /* Put in called number and subaddress. */
06499       snprintf(called, called_buff_size, "%s:%s", number, subaddr);
06500    }
06501 }
06502 
06503 enum SIG_PRI_CALL_OPT_FLAGS {
06504    OPT_KEYPAD =         (1 << 0),
06505    OPT_REVERSE_CHARGE = (1 << 1),   /* Collect call */
06506    OPT_AOC_REQUEST =    (1 << 2),   /* AOC Request */
06507 };
06508 enum SIG_PRI_CALL_OPT_ARGS {
06509    OPT_ARG_KEYPAD = 0,
06510    OPT_ARG_AOC_REQUEST,
06511 
06512    /* note: this entry _MUST_ be the last one in the enum */
06513    OPT_ARG_ARRAY_SIZE,
06514 };
06515 
06516 AST_APP_OPTIONS(sig_pri_call_opts, BEGIN_OPTIONS
06517    AST_APP_OPTION_ARG('K', OPT_KEYPAD, OPT_ARG_KEYPAD),
06518    AST_APP_OPTION('R', OPT_REVERSE_CHARGE),
06519    AST_APP_OPTION_ARG('A', OPT_AOC_REQUEST, OPT_ARG_AOC_REQUEST),
06520 END_OPTIONS);
06521 
06522 /*! \note Parsing must remain in sync with sig_pri_extract_called_num_subaddr(). */
06523 int sig_pri_call(struct sig_pri_chan *p, struct ast_channel *ast, char *rdest, int timeout, int layer1)
06524 {
06525    char dest[256]; /* must be same length as p->dialdest */
06526    struct ast_party_subaddress dialed_subaddress; /* Called subaddress */
06527    struct pri_sr *sr;
06528    char *c, *l, *n, *s;
06529 #ifdef SUPPORT_USERUSER
06530    const char *useruser;
06531 #endif
06532    int core_id;
06533    int pridialplan;
06534    int dp_strip;
06535    int prilocaldialplan;
06536    int ldp_strip;
06537    int exclusive;
06538 #if defined(HAVE_PRI_SETUP_KEYPAD)
06539    const char *keypad;
06540 #endif   /* defined(HAVE_PRI_SETUP_KEYPAD) */
06541    AST_DECLARE_APP_ARGS(args,
06542       AST_APP_ARG(group);  /* channel/group token */
06543       AST_APP_ARG(ext); /* extension token */
06544       AST_APP_ARG(opts);   /* options token */
06545       AST_APP_ARG(other);  /* Any remining unused arguments */
06546    );
06547    struct ast_flags opts;
06548    char *opt_args[OPT_ARG_ARRAY_SIZE];
06549 
06550    ast_log(LOG_DEBUG, "CALLER NAME: %s NUM: %s\n",
06551       S_COR(ast->connected.id.name.valid, ast->connected.id.name.str, ""),
06552       S_COR(ast->connected.id.number.valid, ast->connected.id.number.str, ""));
06553 
06554    if (!p->pri) {
06555       ast_log(LOG_ERROR, "Could not find pri on channel %d\n", p->channel);
06556       return -1;
06557    }
06558 
06559    if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
06560       ast_log(LOG_WARNING, "sig_pri_call called on %s, neither down nor reserved\n", ast->name);
06561       return -1;
06562    }
06563 
06564    p->dialdest[0] = '\0';
06565    sig_pri_set_outgoing(p, 1);
06566 
06567    ast_copy_string(dest, rdest, sizeof(dest));
06568    AST_NONSTANDARD_APP_ARGS(args, dest, '/');
06569    if (ast_app_parse_options(sig_pri_call_opts, &opts, opt_args, args.opts)) {
06570       /* General invalid option syntax. */
06571       return -1;
06572    }
06573 
06574    c = args.ext;
06575    if (!c) {
06576       c = "";
06577    }
06578 
06579    /* setup dialed_subaddress if found */
06580    ast_party_subaddress_init(&dialed_subaddress);
06581    s = strchr(c, ':');
06582    if (s) {
06583       *s = '\0';
06584       s++;
06585       /* prefix */
06586       /* 'n' = NSAP */
06587       /* 'u' = User Specified */
06588       /* Default = NSAP */
06589       switch (*s) {
06590       case 'U':
06591       case 'u':
06592          s++;
06593          dialed_subaddress.type = 2;
06594          break;
06595       case 'N':
06596       case 'n':
06597          s++;
06598          /* default already covered with ast_party_subaddress_init */
06599          break;
06600       }
06601       dialed_subaddress.str = s;
06602       dialed_subaddress.valid = 1;
06603    }
06604 
06605    l = NULL;
06606    n = NULL;
06607    if (!p->hidecallerid) {
06608       if (ast->connected.id.number.valid) {
06609          /* If we get to the end of this loop without breaking, there's no
06610           * calleridnum.  This is done instead of testing for "unknown" or
06611           * the thousands of other ways that the calleridnum could be
06612           * invalid. */
06613          for (l = ast->connected.id.number.str; l && *l; l++) {
06614             if (strchr("0123456789", *l)) {
06615                l = ast->connected.id.number.str;
06616                break;
06617             }
06618          }
06619       } else {
06620          l = NULL;
06621       }
06622       if (!p->hidecalleridname) {
06623          n = ast->connected.id.name.valid ? ast->connected.id.name.str : NULL;
06624       }
06625    }
06626 
06627    if (strlen(c) < p->stripmsd) {
06628       ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
06629       return -1;
06630    }
06631 
06632    /* Extract any 'w' deferred digits. */
06633    s = strchr(c + p->stripmsd, 'w');
06634    if (s) {
06635       *s++ = '\0';
06636       ast_copy_string(p->deferred_digits, s, sizeof(p->deferred_digits));
06637       /*
06638        * Since we have a 'w', this means that there will not be any
06639        * more normal dialed digits.  Therefore, the sending complete
06640        * ie needs to be sent with any normal digits.
06641        */
06642    } else {
06643       p->deferred_digits[0] = '\0';
06644    }
06645 
06646    pri_grab(p, p->pri);
06647    if (!(p->call = pri_new_call(p->pri->pri))) {
06648       ast_log(LOG_WARNING, "Unable to create call on channel %d\n", p->channel);
06649       pri_rel(p->pri);
06650       return -1;
06651    }
06652    if (!(sr = pri_sr_new())) {
06653       ast_log(LOG_WARNING, "Failed to allocate setup request on channel %d\n",
06654          p->channel);
06655       pri_destroycall(p->pri->pri, p->call);
06656       p->call = NULL;
06657       pri_rel(p->pri);
06658       return -1;
06659    }
06660 
06661    sig_pri_set_digital(p, IS_DIGITAL(ast->transfercapability));   /* push up to parent for EC */
06662 
06663 #if defined(HAVE_PRI_CALL_WAITING)
06664    if (p->is_call_waiting) {
06665       /*
06666        * Indicate that this is a call waiting call.
06667        * i.e., Normal call but with no B channel.
06668        */
06669       pri_sr_set_channel(sr, 0, 0, 1);
06670    } else
06671 #endif   /* defined(HAVE_PRI_CALL_WAITING) */
06672    {
06673       /* Should the picked channel be used exclusively? */
06674       if (p->priexclusive || p->pri->nodetype == PRI_NETWORK) {
06675          exclusive = 1;
06676       } else {
06677          exclusive = 0;
06678       }
06679       pri_sr_set_channel(sr, PVT_TO_CHANNEL(p), exclusive, 1);
06680    }
06681 
06682    pri_sr_set_bearer(sr, p->digital ? PRI_TRANS_CAP_DIGITAL : ast->transfercapability,
06683       (p->digital ? -1 : layer1));
06684 
06685    if (p->pri->facilityenable)
06686       pri_facility_enable(p->pri->pri);
06687 
06688    ast_verb(3, "Requested transfer capability: 0x%.2x - %s\n", ast->transfercapability, ast_transfercapability2str(ast->transfercapability));
06689    dp_strip = 0;
06690    pridialplan = p->pri->dialplan - 1;
06691    if (pridialplan == -2 || pridialplan == -3) { /* compute dynamically */
06692       if (strncmp(c + p->stripmsd, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) {
06693          if (pridialplan == -2) {
06694             dp_strip = strlen(p->pri->internationalprefix);
06695          }
06696          pridialplan = PRI_INTERNATIONAL_ISDN;
06697       } else if (strncmp(c + p->stripmsd, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) {
06698          if (pridialplan == -2) {
06699             dp_strip = strlen(p->pri->nationalprefix);
06700          }
06701          pridialplan = PRI_NATIONAL_ISDN;
06702       } else {
06703          pridialplan = PRI_LOCAL_ISDN;
06704       }
06705    }
06706    while (c[p->stripmsd] > '9' && c[p->stripmsd] != '*' && c[p->stripmsd] != '#') {
06707       switch (c[p->stripmsd]) {
06708       case 'U':
06709          pridialplan = (PRI_TON_UNKNOWN << 4) | (pridialplan & 0xf);
06710          break;
06711       case 'I':
06712          pridialplan = (PRI_TON_INTERNATIONAL << 4) | (pridialplan & 0xf);
06713          break;
06714       case 'N':
06715          pridialplan = (PRI_TON_NATIONAL << 4) | (pridialplan & 0xf);
06716          break;
06717       case 'L':
06718          pridialplan = (PRI_TON_NET_SPECIFIC << 4) | (pridialplan & 0xf);
06719          break;
06720       case 'S':
06721          pridialplan = (PRI_TON_SUBSCRIBER << 4) | (pridialplan & 0xf);
06722          break;
06723       case 'V':
06724          pridialplan = (PRI_TON_ABBREVIATED << 4) | (pridialplan & 0xf);
06725          break;
06726       case 'R':
06727          pridialplan = (PRI_TON_RESERVED << 4) | (pridialplan & 0xf);
06728          break;
06729       case 'u':
06730          pridialplan = PRI_NPI_UNKNOWN | (pridialplan & 0xf0);
06731          break;
06732       case 'e':
06733          pridialplan = PRI_NPI_E163_E164 | (pridialplan & 0xf0);
06734          break;
06735       case 'x':
06736          pridialplan = PRI_NPI_X121 | (pridialplan & 0xf0);
06737          break;
06738       case 'f':
06739          pridialplan = PRI_NPI_F69 | (pridialplan & 0xf0);
06740          break;
06741       case 'n':
06742          pridialplan = PRI_NPI_NATIONAL | (pridialplan & 0xf0);
06743          break;
06744       case 'p':
06745          pridialplan = PRI_NPI_PRIVATE | (pridialplan & 0xf0);
06746          break;
06747       case 'r':
06748          pridialplan = PRI_NPI_RESERVED | (pridialplan & 0xf0);
06749          break;
06750       default:
06751          if (isalpha(c[p->stripmsd])) {
06752             ast_log(LOG_WARNING, "Unrecognized pridialplan %s modifier: %c\n",
06753                c[p->stripmsd] > 'Z' ? "NPI" : "TON", c[p->stripmsd]);
06754          }
06755          break;
06756       }
06757       c++;
06758    }
06759 #if defined(HAVE_PRI_SETUP_KEYPAD)
06760    if (ast_test_flag(&opts, OPT_KEYPAD)
06761       && !ast_strlen_zero(opt_args[OPT_ARG_KEYPAD])) {
06762       /* We have a keypad facility digits option with digits. */
06763       keypad = opt_args[OPT_ARG_KEYPAD];
06764       pri_sr_set_keypad_digits(sr, keypad);
06765    } else {
06766       keypad = NULL;
06767    }
06768    if (!keypad || !ast_strlen_zero(c + p->stripmsd + dp_strip))
06769 #endif   /* defined(HAVE_PRI_SETUP_KEYPAD) */
06770    {
06771       pri_sr_set_called(sr, c + p->stripmsd + dp_strip, pridialplan, s ? 1 : 0);
06772    }
06773 
06774 #if defined(HAVE_PRI_SUBADDR)
06775    if (dialed_subaddress.valid) {
06776       struct pri_party_subaddress subaddress;
06777 
06778       memset(&subaddress, 0, sizeof(subaddress));
06779       sig_pri_party_subaddress_from_ast(&subaddress, &dialed_subaddress);
06780       pri_sr_set_called_subaddress(sr, &subaddress);
06781    }
06782 #endif   /* defined(HAVE_PRI_SUBADDR) */
06783 #if defined(HAVE_PRI_REVERSE_CHARGE)
06784    if (ast_test_flag(&opts, OPT_REVERSE_CHARGE)) {
06785       pri_sr_set_reversecharge(sr, PRI_REVERSECHARGE_REQUESTED);
06786    }
06787 #endif   /* defined(HAVE_PRI_REVERSE_CHARGE) */
06788 #if defined(HAVE_PRI_AOC_EVENTS)
06789    if (ast_test_flag(&opts, OPT_AOC_REQUEST)
06790       && !ast_strlen_zero(opt_args[OPT_ARG_AOC_REQUEST])) {
06791       if (strchr(opt_args[OPT_ARG_AOC_REQUEST], 's')) {
06792          pri_sr_set_aoc_charging_request(sr, PRI_AOC_REQUEST_S);
06793       }
06794       if (strchr(opt_args[OPT_ARG_AOC_REQUEST], 'd')) {
06795          pri_sr_set_aoc_charging_request(sr, PRI_AOC_REQUEST_D);
06796       }
06797       if (strchr(opt_args[OPT_ARG_AOC_REQUEST], 'e')) {
06798          pri_sr_set_aoc_charging_request(sr, PRI_AOC_REQUEST_E);
06799       }
06800    }
06801 #endif   /* defined(HAVE_PRI_AOC_EVENTS) */
06802 
06803    /* Setup the user tag for party id's from this device for this call. */
06804    if (p->pri->append_msn_to_user_tag) {
06805       snprintf(p->user_tag, sizeof(p->user_tag), "%s_%s", p->pri->initial_user_tag,
06806          p->pri->nodetype == PRI_NETWORK
06807             ? c + p->stripmsd + dp_strip
06808             : S_COR(ast->connected.id.number.valid,
06809                ast->connected.id.number.str, ""));
06810    } else {
06811       ast_copy_string(p->user_tag, p->pri->initial_user_tag, sizeof(p->user_tag));
06812    }
06813 
06814    /*
06815     * Replace the caller id tag from the channel creation
06816     * with the actual tag value.
06817     */
06818    ast_free(ast->caller.id.tag);
06819    ast->caller.id.tag = ast_strdup(p->user_tag);
06820 
06821    ldp_strip = 0;
06822    prilocaldialplan = p->pri->localdialplan - 1;
06823    if ((l != NULL) && (prilocaldialplan == -2 || prilocaldialplan == -3)) { /* compute dynamically */
06824       if (strncmp(l, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) {
06825          if (prilocaldialplan == -2) {
06826             ldp_strip = strlen(p->pri->internationalprefix);
06827          }
06828          prilocaldialplan = PRI_INTERNATIONAL_ISDN;
06829       } else if (strncmp(l, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) {
06830          if (prilocaldialplan == -2) {
06831             ldp_strip = strlen(p->pri->nationalprefix);
06832          }
06833          prilocaldialplan = PRI_NATIONAL_ISDN;
06834       } else {
06835          prilocaldialplan = PRI_LOCAL_ISDN;
06836       }
06837    }
06838    if (l != NULL) {
06839       while (*l > '9' && *l != '*' && *l != '#') {
06840          switch (*l) {
06841          case 'U':
06842             prilocaldialplan = (PRI_TON_UNKNOWN << 4) | (prilocaldialplan & 0xf);
06843             break;
06844          case 'I':
06845             prilocaldialplan = (PRI_TON_INTERNATIONAL << 4) | (prilocaldialplan & 0xf);
06846             break;
06847          case 'N':
06848             prilocaldialplan = (PRI_TON_NATIONAL << 4) | (prilocaldialplan & 0xf);
06849             break;
06850          case 'L':
06851             prilocaldialplan = (PRI_TON_NET_SPECIFIC << 4) | (prilocaldialplan & 0xf);
06852             break;
06853          case 'S':
06854             prilocaldialplan = (PRI_TON_SUBSCRIBER << 4) | (prilocaldialplan & 0xf);
06855             break;
06856          case 'V':
06857             prilocaldialplan = (PRI_TON_ABBREVIATED << 4) | (prilocaldialplan & 0xf);
06858             break;
06859          case 'R':
06860             prilocaldialplan = (PRI_TON_RESERVED << 4) | (prilocaldialplan & 0xf);
06861             break;
06862          case 'u':
06863             prilocaldialplan = PRI_NPI_UNKNOWN | (prilocaldialplan & 0xf0);
06864             break;
06865          case 'e':
06866             prilocaldialplan = PRI_NPI_E163_E164 | (prilocaldialplan & 0xf0);
06867             break;
06868          case 'x':
06869             prilocaldialplan = PRI_NPI_X121 | (prilocaldialplan & 0xf0);
06870             break;
06871          case 'f':
06872             prilocaldialplan = PRI_NPI_F69 | (prilocaldialplan & 0xf0);
06873             break;
06874          case 'n':
06875             prilocaldialplan = PRI_NPI_NATIONAL | (prilocaldialplan & 0xf0);
06876             break;
06877          case 'p':
06878             prilocaldialplan = PRI_NPI_PRIVATE | (prilocaldialplan & 0xf0);
06879             break;
06880          case 'r':
06881             prilocaldialplan = PRI_NPI_RESERVED | (prilocaldialplan & 0xf0);
06882             break;
06883          default:
06884             if (isalpha(*l)) {
06885                ast_log(LOG_WARNING,
06886                   "Unrecognized prilocaldialplan %s modifier: %c\n",
06887                   *l > 'Z' ? "NPI" : "TON", *l);
06888             }
06889             break;
06890          }
06891          l++;
06892       }
06893    }
06894    pri_sr_set_caller(sr, l ? (l + ldp_strip) : NULL, n, prilocaldialplan,
06895       p->use_callingpres ? ast->connected.id.number.presentation : (l ? PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN : PRES_NUMBER_NOT_AVAILABLE));
06896 
06897 #if defined(HAVE_PRI_SUBADDR)
06898    if (ast->connected.id.subaddress.valid) {
06899       struct pri_party_subaddress subaddress;
06900 
06901       memset(&subaddress, 0, sizeof(subaddress));
06902       sig_pri_party_subaddress_from_ast(&subaddress, &ast->connected.id.subaddress);
06903       pri_sr_set_caller_subaddress(sr, &subaddress);
06904    }
06905 #endif   /* defined(HAVE_PRI_SUBADDR) */
06906 
06907    sig_pri_redirecting_update(p, ast);
06908 
06909 #ifdef SUPPORT_USERUSER
06910    /* User-user info */
06911    useruser = pbx_builtin_getvar_helper(p->owner, "USERUSERINFO");
06912    if (useruser)
06913       pri_sr_set_useruser(sr, useruser);
06914 #endif
06915 
06916 #if defined(HAVE_PRI_CCSS)
06917    if (ast_cc_is_recall(ast, &core_id, sig_pri_cc_type_name)) {
06918       struct ast_cc_monitor *monitor;
06919       char device_name[AST_CHANNEL_NAME];
06920 
06921       /* This is a CC recall call. */
06922       ast_channel_get_device_name(ast, device_name, sizeof(device_name));
06923       monitor = ast_cc_get_monitor_by_recall_core_id(core_id, device_name);
06924       if (monitor) {
06925          struct sig_pri_cc_monitor_instance *instance;
06926 
06927          instance = monitor->private_data;
06928 
06929          /* If this fails then we have monitor instance ambiguity. */
06930          ast_assert(p->pri == instance->pri);
06931 
06932          if (pri_cc_call(p->pri->pri, instance->cc_id, p->call, sr)) {
06933             /* The CC recall call failed for some reason. */
06934             ast_log(LOG_WARNING, "Unable to setup CC recall call to device %s\n",
06935                device_name);
06936             ao2_ref(monitor, -1);
06937             pri_destroycall(p->pri->pri, p->call);
06938             p->call = NULL;
06939             pri_rel(p->pri);
06940             pri_sr_free(sr);
06941             return -1;
06942          }
06943          ao2_ref(monitor, -1);
06944       } else {
06945          core_id = -1;
06946       }
06947    } else
06948 #endif   /* defined(HAVE_PRI_CCSS) */
06949    {
06950       core_id = -1;
06951    }
06952    if (core_id == -1 && pri_setup(p->pri->pri, p->call, sr)) {
06953       ast_log(LOG_WARNING, "Unable to setup call to %s (using %s)\n",
06954          c + p->stripmsd + dp_strip, dialplan2str(p->pri->dialplan));
06955       pri_destroycall(p->pri->pri, p->call);
06956       p->call = NULL;
06957       pri_rel(p->pri);
06958       pri_sr_free(sr);
06959       return -1;
06960    }
06961    p->call_level = SIG_PRI_CALL_LEVEL_SETUP;
06962    pri_sr_free(sr);
06963    ast_setstate(ast, AST_STATE_DIALING);
06964    sig_pri_set_dialing(p, 1);
06965    pri_rel(p->pri);
06966    return 0;
06967 }
06968 
06969 int sig_pri_indicate(struct sig_pri_chan *p, struct ast_channel *chan, int condition, const void *data, size_t datalen)
06970 {
06971    int res = -1;
06972 
06973    switch (condition) {
06974    case AST_CONTROL_BUSY:
06975       if (p->priindication_oob || p->no_b_channel) {
06976          chan->hangupcause = AST_CAUSE_USER_BUSY;
06977          chan->_softhangup |= AST_SOFTHANGUP_DEV;
06978          res = 0;
06979          break;
06980       }
06981       res = sig_pri_play_tone(p, SIG_PRI_TONE_BUSY);
06982       if (p->call_level < SIG_PRI_CALL_LEVEL_ALERTING && !p->outgoing) {
06983          chan->hangupcause = AST_CAUSE_USER_BUSY;
06984          p->progress = 1;/* No need to send plain PROGRESS after this. */
06985          if (p->pri && p->pri->pri) {
06986             pri_grab(p, p->pri);
06987 #ifdef HAVE_PRI_PROG_W_CAUSE
06988             pri_progress_with_cause(p->pri->pri, p->call, PVT_TO_CHANNEL(p), 1, chan->hangupcause);
06989 #else
06990             pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
06991 #endif
06992             pri_rel(p->pri);
06993          }
06994       }
06995       break;
06996    case AST_CONTROL_RINGING:
06997       if (p->call_level < SIG_PRI_CALL_LEVEL_ALERTING && !p->outgoing) {
06998          p->call_level = SIG_PRI_CALL_LEVEL_ALERTING;
06999          if (p->pri && p->pri->pri) {
07000             pri_grab(p, p->pri);
07001             pri_acknowledge(p->pri->pri,p->call, PVT_TO_CHANNEL(p),
07002                p->no_b_channel || p->digital ? 0 : 1);
07003             pri_rel(p->pri);
07004          }
07005       }
07006       res = sig_pri_play_tone(p, SIG_PRI_TONE_RINGTONE);
07007       if (chan->_state != AST_STATE_UP) {
07008          if (chan->_state != AST_STATE_RING)
07009             ast_setstate(chan, AST_STATE_RINGING);
07010       }
07011       break;
07012    case AST_CONTROL_PROCEEDING:
07013       ast_debug(1,"Received AST_CONTROL_PROCEEDING on %s\n",chan->name);
07014       if (p->call_level < SIG_PRI_CALL_LEVEL_PROCEEDING && !p->outgoing) {
07015          p->call_level = SIG_PRI_CALL_LEVEL_PROCEEDING;
07016          if (p->pri && p->pri->pri) {
07017             pri_grab(p, p->pri);
07018             pri_proceeding(p->pri->pri,p->call, PVT_TO_CHANNEL(p),
07019                p->no_b_channel || p->digital ? 0 : 1);
07020             if (!p->no_b_channel && !p->digital) {
07021                sig_pri_set_dialing(p, 0);
07022             }
07023             pri_rel(p->pri);
07024          }
07025       }
07026       /* don't continue in ast_indicate */
07027       res = 0;
07028       break;
07029    case AST_CONTROL_PROGRESS:
07030       ast_debug(1,"Received AST_CONTROL_PROGRESS on %s\n",chan->name);
07031       sig_pri_set_digital(p, 0); /* Digital-only calls isn't allowing any inband progress messages */
07032       if (!p->progress && p->call_level < SIG_PRI_CALL_LEVEL_ALERTING && !p->outgoing
07033          && !p->no_b_channel) {
07034          p->progress = 1;/* No need to send plain PROGRESS again. */
07035          if (p->pri && p->pri->pri) {
07036             pri_grab(p, p->pri);
07037 #ifdef HAVE_PRI_PROG_W_CAUSE
07038             pri_progress_with_cause(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1, -1);  /* no cause at all */
07039 #else
07040             pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
07041 #endif
07042             pri_rel(p->pri);
07043          }
07044       }
07045       /* don't continue in ast_indicate */
07046       res = 0;
07047       break;
07048    case AST_CONTROL_INCOMPLETE:
07049       /* If we are connected or if we support overlap dialing, wait for additional digits */
07050       if (p->call_level == SIG_PRI_CALL_LEVEL_CONNECT || (p->pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)) {
07051          res = 0;
07052          break;
07053       }
07054       /* Otherwise, treat as congestion */
07055       chan->hangupcause = AST_CAUSE_INVALID_NUMBER_FORMAT;
07056       /* Falls through */
07057    case AST_CONTROL_CONGESTION:
07058       if (p->priindication_oob || p->no_b_channel) {
07059          /* There are many cause codes that generate an AST_CONTROL_CONGESTION. */
07060          switch (chan->hangupcause) {
07061          case AST_CAUSE_USER_BUSY:
07062          case AST_CAUSE_NORMAL_CLEARING:
07063          case 0:/* Cause has not been set. */
07064             /* Supply a more appropriate cause. */
07065             chan->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
07066             break;
07067          default:
07068             break;
07069          }
07070          chan->_softhangup |= AST_SOFTHANGUP_DEV;
07071          res = 0;
07072          break;
07073       }
07074       res = sig_pri_play_tone(p, SIG_PRI_TONE_CONGESTION);
07075       if (p->call_level < SIG_PRI_CALL_LEVEL_ALERTING && !p->outgoing) {
07076          /* There are many cause codes that generate an AST_CONTROL_CONGESTION. */
07077          switch (chan->hangupcause) {
07078          case AST_CAUSE_USER_BUSY:
07079          case AST_CAUSE_NORMAL_CLEARING:
07080          case 0:/* Cause has not been set. */
07081             /* Supply a more appropriate cause. */
07082             chan->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
07083             break;
07084          default:
07085             break;
07086          }
07087          p->progress = 1;/* No need to send plain PROGRESS after this. */
07088          if (p->pri && p->pri->pri) {
07089             pri_grab(p, p->pri);
07090 #ifdef HAVE_PRI_PROG_W_CAUSE
07091             pri_progress_with_cause(p->pri->pri, p->call, PVT_TO_CHANNEL(p), 1, chan->hangupcause);
07092 #else
07093             pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
07094 #endif
07095             pri_rel(p->pri);
07096          }
07097       }
07098       break;
07099    case AST_CONTROL_HOLD:
07100       if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) {
07101          pri_grab(p, p->pri);
07102          res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_HOLD);
07103          pri_rel(p->pri);
07104       } else
07105          ast_moh_start(chan, data, p->mohinterpret);
07106       break;
07107    case AST_CONTROL_UNHOLD:
07108       if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) {
07109          pri_grab(p, p->pri);
07110          res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_RETRIEVAL);
07111          pri_rel(p->pri);
07112       } else
07113          ast_moh_stop(chan);
07114       break;
07115    case AST_CONTROL_SRCUPDATE:
07116       res = 0;
07117       break;
07118    case -1:
07119       res = sig_pri_play_tone(p, -1);
07120       break;
07121    case AST_CONTROL_CONNECTED_LINE:
07122       ast_debug(1, "Received AST_CONTROL_CONNECTED_LINE on %s\n", chan->name);
07123       if (p->pri) {
07124          struct pri_party_connected_line connected;
07125 
07126          pri_grab(p, p->pri);
07127          memset(&connected, 0, sizeof(connected));
07128          sig_pri_party_id_from_ast(&connected.id, &chan->connected.id);
07129 
07130          pri_connected_line_update(p->pri->pri, p->call, &connected);
07131          pri_rel(p->pri);
07132       }
07133       break;
07134    case AST_CONTROL_REDIRECTING:
07135       ast_debug(1, "Received AST_CONTROL_REDIRECTING on %s\n", chan->name);
07136       if (p->pri) {
07137          pri_grab(p, p->pri);
07138          sig_pri_redirecting_update(p, chan);
07139          pri_rel(p->pri);
07140       }
07141       break;
07142    case AST_CONTROL_AOC:
07143 #if defined(HAVE_PRI_AOC_EVENTS)
07144       {
07145          struct ast_aoc_decoded *decoded
07146             = ast_aoc_decode((struct ast_aoc_encoded *) data, datalen, chan);
07147          ast_debug(1, "Received AST_CONTROL_AOC on %s\n", chan->name);
07148          if (decoded && p->pri) {
07149             pri_grab(p, p->pri);
07150             switch (ast_aoc_get_msg_type(decoded)) {
07151             case AST_AOC_S:
07152                if (p->pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_S) {
07153                   sig_pri_aoc_s_from_ast(p, decoded);
07154                }
07155                break;
07156             case AST_AOC_D:
07157                if (p->pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_D) {
07158                   sig_pri_aoc_d_from_ast(p, decoded);
07159                }
07160                break;
07161             case AST_AOC_E:
07162                if (p->pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_E) {
07163                   sig_pri_aoc_e_from_ast(p, decoded);
07164                }
07165                /* if hangup was delayed for this AOC-E msg, waiting_for_aoc
07166                 * will be set.  A hangup is already occuring via a timeout during
07167                 * this delay.  Instead of waiting for that timeout to occur, go ahead
07168                 * and initiate the softhangup since the delay is no longer necessary */
07169                if (p->waiting_for_aoce) {
07170                   p->waiting_for_aoce = 0;
07171                   ast_log(LOG_DEBUG,
07172                      "Received final AOC-E msg, continue with hangup on %s\n",
07173                      chan->name);
07174                   ast_softhangup_nolock(chan, AST_SOFTHANGUP_DEV);
07175                }
07176                break;
07177             case AST_AOC_REQUEST:
07178                /* We do not pass through AOC requests, So unless this
07179                 * is an AOC termination request it will be ignored */
07180                if (ast_aoc_get_termination_request(decoded)) {
07181                   pri_hangup(p->pri->pri, p->call, -1);
07182                }
07183                break;
07184             default:
07185                break;
07186             }
07187             pri_rel(p->pri);
07188          }
07189          ast_aoc_destroy_decoded(decoded);
07190       }
07191 #endif   /* defined(HAVE_PRI_AOC_EVENTS) */
07192       break;
07193    }
07194 
07195    return res;
07196 }
07197 
07198 int sig_pri_answer(struct sig_pri_chan *p, struct ast_channel *ast)
07199 {
07200    int res;
07201 
07202    /* Send a pri acknowledge */
07203    pri_grab(p, p->pri);
07204 #if defined(HAVE_PRI_AOC_EVENTS)
07205    if (p->aoc_s_request_invoke_id_valid) {
07206       /* if AOC-S was requested and the invoke id is still present on answer.  That means
07207        * no AOC-S rate list was provided, so send a NULL response which will indicate that
07208        * AOC-S is not available */
07209       pri_aoc_s_request_response_send(p->pri->pri, p->call,
07210          p->aoc_s_request_invoke_id, NULL);
07211       p->aoc_s_request_invoke_id_valid = 0;
07212    }
07213 #endif   /* defined(HAVE_PRI_AOC_EVENTS) */
07214    if (p->call_level < SIG_PRI_CALL_LEVEL_CONNECT) {
07215       p->call_level = SIG_PRI_CALL_LEVEL_CONNECT;
07216    }
07217    sig_pri_set_dialing(p, 0);
07218    sig_pri_open_media(p);
07219    res = pri_answer(p->pri->pri, p->call, 0, !p->digital);
07220    pri_rel(p->pri);
07221    ast_setstate(ast, AST_STATE_UP);
07222    return res;
07223 }
07224 
07225 /*!
07226  * \internal
07227  * \brief Simple check if the channel is available to use.
07228  * \since 1.8
07229  *
07230  * \param pvt Private channel control structure.
07231  *
07232  * \retval 0 Interface not available.
07233  * \retval 1 Interface is available.
07234  */
07235 static int sig_pri_available_check(struct sig_pri_chan *pvt)
07236 {
07237    /*
07238     * If interface has a B channel and is available for use
07239     * then the channel is available.
07240     */
07241    if (!pvt->no_b_channel && sig_pri_is_chan_available(pvt)) {
07242       return 1;
07243    }
07244    return 0;
07245 }
07246 
07247 #if defined(HAVE_PRI_CALL_WAITING)
07248 /*!
07249  * \internal
07250  * \brief Get an available call waiting interface.
07251  * \since 1.8
07252  *
07253  * \param pri PRI span control structure.
07254  *
07255  * \note Assumes the pri->lock is already obtained.
07256  *
07257  * \retval cw Call waiting interface to use.
07258  * \retval NULL if no call waiting interface available.
07259  */
07260 static struct sig_pri_chan *sig_pri_cw_available(struct sig_pri_span *pri)
07261 {
07262    struct sig_pri_chan *cw;
07263    int idx;
07264 
07265    cw = NULL;
07266    if (pri->num_call_waiting_calls < pri->max_call_waiting_calls) {
07267       if (!pri->num_call_waiting_calls) {
07268          /*
07269           * There are no outstanding call waiting calls.  Check to see
07270           * if the span is in a congested state for the first call
07271           * waiting call.
07272           */
07273          for (idx = 0; idx < pri->numchans; ++idx) {
07274             if (pri->pvts[idx] && sig_pri_available_check(pri->pvts[idx])) {
07275                /* There is another channel that is available on this span. */
07276                return cw;
07277             }
07278          }
07279       }
07280       idx = pri_find_empty_nobch(pri);
07281       if (0 <= idx) {
07282          /* Setup the call waiting interface to use. */
07283          cw = pri->pvts[idx];
07284          cw->is_call_waiting = 1;
07285          sig_pri_init_config(cw, pri);
07286          ast_atomic_fetchadd_int(&pri->num_call_waiting_calls, 1);
07287       }
07288    }
07289    return cw;
07290 }
07291 #endif   /* defined(HAVE_PRI_CALL_WAITING) */
07292 
07293 int sig_pri_available(struct sig_pri_chan **pvt, int is_specific_channel)
07294 {
07295    struct sig_pri_chan *p = *pvt;
07296    struct sig_pri_span *pri;
07297 
07298    if (!p->pri) {
07299       /* Something is wrong here.  A PRI channel without the pri pointer? */
07300       return 0;
07301    }
07302    pri = p->pri;
07303 
07304    ast_mutex_lock(&pri->lock);
07305    if (
07306 #if defined(HAVE_PRI_CALL_WAITING)
07307       /*
07308        * Only do call waiting calls if we have any
07309        * call waiting call outstanding.  We do not
07310        * want new calls to steal a B channel
07311        * freed for an earlier call waiting call.
07312        */
07313       !pri->num_call_waiting_calls &&
07314 #endif   /* defined(HAVE_PRI_CALL_WAITING) */
07315       sig_pri_available_check(p)) {
07316       p->allocated = 1;
07317       ast_mutex_unlock(&pri->lock);
07318       return 1;
07319    }
07320 
07321 #if defined(HAVE_PRI_CALL_WAITING)
07322    if (!is_specific_channel) {
07323       struct sig_pri_chan *cw;
07324 
07325       cw = sig_pri_cw_available(pri);
07326       if (cw) {
07327          /* We have a call waiting interface to use instead. */
07328          cw->allocated = 1;
07329          *pvt = cw;
07330          ast_mutex_unlock(&pri->lock);
07331          return 1;
07332       }
07333    }
07334 #endif   /* defined(HAVE_PRI_CALL_WAITING) */
07335    ast_mutex_unlock(&pri->lock);
07336    return 0;
07337 }
07338 
07339 /* If return 0, it means this function was able to handle it (pre setup digits).  If non zero, the user of this
07340  * functions should handle it normally (generate inband DTMF) */
07341 int sig_pri_digit_begin(struct sig_pri_chan *pvt, struct ast_channel *ast, char digit)
07342 {
07343    if (ast->_state == AST_STATE_DIALING) {
07344       if (pvt->call_level < SIG_PRI_CALL_LEVEL_OVERLAP) {
07345          unsigned int len;
07346 
07347          len = strlen(pvt->dialdest);
07348          if (len < sizeof(pvt->dialdest) - 1) {
07349             ast_debug(1, "Queueing digit '%c' since setup_ack not yet received\n",
07350                digit);
07351             pvt->dialdest[len++] = digit;
07352             pvt->dialdest[len] = '\0';
07353          } else {
07354             ast_log(LOG_WARNING,
07355                "Span %d: Deferred digit buffer overflow for digit '%c'.\n",
07356                pvt->pri->span, digit);
07357          }
07358          return 0;
07359       }
07360       if (pvt->call_level < SIG_PRI_CALL_LEVEL_PROCEEDING) {
07361          pri_grab(pvt, pvt->pri);
07362          pri_information(pvt->pri->pri, pvt->call, digit);
07363          pri_rel(pvt->pri);
07364          return 0;
07365       }
07366       if (pvt->call_level < SIG_PRI_CALL_LEVEL_CONNECT) {
07367          ast_log(LOG_WARNING,
07368             "Span %d: Digit '%c' may be ignored by peer. (Call level:%d(%s))\n",
07369             pvt->pri->span, digit, pvt->call_level,
07370             sig_pri_call_level2str(pvt->call_level));
07371       }
07372    }
07373    return 1;
07374 }
07375 
07376 /*!
07377  * \brief DTMF dial string complete.
07378  * \since 1.8.11
07379  *
07380  * \param pvt sig_pri private channel structure.
07381  * \param ast Asterisk channel
07382  *
07383  * \note Channel and private lock are already held.
07384  *
07385  * \return Nothing
07386  */
07387 void sig_pri_dial_complete(struct sig_pri_chan *pvt, struct ast_channel *ast)
07388 {
07389    /* If we just completed 'w' deferred dialing digits, we need to answer now. */
07390    if (pvt->call_level == SIG_PRI_CALL_LEVEL_DEFER_DIAL) {
07391       pvt->call_level = SIG_PRI_CALL_LEVEL_CONNECT;
07392 
07393       sig_pri_open_media(pvt);
07394       {
07395          struct ast_frame f = {AST_FRAME_CONTROL, };
07396 
07397          if (pvt->calls->queue_control) {
07398             pvt->calls->queue_control(pvt->chan_pvt, AST_CONTROL_ANSWER);
07399          }
07400 
07401          f.subclass.integer = AST_CONTROL_ANSWER;
07402          ast_queue_frame(ast, &f);
07403       }
07404       sig_pri_set_dialing(pvt, 0);
07405       /* Enable echo cancellation if it's not on already */
07406       sig_pri_set_echocanceller(pvt, 1);
07407    }
07408 }
07409 
07410 #if defined(HAVE_PRI_MWI)
07411 /*!
07412  * \internal
07413  * \brief Send a MWI indication to the given span.
07414  * \since 1.8
07415  *
07416  * \param pri PRI span control structure.
07417  * \param mbox_number Mailbox number
07418  * \param mbox_context Mailbox context
07419  * \param num_messages Number of messages waiting.
07420  *
07421  * \return Nothing
07422  */
07423 static void sig_pri_send_mwi_indication(struct sig_pri_span *pri, const char *mbox_number, const char *mbox_context, int num_messages)
07424 {
07425    struct pri_party_id mailbox;
07426 
07427    ast_debug(1, "Send MWI indication for %s@%s num_messages:%d\n", mbox_number,
07428       mbox_context, num_messages);
07429 
07430    memset(&mailbox, 0, sizeof(mailbox));
07431    mailbox.number.valid = 1;
07432    mailbox.number.presentation = PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
07433    mailbox.number.plan = (PRI_TON_UNKNOWN << 4) | PRI_NPI_UNKNOWN;
07434    ast_copy_string(mailbox.number.str, mbox_number, sizeof(mailbox.number.str));
07435 
07436    ast_mutex_lock(&pri->lock);
07437    pri_mwi_indicate(pri->pri, &mailbox, 1 /* speech */, num_messages, NULL, NULL, -1, 0);
07438    ast_mutex_unlock(&pri->lock);
07439 }
07440 #endif   /* defined(HAVE_PRI_MWI) */
07441 
07442 #if defined(HAVE_PRI_MWI)
07443 /*!
07444  * \internal
07445  * \brief MWI subscription event callback.
07446  * \since 1.8
07447  *
07448  * \param event the event being passed to the subscriber
07449  * \param userdata the data provider in the call to ast_event_subscribe()
07450  *
07451  * \return Nothing
07452  */
07453 static void sig_pri_mwi_event_cb(const struct ast_event *event, void *userdata)
07454 {
07455    struct sig_pri_span *pri = userdata;
07456    const char *mbox_context;
07457    const char *mbox_number;
07458    int num_messages;
07459 
07460    mbox_number = ast_event_get_ie_str(event, AST_EVENT_IE_MAILBOX);
07461    if (ast_strlen_zero(mbox_number)) {
07462       return;
07463    }
07464    mbox_context = ast_event_get_ie_str(event, AST_EVENT_IE_CONTEXT);
07465    if (ast_strlen_zero(mbox_context)) {
07466       return;
07467    }
07468    num_messages = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS);
07469    sig_pri_send_mwi_indication(pri, mbox_number, mbox_context, num_messages);
07470 }
07471 #endif   /* defined(HAVE_PRI_MWI) */
07472 
07473 #if defined(HAVE_PRI_MWI)
07474 /*!
07475  * \internal
07476  * \brief Send update MWI indications from the event cache.
07477  * \since 1.8
07478  *
07479  * \param pri PRI span control structure.
07480  *
07481  * \return Nothing
07482  */
07483 static void sig_pri_mwi_cache_update(struct sig_pri_span *pri)
07484 {
07485    int idx;
07486    int num_messages;
07487    struct ast_event *event;
07488 
07489    for (idx = 0; idx < ARRAY_LEN(pri->mbox); ++idx) {
07490       if (!pri->mbox[idx].sub) {
07491          /* There are no more mailboxes on this span. */
07492          break;
07493       }
07494 
07495       event = ast_event_get_cached(AST_EVENT_MWI,
07496          AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, pri->mbox[idx].number,
07497          AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, pri->mbox[idx].context,
07498          AST_EVENT_IE_END);
07499       if (!event) {
07500          /* No cached event for this mailbox. */
07501          continue;
07502       }
07503       num_messages = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS);
07504       sig_pri_send_mwi_indication(pri, pri->mbox[idx].number, pri->mbox[idx].context,
07505          num_messages);
07506       ast_event_destroy(event);
07507    }
07508 }
07509 #endif   /* defined(HAVE_PRI_MWI) */
07510 
07511 /*!
07512  * \brief Stop PRI span.
07513  * \since 1.8
07514  *
07515  * \param pri PRI span control structure.
07516  *
07517  * \return Nothing
07518  */
07519 void sig_pri_stop_pri(struct sig_pri_span *pri)
07520 {
07521 #if defined(HAVE_PRI_MWI)
07522    int idx;
07523 #endif   /* defined(HAVE_PRI_MWI) */
07524 
07525 #if defined(HAVE_PRI_MWI)
07526    for (idx = 0; idx < ARRAY_LEN(pri->mbox); ++idx) {
07527       if (pri->mbox[idx].sub) {
07528          pri->mbox[idx].sub = ast_event_unsubscribe(pri->mbox[idx].sub);
07529       }
07530    }
07531 #endif   /* defined(HAVE_PRI_MWI) */
07532 }
07533 
07534 /*!
07535  * \internal
07536  * \brief qsort comparison function.
07537  * \since 1.8
07538  *
07539  * \param left Ptr to sig_pri_chan ptr to compare.
07540  * \param right Ptr to sig_pri_chan ptr to compare.
07541  *
07542  * \retval <0 if left < right.
07543  * \retval =0 if left == right.
07544  * \retval >0 if left > right.
07545  */
07546 static int sig_pri_cmp_pri_chans(const void *left, const void *right)
07547 {
07548    const struct sig_pri_chan *pvt_left;
07549    const struct sig_pri_chan *pvt_right;
07550 
07551    pvt_left = *(struct sig_pri_chan **) left;
07552    pvt_right = *(struct sig_pri_chan **) right;
07553    if (!pvt_left) {
07554       if (!pvt_right) {
07555          return 0;
07556       }
07557       return 1;
07558    }
07559    if (!pvt_right) {
07560       return -1;
07561    }
07562 
07563    return pvt_left->channel - pvt_right->channel;
07564 }
07565 
07566 /*!
07567  * \internal
07568  * \brief Sort the PRI B channel private pointer array.
07569  * \since 1.8
07570  *
07571  * \param pri PRI span control structure.
07572  *
07573  * \details
07574  * Since the chan_dahdi.conf file can declare channels in any order, we need to sort
07575  * the private channel pointer array.
07576  *
07577  * \return Nothing
07578  */
07579 static void sig_pri_sort_pri_chans(struct sig_pri_span *pri)
07580 {
07581    qsort(&pri->pvts, pri->numchans, sizeof(pri->pvts[0]), sig_pri_cmp_pri_chans);
07582 }
07583 
07584 int sig_pri_start_pri(struct sig_pri_span *pri)
07585 {
07586    int x;
07587    int i;
07588 #if defined(HAVE_PRI_MWI)
07589    char *saveptr;
07590    char *mbox_number;
07591    char *mbox_context;
07592    struct ast_str *mwi_description = ast_str_alloca(64);
07593 #endif   /* defined(HAVE_PRI_MWI) */
07594 
07595 #if defined(HAVE_PRI_MWI)
07596    /* Prepare the mbox[] for use. */
07597    for (i = 0; i < ARRAY_LEN(pri->mbox); ++i) {
07598       if (pri->mbox[i].sub) {
07599          pri->mbox[i].sub = ast_event_unsubscribe(pri->mbox[i].sub);
07600       }
07601    }
07602 #endif   /* defined(HAVE_PRI_MWI) */
07603 
07604    ast_mutex_init(&pri->lock);
07605    sig_pri_sort_pri_chans(pri);
07606 
07607 #if defined(HAVE_PRI_MWI)
07608    /*
07609     * Split the mwi_mailboxes configuration string into the mbox[]:
07610     * mailbox_number[@context]{,mailbox_number[@context]}
07611     */
07612    i = 0;
07613    saveptr = pri->mwi_mailboxes;
07614    while (i < ARRAY_LEN(pri->mbox)) {
07615       mbox_number = strsep(&saveptr, ",");
07616       if (!mbox_number) {
07617          break;
07618       }
07619       /* Split the mailbox_number and context */
07620       mbox_context = strchr(mbox_number, '@');
07621       if (mbox_context) {
07622          *mbox_context++ = '\0';
07623          mbox_context = ast_strip(mbox_context);
07624       }
07625       mbox_number = ast_strip(mbox_number);
07626       if (ast_strlen_zero(mbox_number)) {
07627          /* There is no mailbox number.  Skip it. */
07628          continue;
07629       }
07630       if (ast_strlen_zero(mbox_context)) {
07631          /* There was no context so use the default. */
07632          mbox_context = "default";
07633       }
07634 
07635       /* Fill the mbox[] element. */
07636       ast_str_set(&mwi_description, -1, "%s span %d[%d] MWI mailbox %s@%s",
07637          sig_pri_cc_type_name, pri->span, i, mbox_number, mbox_context);
07638       pri->mbox[i].sub = ast_event_subscribe(AST_EVENT_MWI, sig_pri_mwi_event_cb,
07639          ast_str_buffer(mwi_description), pri,
07640          AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mbox_number,
07641          AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, mbox_context,
07642          AST_EVENT_IE_END);
07643       if (!pri->mbox[i].sub) {
07644          ast_log(LOG_ERROR, "%s span %d could not subscribe to MWI events for %s@%s.",
07645             sig_pri_cc_type_name, pri->span, mbox_number, mbox_context);
07646          continue;
07647       }
07648       pri->mbox[i].number = mbox_number;
07649       pri->mbox[i].context = mbox_context;
07650       ++i;
07651    }
07652 #endif   /* defined(HAVE_PRI_MWI) */
07653 
07654    for (i = 0; i < SIG_PRI_NUM_DCHANS; i++) {
07655       if (pri->fds[i] == -1) {
07656          break;
07657       }
07658 
07659       switch (pri->sig) {
07660       case SIG_BRI:
07661          pri->dchans[i] = pri_new_bri(pri->fds[i], 1, pri->nodetype, pri->switchtype);
07662          break;
07663       case SIG_BRI_PTMP:
07664          pri->dchans[i] = pri_new_bri(pri->fds[i], 0, pri->nodetype, pri->switchtype);
07665          break;
07666       default:
07667          pri->dchans[i] = pri_new(pri->fds[i], pri->nodetype, pri->switchtype);
07668 #if defined(HAVE_PRI_SERVICE_MESSAGES)
07669          if (pri->enable_service_message_support) {
07670             pri_set_service_message_support(pri->dchans[i], 1);
07671          }
07672 #endif   /* defined(HAVE_PRI_SERVICE_MESSAGES) */
07673          break;
07674       }
07675 
07676       pri_set_overlapdial(pri->dchans[i], (pri->overlapdial & DAHDI_OVERLAPDIAL_OUTGOING) ? 1 : 0);
07677 #ifdef HAVE_PRI_PROG_W_CAUSE
07678       pri_set_chan_mapping_logical(pri->dchans[i], pri->qsigchannelmapping == DAHDI_CHAN_MAPPING_LOGICAL);
07679 #endif
07680 #ifdef HAVE_PRI_INBANDDISCONNECT
07681       pri_set_inbanddisconnect(pri->dchans[i], pri->inbanddisconnect);
07682 #endif
07683       /* Enslave to master if appropriate */
07684       if (i)
07685          pri_enslave(pri->dchans[0], pri->dchans[i]);
07686       if (!pri->dchans[i]) {
07687          if (pri->fds[i] > 0)
07688             close(pri->fds[i]);
07689          pri->fds[i] = -1;
07690          ast_log(LOG_ERROR, "Unable to create PRI structure\n");
07691          return -1;
07692       }
07693       pri_set_debug(pri->dchans[i], SIG_PRI_DEBUG_DEFAULT);
07694       pri_set_nsf(pri->dchans[i], pri->nsf);
07695 #ifdef PRI_GETSET_TIMERS
07696       for (x = 0; x < PRI_MAX_TIMERS; x++) {
07697          if (pri->pritimers[x] != 0)
07698             pri_set_timer(pri->dchans[i], x, pri->pritimers[x]);
07699       }
07700 #endif
07701    }
07702 
07703    /* Assume primary is the one we use */
07704    pri->pri = pri->dchans[0];
07705 
07706 #if defined(HAVE_PRI_CALL_HOLD)
07707    pri_hold_enable(pri->pri, 1);
07708 #endif   /* defined(HAVE_PRI_CALL_HOLD) */
07709 #if defined(HAVE_PRI_CALL_REROUTING)
07710    pri_reroute_enable(pri->pri, 1);
07711 #endif   /* defined(HAVE_PRI_CALL_REROUTING) */
07712 #if defined(HAVE_PRI_HANGUP_FIX)
07713    pri_hangup_fix_enable(pri->pri, 1);
07714 #endif   /* defined(HAVE_PRI_HANGUP_FIX) */
07715 #if defined(HAVE_PRI_CCSS)
07716    pri_cc_enable(pri->pri, 1);
07717    pri_cc_recall_mode(pri->pri, pri->cc_ptmp_recall_mode);
07718    pri_cc_retain_signaling_req(pri->pri, pri->cc_qsig_signaling_link_req);
07719    pri_cc_retain_signaling_rsp(pri->pri, pri->cc_qsig_signaling_link_rsp);
07720 #endif   /* defined(HAVE_PRI_CCSS) */
07721 #if defined(HAVE_PRI_TRANSFER)
07722    pri_transfer_enable(pri->pri, 1);
07723 #endif   /* defined(HAVE_PRI_TRANSFER) */
07724 #if defined(HAVE_PRI_AOC_EVENTS)
07725    pri_aoc_events_enable(pri->pri, 1);
07726 #endif   /* defined(HAVE_PRI_AOC_EVENTS) */
07727 #if defined(HAVE_PRI_CALL_WAITING)
07728    pri_connect_ack_enable(pri->pri, 1);
07729 #endif   /* defined(HAVE_PRI_CALL_WAITING) */
07730 #if defined(HAVE_PRI_MCID)
07731    pri_mcid_enable(pri->pri, 1);
07732 #endif   /* defined(HAVE_PRI_MCID) */
07733 #if defined(HAVE_PRI_L2_PERSISTENCE)
07734    pri_persistent_layer2_option(pri->pri, pri->l2_persistence);
07735 #endif   /* defined(HAVE_PRI_L2_PERSISTENCE) */
07736 
07737    pri->resetpos = -1;
07738    if (ast_pthread_create_background(&pri->master, NULL, pri_dchannel, pri)) {
07739       for (i = 0; i < SIG_PRI_NUM_DCHANS; i++) {
07740          if (!pri->dchans[i])
07741             break;
07742          if (pri->fds[i] > 0)
07743             close(pri->fds[i]);
07744          pri->fds[i] = -1;
07745       }
07746       ast_log(LOG_ERROR, "Unable to spawn D-channel: %s\n", strerror(errno));
07747       return -1;
07748    }
07749 
07750 #if defined(HAVE_PRI_MWI)
07751    /*
07752     * Send the initial MWI indications from the event cache for this span.
07753     *
07754     * If we were loaded after app_voicemail the event would already be in
07755     * the cache.  If we were loaded before app_voicemail the event would not
07756     * be in the cache yet and app_voicemail will send the event when it
07757     * gets loaded.
07758     */
07759    sig_pri_mwi_cache_update(pri);
07760 #endif   /* defined(HAVE_PRI_MWI) */
07761 
07762    return 0;
07763 }
07764 
07765 /*!
07766  * \brief Notify new alarm status.
07767  *
07768  * \param p Channel private pointer.
07769  * \param noalarm Non-zero if not in alarm mode.
07770  * 
07771  * \note Assumes the sig_pri_lock_private(p) is already obtained.
07772  *
07773  * \return Nothing
07774  */
07775 void sig_pri_chan_alarm_notify(struct sig_pri_chan *p, int noalarm)
07776 {
07777    pri_grab(p, p->pri);
07778    sig_pri_set_alarm(p, !noalarm);
07779    if (!noalarm) {
07780       if (pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0) {
07781          /* T309 is not enabled : destroy calls when alarm occurs */
07782          if (p->call) {
07783             pri_destroycall(p->pri->pri, p->call);
07784             p->call = NULL;
07785          }
07786          if (p->owner)
07787             p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
07788       }
07789    }
07790    sig_pri_span_devstate_changed(p->pri);
07791    pri_rel(p->pri);
07792 }
07793 
07794 struct sig_pri_chan *sig_pri_chan_new(void *pvt_data, struct sig_pri_callback *callback, struct sig_pri_span *pri, int logicalspan, int channo, int trunkgroup)
07795 {
07796    struct sig_pri_chan *p;
07797 
07798    p = ast_calloc(1, sizeof(*p));
07799    if (!p)
07800       return p;
07801 
07802    p->logicalspan = logicalspan;
07803    p->prioffset = channo;
07804    p->mastertrunkgroup = trunkgroup;
07805 
07806    p->calls = callback;
07807    p->chan_pvt = pvt_data;
07808 
07809    p->pri = pri;
07810 
07811    return p;
07812 }
07813 
07814 /*!
07815  * \brief Delete the sig_pri private channel structure.
07816  * \since 1.8
07817  *
07818  * \param doomed sig_pri private channel structure to delete.
07819  *
07820  * \return Nothing
07821  */
07822 void sig_pri_chan_delete(struct sig_pri_chan *doomed)
07823 {
07824    ast_free(doomed);
07825 }
07826 
07827 #define SIG_PRI_SC_HEADER  "%-4s %4s %-4s %-4s %-10s %-4s %s\n"
07828 #define SIG_PRI_SC_LINE     "%4d %4d %-4s %-4s %-10s %-4s %s"
07829 void sig_pri_cli_show_channels_header(int fd)
07830 {
07831    ast_cli(fd, SIG_PRI_SC_HEADER, "PRI",  "",     "B",    "Chan", "Call",  "PRI",  "Channel");
07832    ast_cli(fd, SIG_PRI_SC_HEADER, "Span", "Chan", "Chan", "Idle", "Level", "Call", "Name");
07833 }
07834 
07835 void sig_pri_cli_show_channels(int fd, struct sig_pri_span *pri)
07836 {
07837    char line[256];
07838    int idx;
07839    struct sig_pri_chan *pvt;
07840 
07841    ast_mutex_lock(&pri->lock);
07842    for (idx = 0; idx < pri->numchans; ++idx) {
07843       if (!pri->pvts[idx]) {
07844          continue;
07845       }
07846       pvt = pri->pvts[idx];
07847       sig_pri_lock_private(pvt);
07848       sig_pri_lock_owner(pri, idx);
07849       if (pvt->no_b_channel && sig_pri_is_chan_available(pvt)) {
07850          /* Don't show held/call-waiting channels if they are not in use. */
07851          sig_pri_unlock_private(pvt);
07852          continue;
07853       }
07854 
07855       snprintf(line, sizeof(line), SIG_PRI_SC_LINE,
07856          pri->span,
07857          pvt->channel,
07858          pvt->no_b_channel ? "No" : "Yes",/* Has media */
07859          sig_pri_is_chan_available(pvt) ? "Yes" : "No",
07860          sig_pri_call_level2str(pvt->call_level),
07861          pvt->call ? "Yes" : "No",
07862          pvt->owner ? pvt->owner->name : "");
07863 
07864       if (pvt->owner) {
07865          ast_channel_unlock(pvt->owner);
07866       }
07867       sig_pri_unlock_private(pvt);
07868 
07869       ast_mutex_unlock(&pri->lock);
07870       ast_cli(fd, "%s\n", line);
07871       ast_mutex_lock(&pri->lock);
07872    }
07873    ast_mutex_unlock(&pri->lock);
07874 }
07875 
07876 static void build_status(char *s, size_t len, int status, int active)
07877 {
07878    if (!s || len < 1) {
07879       return;
07880    }
07881    s[0] = '\0';
07882    if (!(status & DCHAN_NOTINALARM))
07883       strncat(s, "In Alarm, ", len - strlen(s) - 1);
07884    if (status & DCHAN_UP)
07885       strncat(s, "Up", len - strlen(s) - 1);
07886    else
07887       strncat(s, "Down", len - strlen(s) - 1);
07888    if (active)
07889       strncat(s, ", Active", len - strlen(s) - 1);
07890    else
07891       strncat(s, ", Standby", len - strlen(s) - 1);
07892    s[len - 1] = '\0';
07893 }
07894 
07895 void sig_pri_cli_show_spans(int fd, int span, struct sig_pri_span *pri)
07896 {
07897    char status[256];
07898    int x;
07899    for (x = 0; x < SIG_PRI_NUM_DCHANS; x++) {
07900       if (pri->dchans[x]) {
07901          build_status(status, sizeof(status), pri->dchanavail[x], pri->dchans[x] == pri->pri);
07902          ast_cli(fd, "PRI span %d/%d: %s\n", span, x, status);
07903       }
07904    }
07905 }
07906 
07907 void sig_pri_cli_show_span(int fd, int *dchannels, struct sig_pri_span *pri)
07908 {
07909    int x;
07910    char status[256];
07911 
07912    for (x = 0; x < SIG_PRI_NUM_DCHANS; x++) {
07913       if (pri->dchans[x]) {
07914 #ifdef PRI_DUMP_INFO_STR
07915          char *info_str = NULL;
07916 #endif
07917          ast_cli(fd, "%s D-channel: %d\n", pri_order(x), dchannels[x]);
07918          build_status(status, sizeof(status), pri->dchanavail[x], pri->dchans[x] == pri->pri);
07919          ast_cli(fd, "Status: %s\n", status);
07920          ast_mutex_lock(&pri->lock);
07921 #ifdef PRI_DUMP_INFO_STR
07922          info_str = pri_dump_info_str(pri->pri);
07923          if (info_str) {
07924             ast_cli(fd, "%s", info_str);
07925             free(info_str);
07926          }
07927 #else
07928          pri_dump_info(pri->pri);
07929 #endif
07930          ast_mutex_unlock(&pri->lock);
07931          ast_cli(fd, "Overlap Recv: %s\n\n", (pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)?"Yes":"No");
07932          ast_cli(fd, "\n");
07933       }
07934    }
07935 }
07936 
07937 int pri_send_keypad_facility_exec(struct sig_pri_chan *p, const char *digits)
07938 {
07939    sig_pri_lock_private(p);
07940 
07941    if (!p->pri || !p->call) {
07942       ast_debug(1, "Unable to find pri or call on channel!\n");
07943       sig_pri_unlock_private(p);
07944       return -1;
07945    }
07946 
07947    pri_grab(p, p->pri);
07948    pri_keypad_facility(p->pri->pri, p->call, digits);
07949    pri_rel(p->pri);
07950 
07951    sig_pri_unlock_private(p);
07952 
07953    return 0;
07954 }
07955 
07956 int pri_send_callrerouting_facility_exec(struct sig_pri_chan *p, enum ast_channel_state chanstate, const char *destination, const char *original, const char *reason)
07957 {
07958    int res = -1;
07959 
07960    sig_pri_lock_private(p);
07961 
07962    if (!p->pri || !p->call) {
07963       ast_log(LOG_DEBUG, "Unable to find pri or call on channel!\n");
07964       sig_pri_unlock_private(p);
07965       return -1;
07966    }
07967 
07968    pri_grab(p, p->pri);
07969    res = pri_callrerouting_facility(p->pri->pri, p->call, destination, original, reason);
07970    pri_rel(p->pri);
07971 
07972    sig_pri_unlock_private(p);
07973 
07974    return res;
07975 }
07976 
07977 #if defined(HAVE_PRI_SERVICE_MESSAGES)
07978 int pri_maintenance_bservice(struct pri *pri, struct sig_pri_chan *p, int changestatus)
07979 {
07980    int channel = PVT_TO_CHANNEL(p);
07981    int span = PRI_SPAN(channel);
07982 
07983    return pri_maintenance_service(pri, span, channel, changestatus);
07984 }
07985 #endif   /* defined(HAVE_PRI_SERVICE_MESSAGES) */
07986 
07987 void sig_pri_fixup(struct ast_channel *oldchan, struct ast_channel *newchan, struct sig_pri_chan *pchan)
07988 {
07989    if (pchan->owner == oldchan) {
07990       pchan->owner = newchan;
07991    }
07992 }
07993 
07994 #if defined(HAVE_PRI_CCSS)
07995 /*!
07996  * \brief PRI CC agent initialization.
07997  * \since 1.8
07998  *
07999  * \param agent CC core agent control.
08000  * \param pvt_chan Original channel the agent will attempt to recall.
08001  *
08002  * \details
08003  * This callback is called when the CC core is initialized.  Agents should allocate
08004  * any private data necessary for the call and assign it to the private_data
08005  * on the agent.  Additionally, if any ast_cc_agent_flags are pertinent to the
08006  * specific agent type, they should be set in this function as well.
08007  *
08008  * \retval 0 on success.
08009  * \retval -1 on error.
08010  */
08011 int sig_pri_cc_agent_init(struct ast_cc_agent *agent, struct sig_pri_chan *pvt_chan)
08012 {
08013    struct sig_pri_cc_agent_prv *cc_pvt;
08014 
08015    cc_pvt = ast_calloc(1, sizeof(*cc_pvt));
08016    if (!cc_pvt) {
08017       return -1;
08018    }
08019 
08020    ast_mutex_lock(&pvt_chan->pri->lock);
08021    cc_pvt->pri = pvt_chan->pri;
08022    cc_pvt->cc_id = pri_cc_available(pvt_chan->pri->pri, pvt_chan->call);
08023    ast_mutex_unlock(&pvt_chan->pri->lock);
08024    if (cc_pvt->cc_id == -1) {
08025       ast_free(cc_pvt);
08026       return -1;
08027    }
08028    agent->private_data = cc_pvt;
08029    return 0;
08030 }
08031 #endif   /* defined(HAVE_PRI_CCSS) */
08032 
08033 #if defined(HAVE_PRI_CCSS)
08034 /*!
08035  * \brief Start the offer timer.
08036  * \since 1.8
08037  *
08038  * \param agent CC core agent control.
08039  *
08040  * \details
08041  * This is called by the core when the caller hangs up after
08042  * a call for which CC may be requested. The agent should
08043  * begin the timer as configured.
08044  *
08045  * The primary reason why this functionality is left to
08046  * the specific agent implementations is due to the differing
08047  * use of schedulers throughout the code. Some channel drivers
08048  * may already have a scheduler context they wish to use, and
08049  * amongst those, some may use the ast_sched API while others
08050  * may use the ast_sched_thread API, which are incompatible.
08051  *
08052  * \retval 0 on success.
08053  * \retval -1 on error.
08054  */
08055 int sig_pri_cc_agent_start_offer_timer(struct ast_cc_agent *agent)
08056 {
08057    /* libpri maintains it's own offer timer in the form of T_RETENTION. */
08058    return 0;
08059 }
08060 #endif   /* defined(HAVE_PRI_CCSS) */
08061 
08062 #if defined(HAVE_PRI_CCSS)
08063 /*!
08064  * \brief Stop the offer timer.
08065  * \since 1.8
08066  *
08067  * \param agent CC core agent control.
08068  *
08069  * \details
08070  * This callback is called by the CC core when the caller
08071  * has requested CC.
08072  *
08073  * \retval 0 on success.
08074  * \retval -1 on error.
08075  */
08076 int sig_pri_cc_agent_stop_offer_timer(struct ast_cc_agent *agent)
08077 {
08078    /* libpri maintains it's own offer timer in the form of T_RETENTION. */
08079    return 0;
08080 }
08081 #endif   /* defined(HAVE_PRI_CCSS) */
08082 
08083 #if defined(HAVE_PRI_CCSS)
08084 /*!
08085  * \brief Response to a CC request.
08086  * \since 1.8
08087  *
08088  * \param agent CC core agent control.
08089  * \param reason CC request response status.
08090  *
08091  * \details
08092  * When the core receives knowledge that a called
08093  * party has accepted a CC request, it will call
08094  * this callback.  The core may also call this
08095  * if there is some error when attempting to process
08096  * the incoming CC request.
08097  *
08098  * The duty of this is to issue a propper response to a
08099  * CC request from the caller by acknowledging receipt
08100  * of that request or rejecting it.
08101  *
08102  * \return Nothing
08103  */
08104 void sig_pri_cc_agent_req_rsp(struct ast_cc_agent *agent, enum ast_cc_agent_response_reason reason)
08105 {
08106    struct sig_pri_cc_agent_prv *cc_pvt;
08107    int res;
08108    int status;
08109    const char *failed_msg;
08110    static const char *failed_to_send = "Failed to send the CC request response.";
08111    static const char *not_accepted = "The core declined the CC request.";
08112 
08113    cc_pvt = agent->private_data;
08114    ast_mutex_lock(&cc_pvt->pri->lock);
08115    if (cc_pvt->cc_request_response_pending) {
08116       cc_pvt->cc_request_response_pending = 0;
08117 
08118       /* Convert core response reason to ISDN response status. */
08119       status = 2;/* short_term_denial */
08120       switch (reason) {
08121       case AST_CC_AGENT_RESPONSE_SUCCESS:
08122          status = 0;/* success */
08123          break;
08124       case AST_CC_AGENT_RESPONSE_FAILURE_INVALID:
08125          status = 2;/* short_term_denial */
08126          break;
08127       case AST_CC_AGENT_RESPONSE_FAILURE_TOO_MANY:
08128          status = 5;/* queue_full */
08129          break;
08130       }
08131 
08132       res = pri_cc_req_rsp(cc_pvt->pri->pri, cc_pvt->cc_id, status);
08133       if (!status) {
08134          /* CC core request was accepted. */
08135          if (res) {
08136             failed_msg = failed_to_send;
08137          } else {
08138             failed_msg = NULL;
08139          }
08140       } else {
08141          /* CC core request was declined. */
08142          if (res) {
08143             failed_msg = failed_to_send;
08144          } else {
08145             failed_msg = not_accepted;
08146          }
08147       }
08148    } else {
08149       failed_msg = NULL;
08150    }
08151    ast_mutex_unlock(&cc_pvt->pri->lock);
08152    if (failed_msg) {
08153       ast_cc_failed(agent->core_id, "%s agent: %s", sig_pri_cc_type_name, failed_msg);
08154    }
08155 }
08156 #endif   /* defined(HAVE_PRI_CCSS) */
08157 
08158 #if defined(HAVE_PRI_CCSS)
08159 /*!
08160  * \brief Request the status of the agent's device.
08161  * \since 1.8
08162  *
08163  * \param agent CC core agent control.
08164  *
08165  * \details
08166  * Asynchronous request for the status of any caller
08167  * which may be a valid caller for the CC transaction.
08168  * Status responses should be made using the
08169  * ast_cc_status_response function.
08170  *
08171  * \retval 0 on success.
08172  * \retval -1 on error.
08173  */
08174 int sig_pri_cc_agent_status_req(struct ast_cc_agent *agent)
08175 {
08176    struct sig_pri_cc_agent_prv *cc_pvt;
08177 
08178    cc_pvt = agent->private_data;
08179    ast_mutex_lock(&cc_pvt->pri->lock);
08180    pri_cc_status_req(cc_pvt->pri->pri, cc_pvt->cc_id);
08181    ast_mutex_unlock(&cc_pvt->pri->lock);
08182    return 0;
08183 }
08184 #endif   /* defined(HAVE_PRI_CCSS) */
08185 
08186 #if defined(HAVE_PRI_CCSS)
08187 /*!
08188  * \brief Request for an agent's phone to stop ringing.
08189  * \since 1.8
08190  *
08191  * \param agent CC core agent control.
08192  *
08193  * \details
08194  * The usefulness of this is quite limited. The only specific
08195  * known case for this is if Asterisk requests CC over an ISDN
08196  * PTMP link as the TE side. If other phones are in the same
08197  * recall group as the Asterisk server, and one of those phones
08198  * picks up the recall notice, then Asterisk will receive a
08199  * "stop ringing" notification from the NT side of the PTMP
08200  * link. This indication needs to be passed to the phone
08201  * on the other side of the Asterisk server which originally
08202  * placed the call so that it will stop ringing. Since the
08203  * phone may be of any type, it is necessary to have a callback
08204  * that the core can know about.
08205  *
08206  * \retval 0 on success.
08207  * \retval -1 on error.
08208  */
08209 int sig_pri_cc_agent_stop_ringing(struct ast_cc_agent *agent)
08210 {
08211    struct sig_pri_cc_agent_prv *cc_pvt;
08212 
08213    cc_pvt = agent->private_data;
08214    ast_mutex_lock(&cc_pvt->pri->lock);
08215    pri_cc_stop_alerting(cc_pvt->pri->pri, cc_pvt->cc_id);
08216    ast_mutex_unlock(&cc_pvt->pri->lock);
08217    return 0;
08218 }
08219 #endif   /* defined(HAVE_PRI_CCSS) */
08220 
08221 #if defined(HAVE_PRI_CCSS)
08222 /*!
08223  * \brief Let the caller know that the callee has become free
08224  * but that the caller cannot attempt to call back because
08225  * he is either busy or there is congestion on his line.
08226  * \since 1.8
08227  *
08228  * \param agent CC core agent control.
08229  *
08230  * \details
08231  * This is something that really only affects a scenario where
08232  * a phone places a call over ISDN PTMP to Asterisk, who then
08233  * connects over PTMP again to the ISDN network. For most agent
08234  * types, there is no need to implement this callback at all
08235  * because they don't really need to actually do anything in
08236  * this situation. If you're having trouble understanding what
08237  * the purpose of this callback is, then you can be safe simply
08238  * not implementing it.
08239  *
08240  * \retval 0 on success.
08241  * \retval -1 on error.
08242  */
08243 int sig_pri_cc_agent_party_b_free(struct ast_cc_agent *agent)
08244 {
08245    struct sig_pri_cc_agent_prv *cc_pvt;
08246 
08247    cc_pvt = agent->private_data;
08248    ast_mutex_lock(&cc_pvt->pri->lock);
08249    pri_cc_b_free(cc_pvt->pri->pri, cc_pvt->cc_id);
08250    ast_mutex_unlock(&cc_pvt->pri->lock);
08251    return 0;
08252 }
08253 #endif   /* defined(HAVE_PRI_CCSS) */
08254 
08255 #if defined(HAVE_PRI_CCSS)
08256 /*!
08257  * \brief Begin monitoring a busy device.
08258  * \since 1.8
08259  *
08260  * \param agent CC core agent control.
08261  *
08262  * \details
08263  * The core will call this callback if the callee becomes
08264  * available but the caller has reported that he is busy.
08265  * The agent should begin monitoring the caller's device.
08266  * When the caller becomes available again, the agent should
08267  * call ast_cc_agent_caller_available.
08268  *
08269  * \retval 0 on success.
08270  * \retval -1 on error.
08271  */
08272 int sig_pri_cc_agent_start_monitoring(struct ast_cc_agent *agent)
08273 {
08274    /* libpri already knows when and how it needs to monitor Party A. */
08275    return 0;
08276 }
08277 #endif   /* defined(HAVE_PRI_CCSS) */
08278 
08279 #if defined(HAVE_PRI_CCSS)
08280 /*!
08281  * \brief Alert the caller that it is time to try recalling.
08282  * \since 1.8
08283  *
08284  * \param agent CC core agent control.
08285  *
08286  * \details
08287  * The core will call this function when it receives notice
08288  * that a monitored party has become available.
08289  *
08290  * The agent's job is to send a message to the caller to
08291  * notify it of such a change. If the agent is able to
08292  * discern that the caller is currently unavailable, then
08293  * the agent should react by calling the ast_cc_caller_unavailable
08294  * function.
08295  *
08296  * \retval 0 on success.
08297  * \retval -1 on error.
08298  */
08299 int sig_pri_cc_agent_callee_available(struct ast_cc_agent *agent)
08300 {
08301    struct sig_pri_cc_agent_prv *cc_pvt;
08302 
08303    cc_pvt = agent->private_data;
08304    ast_mutex_lock(&cc_pvt->pri->lock);
08305    pri_cc_remote_user_free(cc_pvt->pri->pri, cc_pvt->cc_id);
08306    ast_mutex_unlock(&cc_pvt->pri->lock);
08307    return 0;
08308 }
08309 #endif   /* defined(HAVE_PRI_CCSS) */
08310 
08311 #if defined(HAVE_PRI_CCSS)
08312 /*!
08313  * \brief Destroy private data on the agent.
08314  * \since 1.8
08315  *
08316  * \param agent CC core agent control.
08317  *
08318  * \details
08319  * The core will call this function upon completion
08320  * or failure of CC.
08321  *
08322  * \note
08323  * The agent private_data pointer may be NULL if the agent
08324  * constructor failed.
08325  *
08326  * \return Nothing
08327  */
08328 void sig_pri_cc_agent_destructor(struct ast_cc_agent *agent)
08329 {
08330    struct sig_pri_cc_agent_prv *cc_pvt;
08331    int res;
08332 
08333    cc_pvt = agent->private_data;
08334    if (!cc_pvt) {
08335       /* The agent constructor probably failed. */
08336       return;
08337    }
08338    ast_mutex_lock(&cc_pvt->pri->lock);
08339    res = -1;
08340    if (cc_pvt->cc_request_response_pending) {
08341       res = pri_cc_req_rsp(cc_pvt->pri->pri, cc_pvt->cc_id, 2/* short_term_denial */);
08342    }
08343    if (res) {
08344       pri_cc_cancel(cc_pvt->pri->pri, cc_pvt->cc_id);
08345    }
08346    ast_mutex_unlock(&cc_pvt->pri->lock);
08347    ast_free(cc_pvt);
08348 }
08349 #endif   /* defined(HAVE_PRI_CCSS) */
08350 
08351 #if defined(HAVE_PRI_CCSS)
08352 /*!
08353  * \internal
08354  * \brief Return the hash value of the given CC monitor instance object.
08355  * \since 1.8
08356  *
08357  * \param obj pointer to the (user-defined part) of an object.
08358  * \param flags flags from ao2_callback().  Ignored at the moment.
08359  *
08360  * \retval core_id
08361  */
08362 static int sig_pri_cc_monitor_instance_hash_fn(const void *obj, const int flags)
08363 {
08364    const struct sig_pri_cc_monitor_instance *monitor_instance = obj;
08365 
08366    return monitor_instance->core_id;
08367 }
08368 #endif   /* defined(HAVE_PRI_CCSS) */
08369 
08370 #if defined(HAVE_PRI_CCSS)
08371 /*!
08372  * \internal
08373  * \brief Compere the monitor instance core_id key value.
08374  * \since 1.8
08375  *
08376  * \param obj pointer to the (user-defined part) of an object.
08377  * \param arg callback argument from ao2_callback()
08378  * \param flags flags from ao2_callback()
08379  *
08380  * \return values are a combination of enum _cb_results.
08381  */
08382 static int sig_pri_cc_monitor_instance_cmp_fn(void *obj, void *arg, int flags)
08383 {
08384    struct sig_pri_cc_monitor_instance *monitor_1 = obj;
08385    struct sig_pri_cc_monitor_instance *monitor_2 = arg;
08386 
08387    return monitor_1->core_id == monitor_2->core_id ? CMP_MATCH | CMP_STOP : 0;
08388 }
08389 #endif   /* defined(HAVE_PRI_CCSS) */
08390 
08391 #if defined(HAVE_PRI_CCSS)
08392 /*!
08393  * \brief Request CCSS.
08394  * \since 1.8
08395  *
08396  * \param monitor CC core monitor control.
08397  * \param available_timer_id Where to put the available timer scheduler id.
08398  * Will never be NULL for a device monitor.
08399  *
08400  * \details
08401  * Perform whatever steps are necessary in order to request CC.
08402  * In addition, the monitor implementation is responsible for
08403  * starting the available timer in this callback. The scheduler
08404  * ID for the callback must be stored in the parent_link's child_avail_id
08405  * field.
08406  *
08407  * \retval 0 on success
08408  * \retval -1 on failure.
08409  */
08410 int sig_pri_cc_monitor_req_cc(struct ast_cc_monitor *monitor, int *available_timer_id)
08411 {
08412    struct sig_pri_cc_monitor_instance *instance;
08413    int cc_mode;
08414    int res;
08415 
08416    switch (monitor->service_offered) {
08417    case AST_CC_CCBS:
08418       cc_mode = 0;/* CCBS */
08419       break;
08420    case AST_CC_CCNR:
08421       cc_mode = 1;/* CCNR */
08422       break;
08423    default:
08424       /* CC service not supported by ISDN. */
08425       return -1;
08426    }
08427 
08428    instance = monitor->private_data;
08429 
08430    /* libpri handles it's own available timer. */
08431    ast_mutex_lock(&instance->pri->lock);
08432    res = pri_cc_req(instance->pri->pri, instance->cc_id, cc_mode);
08433    ast_mutex_unlock(&instance->pri->lock);
08434 
08435    return res;
08436 }
08437 #endif   /* defined(HAVE_PRI_CCSS) */
08438 
08439 #if defined(HAVE_PRI_CCSS)
08440 /*!
08441  * \brief Suspend monitoring.
08442  * \since 1.8
08443  *
08444  * \param monitor CC core monitor control.
08445  *
08446  * \details
08447  * Implementers must perform the necessary steps to suspend
08448  * monitoring.
08449  *
08450  * \retval 0 on success
08451  * \retval -1 on failure.
08452  */
08453 int sig_pri_cc_monitor_suspend(struct ast_cc_monitor *monitor)
08454 {
08455    struct sig_pri_cc_monitor_instance *instance;
08456 
08457    instance = monitor->private_data;
08458    ast_mutex_lock(&instance->pri->lock);
08459    pri_cc_status(instance->pri->pri, instance->cc_id, 1/* busy */);
08460    ast_mutex_unlock(&instance->pri->lock);
08461 
08462    return 0;
08463 }
08464 #endif   /* defined(HAVE_PRI_CCSS) */
08465 
08466 #if defined(HAVE_PRI_CCSS)
08467 /*!
08468  * \brief Unsuspend monitoring.
08469  * \since 1.8
08470  *
08471  * \param monitor CC core monitor control.
08472  *
08473  * \details
08474  * Perform the necessary steps to unsuspend monitoring.
08475  *
08476  * \retval 0 on success
08477  * \retval -1 on failure.
08478  */
08479 int sig_pri_cc_monitor_unsuspend(struct ast_cc_monitor *monitor)
08480 {
08481    struct sig_pri_cc_monitor_instance *instance;
08482 
08483    instance = monitor->private_data;
08484    ast_mutex_lock(&instance->pri->lock);
08485    pri_cc_status(instance->pri->pri, instance->cc_id, 0/* free */);
08486    ast_mutex_unlock(&instance->pri->lock);
08487 
08488    return 0;
08489 }
08490 #endif   /* defined(HAVE_PRI_CCSS) */
08491 
08492 #if defined(HAVE_PRI_CCSS)
08493 /*!
08494  * \brief Status response to an ast_cc_monitor_status_request().
08495  * \since 1.8
08496  *
08497  * \param monitor CC core monitor control.
08498  * \param devstate Current status of a Party A device.
08499  *
08500  * \details
08501  * Alert a monitor as to the status of the agent for which
08502  * the monitor had previously requested a status request.
08503  *
08504  * \note Zero or more responses may come as a result.
08505  *
08506  * \retval 0 on success
08507  * \retval -1 on failure.
08508  */
08509 int sig_pri_cc_monitor_status_rsp(struct ast_cc_monitor *monitor, enum ast_device_state devstate)
08510 {
08511    struct sig_pri_cc_monitor_instance *instance;
08512    int cc_status;
08513 
08514    switch (devstate) {
08515    case AST_DEVICE_UNKNOWN:
08516    case AST_DEVICE_NOT_INUSE:
08517       cc_status = 0;/* free */
08518       break;
08519    case AST_DEVICE_BUSY:
08520    case AST_DEVICE_INUSE:
08521       cc_status = 1;/* busy */
08522       break;
08523    default:
08524       /* Don't know how to interpret this device state into free/busy status. */
08525       return 0;
08526    }
08527    instance = monitor->private_data;
08528    ast_mutex_lock(&instance->pri->lock);
08529    pri_cc_status_req_rsp(instance->pri->pri, instance->cc_id, cc_status);
08530    ast_mutex_unlock(&instance->pri->lock);
08531 
08532    return 0;
08533 }
08534 #endif   /* defined(HAVE_PRI_CCSS) */
08535 
08536 #if defined(HAVE_PRI_CCSS)
08537 /*!
08538  * \brief Cancel the running available timer.
08539  * \since 1.8
08540  *
08541  * \param monitor CC core monitor control.
08542  * \param sched_id Available timer scheduler id to cancel.
08543  * Will never be NULL for a device monitor.
08544  *
08545  * \details
08546  * In most cases, this function will likely consist of just a
08547  * call to AST_SCHED_DEL. It might have been possible to do this
08548  * within the core, but unfortunately the mixture of sched_thread
08549  * and sched usage in Asterisk prevents such usage.
08550  *
08551  * \retval 0 on success
08552  * \retval -1 on failure.
08553  */
08554 int sig_pri_cc_monitor_cancel_available_timer(struct ast_cc_monitor *monitor, int *sched_id)
08555 {
08556    /*
08557     * libpri maintains it's own available timer as one of:
08558     * T_CCBS2/T_CCBS5/T_CCBS6/QSIG_CCBS_T2
08559     * T_CCNR2/T_CCNR5/T_CCNR6/QSIG_CCNR_T2
08560     */
08561    return 0;
08562 }
08563 #endif   /* defined(HAVE_PRI_CCSS) */
08564 
08565 #if defined(HAVE_PRI_CCSS)
08566 /*!
08567  * \brief Destroy PRI private data on the monitor.
08568  * \since 1.8
08569  *
08570  * \param monitor_pvt CC device monitor private data pointer.
08571  *
08572  * \details
08573  * Implementers of this callback are responsible for destroying
08574  * all heap-allocated data in the monitor's private_data pointer, including
08575  * the private_data itself.
08576  */
08577 void sig_pri_cc_monitor_destructor(void *monitor_pvt)
08578 {
08579    struct sig_pri_cc_monitor_instance *instance;
08580 
08581    instance = monitor_pvt;
08582    if (!instance) {
08583       return;
08584    }
08585    ao2_unlink(sig_pri_cc_monitors, instance);
08586    ao2_ref(instance, -1);
08587 }
08588 #endif   /* defined(HAVE_PRI_CCSS) */
08589 
08590 /*!
08591  * \brief Load the sig_pri submodule.
08592  * \since 1.8
08593  *
08594  * \param cc_type_name CC type name to use when looking up agent/monitor.
08595  *
08596  * \retval 0 on success.
08597  * \retval -1 on error.
08598  */
08599 int sig_pri_load(const char *cc_type_name)
08600 {
08601 #if defined(HAVE_PRI_CCSS)
08602    sig_pri_cc_type_name = cc_type_name;
08603    sig_pri_cc_monitors = ao2_container_alloc(37, sig_pri_cc_monitor_instance_hash_fn,
08604       sig_pri_cc_monitor_instance_cmp_fn);
08605    if (!sig_pri_cc_monitors) {
08606       return -1;
08607    }
08608 #endif   /* defined(HAVE_PRI_CCSS) */
08609    return 0;
08610 }
08611 
08612 /*!
08613  * \brief Unload the sig_pri submodule.
08614  * \since 1.8
08615  *
08616  * \return Nothing
08617  */
08618 void sig_pri_unload(void)
08619 {
08620 #if defined(HAVE_PRI_CCSS)
08621    if (sig_pri_cc_monitors) {
08622       ao2_ref(sig_pri_cc_monitors, -1);
08623       sig_pri_cc_monitors = NULL;
08624    }
08625 #endif   /* defined(HAVE_PRI_CCSS) */
08626 }
08627 
08628 #endif /* HAVE_PRI */