Wed Apr 6 11:30:10 2011

Asterisk developer's documentation


sig_pri.h File Reference

Interface header for PRI signaling module. More...

#include "asterisk/channel.h"
#include "asterisk/frame.h"
#include "asterisk/event.h"
#include "asterisk/ccss.h"
#include <libpri.h>
#include <dahdi/user.h>

Go to the source code of this file.

Data Structures

struct  sig_pri_callback
struct  sig_pri_chan
struct  sig_pri_span

Defines

#define DAHDI_CHAN_MAPPING_LOGICAL   1
#define DAHDI_CHAN_MAPPING_PHYSICAL   0
#define DAHDI_OVERLAPDIAL_BOTH   (DAHDI_OVERLAPDIAL_INCOMING|DAHDI_OVERLAPDIAL_OUTGOING)
#define DAHDI_OVERLAPDIAL_INCOMING   2
#define DAHDI_OVERLAPDIAL_NONE   0
#define DAHDI_OVERLAPDIAL_OUTGOING   1
#define SIG_BRI   (0x2000000 | DAHDI_SIG_CLEAR)
#define SIG_BRI_PTMP   (0X4000000 | DAHDI_SIG_CLEAR)
#define SIG_PRI   DAHDI_SIG_CLEAR
#define SIG_PRI_AOC_GRANT_D   (1 << 1)
#define SIG_PRI_AOC_GRANT_E   (1 << 2)
#define SIG_PRI_AOC_GRANT_S   (1 << 0)
#define SIG_PRI_DEBUG_DEFAULT   0
#define SIG_PRI_DEBUG_INTENSE
#define SIG_PRI_DEBUG_NORMAL   (PRI_DEBUG_APDU | PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q931_STATE | PRI_DEBUG_Q921_STATE)
#define SIG_PRI_MAX_CHANNELS   672
#define SIG_PRI_NUM_DCHANS   4
#define SRVST_BOTH   (SRVST_NEAREND | SRVST_FAREND)
 SRVST_BOTH is used to indicate that both sides of the channel are out-of-service.
#define SRVST_DBKEY   "service-state"
 Persistent Service State.
#define SRVST_FAREND   (1 << 1)
 SRVST_FAREND is used to indicate that the far end was taken out-of-service.
#define SRVST_INITIALIZED   0
 SRVST_INITIALIZED is used to indicate a channel being out-of-service The SRVST_INITIALIZED is mostly used maintain backwards compatibility but also may mean that the channel has not yet received a RESTART message. If a channel is out-of-service with this reason a RESTART message will result in the channel being put into service.
#define SRVST_NEAREND   (1 << 0)
 SRVST_NEAREND is used to indicate that the near end was put out-of-service.
#define SRVST_TYPE_OOS   "O"
 The out-of-service SERVICE state.

Enumerations

enum  sig_pri_law { SIG_PRI_DEFLAW = 0, SIG_PRI_ULAW, SIG_PRI_ALAW }
enum  sig_pri_tone {
  SIG_PRI_TONE_RINGTONE = 0, SIG_PRI_TONE_STUTTER, SIG_PRI_TONE_CONGESTION, SIG_PRI_TONE_DIALTONE,
  SIG_PRI_TONE_DIALRECALL, SIG_PRI_TONE_INFO, SIG_PRI_TONE_BUSY
}

Functions

void pri_event_alarm (struct sig_pri_span *pri, int index, int before_start_pri)
void pri_event_noalarm (struct sig_pri_span *pri, int index, int before_start_pri)
int pri_is_up (struct sig_pri_span *pri)
int pri_maintenance_bservice (struct pri *pri, struct sig_pri_chan *p, int changestatus)
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)
int pri_send_keypad_facility_exec (struct sig_pri_chan *p, const char *digits)
int sig_pri_answer (struct sig_pri_chan *p, struct ast_channel *ast)
int sig_pri_available (struct sig_pri_chan **pvt, int is_specific_channel)
int sig_pri_call (struct sig_pri_chan *p, struct ast_channel *ast, char *rdest, int timeout, int layer1)
int sig_pri_cc_agent_callee_available (struct ast_cc_agent *agent)
void sig_pri_cc_agent_destructor (struct ast_cc_agent *agent)
int sig_pri_cc_agent_init (struct ast_cc_agent *agent, struct sig_pri_chan *pvt_chan)
int sig_pri_cc_agent_party_b_free (struct ast_cc_agent *agent)
void sig_pri_cc_agent_req_ack (struct ast_cc_agent *agent)
int sig_pri_cc_agent_start_monitoring (struct ast_cc_agent *agent)
int sig_pri_cc_agent_start_offer_timer (struct ast_cc_agent *agent)
int sig_pri_cc_agent_status_req (struct ast_cc_agent *agent)
int sig_pri_cc_agent_stop_offer_timer (struct ast_cc_agent *agent)
int sig_pri_cc_agent_stop_ringing (struct ast_cc_agent *agent)
int sig_pri_cc_monitor_cancel_available_timer (struct ast_cc_monitor *monitor, int *sched_id)
void sig_pri_cc_monitor_destructor (void *monitor_pvt)
int sig_pri_cc_monitor_req_cc (struct ast_cc_monitor *monitor, int *available_timer_id)
int sig_pri_cc_monitor_status_rsp (struct ast_cc_monitor *monitor, enum ast_device_state devstate)
int sig_pri_cc_monitor_suspend (struct ast_cc_monitor *monitor)
int sig_pri_cc_monitor_unsuspend (struct ast_cc_monitor *monitor)
void sig_pri_chan_alarm_notify (struct sig_pri_chan *p, int noalarm)
void sig_pri_chan_delete (struct sig_pri_chan *doomed)
 Delete the sig_pri private channel structure.
sig_pri_chansig_pri_chan_new (void *pvt_data, struct sig_pri_callback *callback, struct sig_pri_span *pri, int logicalspan, int channo, int trunkgroup)
void sig_pri_cli_show_span (int fd, int *dchannels, struct sig_pri_span *pri)
void sig_pri_cli_show_spans (int fd, int span, struct sig_pri_span *pri)
int sig_pri_digit_begin (struct sig_pri_chan *pvt, struct ast_channel *ast, char digit)
void sig_pri_extract_called_num_subaddr (struct sig_pri_chan *p, const char *rdest, char *called, size_t called_buff_size)
 Extract the called number and subaddress from the dial string.
void sig_pri_fixup (struct ast_channel *oldchan, struct ast_channel *newchan, struct sig_pri_chan *pchan)
int sig_pri_hangup (struct sig_pri_chan *p, struct ast_channel *ast)
int sig_pri_indicate (struct sig_pri_chan *p, struct ast_channel *chan, int condition, const void *data, size_t datalen)
void sig_pri_init_pri (struct sig_pri_span *pri)
int sig_pri_load (const char *cc_type_name)
 Load the sig_pri submodule.
ast_channelsig_pri_request (struct sig_pri_chan *p, enum sig_pri_law law, const struct ast_channel *requestor, int transfercapability)
int sig_pri_start_pri (struct sig_pri_span *pri)
void sig_pri_stop_pri (struct sig_pri_span *pri)
 Stop PRI span.
void sig_pri_unload (void)
 Unload the sig_pri submodule.

Variables

static const char dahdi_db [] = "dahdi/registry"
 The AstDB family.


Detailed Description

Interface header for PRI signaling module.

Author:
Matthew Fredrickson <creslin@digium.com>

Definition in file sig_pri.h.


Define Documentation

#define DAHDI_CHAN_MAPPING_LOGICAL   1

Definition at line 141 of file sig_pri.h.

#define DAHDI_CHAN_MAPPING_PHYSICAL   0

Definition at line 140 of file sig_pri.h.

Referenced by dahdi_chan_conf_default().

#define DAHDI_OVERLAPDIAL_BOTH   (DAHDI_OVERLAPDIAL_INCOMING|DAHDI_OVERLAPDIAL_OUTGOING)

Definition at line 147 of file sig_pri.h.

#define DAHDI_OVERLAPDIAL_INCOMING   2

Definition at line 146 of file sig_pri.h.

Referenced by dahdi_handle_event(), dahdi_read(), pri_ss_thread(), and sig_pri_cli_show_span().

#define DAHDI_OVERLAPDIAL_NONE   0

Definition at line 144 of file sig_pri.h.

#define DAHDI_OVERLAPDIAL_OUTGOING   1

Definition at line 145 of file sig_pri.h.

Referenced by dahdi_read().

#define SIG_BRI   (0x2000000 | DAHDI_SIG_CLEAR)

Definition at line 136 of file sig_pri.h.

#define SIG_BRI_PTMP   (0X4000000 | DAHDI_SIG_CLEAR)

Definition at line 137 of file sig_pri.h.

#define SIG_PRI   DAHDI_SIG_CLEAR

Definition at line 135 of file sig_pri.h.

#define SIG_PRI_AOC_GRANT_D   (1 << 1)

Definition at line 67 of file sig_pri.h.

Referenced by sig_pri_handle_subcmds(), and sig_pri_indicate().

#define SIG_PRI_AOC_GRANT_E   (1 << 2)

Definition at line 68 of file sig_pri.h.

Referenced by sig_pri_handle_subcmds(), and sig_pri_indicate().

#define SIG_PRI_AOC_GRANT_S   (1 << 0)

Definition at line 66 of file sig_pri.h.

Referenced by sig_pri_handle_subcmds(), and sig_pri_indicate().

#define SIG_PRI_DEBUG_DEFAULT   0

PRI debug message flags set on initial startup.

Definition at line 63 of file sig_pri.h.

#define SIG_PRI_DEBUG_INTENSE

Value:

(PRI_DEBUG_APDU | PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q931_STATE | PRI_DEBUG_Q921_STATE \
   | PRI_DEBUG_Q921_RAW | PRI_DEBUG_Q921_DUMP)
PRI debug message flags when intense PRI debugging is turned on at the command line.

Definition at line 53 of file sig_pri.h.

Referenced by handle_pri_debug().

#define SIG_PRI_DEBUG_NORMAL   (PRI_DEBUG_APDU | PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q931_STATE | PRI_DEBUG_Q921_STATE)

PRI debug message flags when normal PRI debugging is turned on at the command line.

Definition at line 49 of file sig_pri.h.

Referenced by handle_pri_debug().

#define SIG_PRI_MAX_CHANNELS   672

No more than a DS3 per trunk group

Definition at line 133 of file sig_pri.h.

#define SIG_PRI_NUM_DCHANS   4

No more than 4 d-channels

Definition at line 132 of file sig_pri.h.

Referenced by pri_active_dchan_index(), pri_find_dchan(), pri_is_up(), sig_pri_init_pri(), and sig_pri_start_pri().

#define SRVST_BOTH   (SRVST_NEAREND | SRVST_FAREND)

SRVST_BOTH is used to indicate that both sides of the channel are out-of-service.

Definition at line 165 of file sig_pri.h.

#define SRVST_DBKEY   "service-state"

Persistent Service State.

Definition at line 151 of file sig_pri.h.

Referenced by destroy_all_channels().

#define SRVST_FAREND   (1 << 1)

SRVST_FAREND is used to indicate that the far end was taken out-of-service.

Definition at line 163 of file sig_pri.h.

Referenced by pri_check_restart().

#define SRVST_INITIALIZED   0

SRVST_INITIALIZED is used to indicate a channel being out-of-service The SRVST_INITIALIZED is mostly used maintain backwards compatibility but also may mean that the channel has not yet received a RESTART message. If a channel is out-of-service with this reason a RESTART message will result in the channel being put into service.

Definition at line 159 of file sig_pri.h.

#define SRVST_NEAREND   (1 << 0)

SRVST_NEAREND is used to indicate that the near end was put out-of-service.

Definition at line 161 of file sig_pri.h.

Referenced by pri_check_restart().

#define SRVST_TYPE_OOS   "O"

The out-of-service SERVICE state.

Definition at line 153 of file sig_pri.h.


Enumeration Type Documentation

enum sig_pri_law

Enumerator:
SIG_PRI_DEFLAW 
SIG_PRI_ULAW 
SIG_PRI_ALAW 

Definition at line 80 of file sig_pri.h.

00080                  {
00081    SIG_PRI_DEFLAW = 0,
00082    SIG_PRI_ULAW,
00083    SIG_PRI_ALAW
00084 };

enum sig_pri_tone

Enumerator:
SIG_PRI_TONE_RINGTONE 
SIG_PRI_TONE_STUTTER 
SIG_PRI_TONE_CONGESTION 
SIG_PRI_TONE_DIALTONE 
SIG_PRI_TONE_DIALRECALL 
SIG_PRI_TONE_INFO 
SIG_PRI_TONE_BUSY 

Definition at line 70 of file sig_pri.h.


Function Documentation

void pri_event_alarm ( struct sig_pri_span pri,
int  index,
int  before_start_pri 
)

Definition at line 1671 of file sig_pri.c.

References DCHAN_NOTINALARM, DCHAN_UP, sig_pri_span::dchanavail, and pri_find_dchan().

Referenced by my_handle_dchan_exception(), and prepare_pri().

01672 {
01673    pri->dchanavail[index] &= ~(DCHAN_NOTINALARM | DCHAN_UP);
01674    if (!before_start_pri)
01675       pri_find_dchan(pri);
01676 }

void pri_event_noalarm ( struct sig_pri_span pri,
int  index,
int  before_start_pri 
)

Definition at line 1678 of file sig_pri.c.

References DCHAN_NOTINALARM, sig_pri_span::dchanavail, and sig_pri_span::dchans.

Referenced by my_handle_dchan_exception(), and prepare_pri().

01679 {
01680    pri->dchanavail[index] |= DCHAN_NOTINALARM;
01681    if (!before_start_pri)
01682       pri_restart(pri->dchans[index]);
01683 }

int pri_is_up ( struct sig_pri_span pri  ) 

Definition at line 926 of file sig_pri.c.

References DCHAN_AVAILABLE, sig_pri_span::dchanavail, and SIG_PRI_NUM_DCHANS.

Referenced by pri_dchannel().

00927 {
00928    int x;
00929    for (x = 0; x < SIG_PRI_NUM_DCHANS; x++) {
00930       if (pri->dchanavail[x] == DCHAN_AVAILABLE)
00931          return 1;
00932    }
00933    return 0;
00934 }

int pri_maintenance_bservice ( struct pri *  pri,
struct sig_pri_chan p,
int  changestatus 
)

Definition at line 7358 of file sig_pri.c.

References sig_pri_chan::channel, PRI_SPAN, and PVT_TO_CHANNEL().

07359 {
07360    int channel = PVT_TO_CHANNEL(p);
07361    int span = PRI_SPAN(channel);
07362 
07363    return pri_maintenance_service(pri, span, channel, changestatus);
07364 }

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 
)

Definition at line 7333 of file sig_pri.c.

References ast_log(), sig_pri_chan::call, LOG_DEBUG, sig_pri_span::pri, sig_pri_chan::pri, pri_grab(), pri_rel(), sig_pri_lock_private(), sig_pri_unlock_private(), and sig_pri_span::span.

Referenced by dahdi_send_callrerouting_facility_exec().

07334 {
07335    int res = -1;
07336 
07337    sig_pri_lock_private(p);
07338 
07339    if (!p->pri || !p->call) {
07340       ast_log(LOG_DEBUG, "Unable to find pri or call on channel!\n");
07341       sig_pri_unlock_private(p);
07342       return -1;
07343    }
07344 
07345    if (!pri_grab(p, p->pri)) {
07346       res = pri_callrerouting_facility(p->pri->pri, p->call, destination, original, reason);
07347       pri_rel(p->pri);
07348    } else {
07349       ast_log(LOG_DEBUG, "Unable to grab pri to send callrerouting facility on span %d!\n", p->pri->span);
07350    }
07351 
07352    sig_pri_unlock_private(p);
07353 
07354    return res;
07355 }

int pri_send_keypad_facility_exec ( struct sig_pri_chan p,
const char *  digits 
)

Definition at line 7309 of file sig_pri.c.

References ast_debug, sig_pri_chan::call, sig_pri_span::pri, sig_pri_chan::pri, pri_grab(), pri_rel(), sig_pri_lock_private(), and sig_pri_unlock_private().

Referenced by dahdi_send_keypad_facility_exec().

07310 {
07311    sig_pri_lock_private(p);
07312 
07313    if (!p->pri || !p->call) {
07314       ast_debug(1, "Unable to find pri or call on channel!\n");
07315       sig_pri_unlock_private(p);
07316       return -1;
07317    }
07318 
07319    if (!pri_grab(p, p->pri)) {
07320       pri_keypad_facility(p->pri->pri, p->call, digits);
07321       pri_rel(p->pri);
07322    } else {
07323       ast_debug(1, "Unable to grab pri to send keypad facility!\n");
07324       sig_pri_unlock_private(p);
07325       return -1;
07326    }
07327 
07328    sig_pri_unlock_private(p);
07329 
07330    return 0;
07331 }

int sig_pri_answer ( struct sig_pri_chan p,
struct ast_channel ast 
)

Definition at line 6677 of file sig_pri.c.

References ast_setstate(), AST_STATE_UP, sig_pri_chan::call, sig_pri_chan::digital, sig_pri_span::pri, sig_pri_chan::pri, pri_grab(), pri_rel(), sig_pri_chan::proceeding, sig_pri_open_media(), and sig_pri_set_dialing().

Referenced by dahdi_answer().

06678 {
06679    int res = 0;
06680    /* Send a pri acknowledge */
06681    if (!pri_grab(p, p->pri)) {
06682 #if defined(HAVE_PRI_AOC_EVENTS)
06683       if (p->aoc_s_request_invoke_id_valid) {
06684          /* if AOC-S was requested and the invoke id is still present on answer.  That means
06685           * no AOC-S rate list was provided, so send a NULL response which will indicate that
06686           * AOC-S is not available */
06687          pri_aoc_s_request_response_send(p->pri->pri, p->call,
06688             p->aoc_s_request_invoke_id, NULL);
06689          p->aoc_s_request_invoke_id_valid = 0;
06690       }
06691 #endif   /* defined(HAVE_PRI_AOC_EVENTS) */
06692       p->proceeding = 1;
06693       sig_pri_set_dialing(p, 0);
06694       sig_pri_open_media(p);
06695       res = pri_answer(p->pri->pri, p->call, 0, !p->digital);
06696       pri_rel(p->pri);
06697    } else {
06698       res = -1;
06699    }
06700    ast_setstate(ast, AST_STATE_UP);
06701    return res;
06702 }

int sig_pri_available ( struct sig_pri_chan **  pvt,
int  is_specific_channel 
)

Definition at line 6779 of file sig_pri.c.

References sig_pri_chan::pri, and sig_pri_available_check().

Referenced by available().

06780 {
06781    struct sig_pri_chan *p = *pvt;
06782 
06783    if (!p->pri) {
06784       /* Something is wrong here.  A PRI channel without the pri pointer? */
06785       return 0;
06786    }
06787 
06788    if (
06789 #if defined(HAVE_PRI_CALL_WAITING)
06790       /*
06791        * Only do call waiting calls if we have any
06792        * call waiting call outstanding.  We do not
06793        * want new calls to steal a B channel
06794        * freed for an earlier call waiting call.
06795        */
06796       !p->pri->num_call_waiting_calls &&
06797 #endif   /* defined(HAVE_PRI_CALL_WAITING) */
06798       sig_pri_available_check(p)) {
06799       return 1;
06800    }
06801 
06802 #if defined(HAVE_PRI_CALL_WAITING)
06803    if (!is_specific_channel) {
06804       struct sig_pri_chan *cw;
06805 
06806       cw = sig_pri_cw_available(p->pri);
06807       if (cw) {
06808          /* We have a call waiting interface to use instead. */
06809          *pvt = cw;
06810          return 1;
06811       }
06812    }
06813 #endif   /* defined(HAVE_PRI_CALL_WAITING) */
06814    return 0;
06815 }

int sig_pri_call ( struct sig_pri_chan p,
struct ast_channel ast,
char *  rdest,
int  timeout,
int  layer1 
)

Note:
Parsing must remain in sync with sig_pri_extract_called_num_subaddr().

Definition at line 6036 of file sig_pri.c.

References ast_channel::_state, ao2_ref, sig_pri_span::append_msn_to_user_tag, args, AST_APP_ARG, ast_app_parse_options(), ast_assert, ast_cc_get_monitor_by_recall_core_id(), ast_cc_is_recall(), ast_channel_get_device_name(), AST_CHANNEL_NAME, ast_copy_string(), AST_DECLARE_APP_ARGS, ast_free, ast_log(), AST_NONSTANDARD_APP_ARGS, ast_party_subaddress_init(), ast_setstate(), AST_STATE_DIALING, AST_STATE_DOWN, AST_STATE_RESERVED, ast_strdup, ast_strlen_zero(), ast_test_flag, ast_transfercapability2str(), ast_verb, sig_pri_chan::call, ast_channel::caller, sig_pri_chan::channel, ast_channel::connected, sig_pri_chan::dialdest, sig_pri_span::dialplan, dialplan2str(), sig_pri_chan::digital, ext, sig_pri_span::facilityenable, sig_pri_chan::hidecallerid, sig_pri_chan::hidecalleridname, ast_party_caller::id, ast_party_connected_line::id, sig_pri_span::initial_user_tag, sig_pri_span::internationalprefix, IS_DIGITAL, sig_pri_span::localdialplan, LOG_DEBUG, LOG_ERROR, LOG_WARNING, monitor, ast_channel::name, ast_party_id::name, sig_pri_span::nationalprefix, sig_pri_span::nodetype, ast_party_id::number, ast_party_subaddress::odd_even_indicator, OPT_AOC_REQUEST, OPT_ARG_AOC_REQUEST, OPT_ARG_ARRAY_SIZE, OPT_ARG_KEYPAD, OPT_KEYPAD, OPT_REVERSE_CHARGE, sig_pri_chan::outgoing, sig_pri_chan::owner, pbx_builtin_getvar_helper(), ast_party_number::presentation, sig_pri_span::pri, sig_pri_chan::pri, pri_grab(), pri_rel(), PRI_TRANS_CAP_DIGITAL, sig_pri_chan::priexclusive, PVT_TO_CHANNEL(), S_COR, sig_pri_call_opts, sig_pri_party_subaddress_from_ast(), sig_pri_redirecting_update(), sig_pri_set_dialing(), sig_pri_set_digital(), ast_party_subaddress::str, ast_party_number::str, ast_party_name::str, sig_pri_chan::stripmsd, ast_party_id::subaddress, ast_party_id::tag, ast_channel::transfercapability, ast_party_subaddress::type, sig_pri_chan::use_callingpres, sig_pri_chan::user_tag, ast_party_subaddress::valid, ast_party_number::valid, and ast_party_name::valid.

Referenced by dahdi_call().

06037 {
06038    char dest[256]; /* must be same length as p->dialdest */
06039    struct ast_party_subaddress dialed_subaddress; /* Called subaddress */
06040    struct pri_sr *sr;
06041    char *c, *l, *n, *s;
06042 #ifdef SUPPORT_USERUSER
06043    const char *useruser;
06044 #endif
06045    int core_id;
06046    int pridialplan;
06047    int dp_strip;
06048    int prilocaldialplan;
06049    int ldp_strip;
06050    int exclusive;
06051 #if defined(HAVE_PRI_SETUP_KEYPAD)
06052    const char *keypad;
06053 #endif   /* defined(HAVE_PRI_SETUP_KEYPAD) */
06054    AST_DECLARE_APP_ARGS(args,
06055       AST_APP_ARG(group);  /* channel/group token */
06056       AST_APP_ARG(ext); /* extension token */
06057       AST_APP_ARG(opts);   /* options token */
06058       AST_APP_ARG(other);  /* Any remining unused arguments */
06059    );
06060    struct ast_flags opts;
06061    char *opt_args[OPT_ARG_ARRAY_SIZE];
06062 
06063    ast_log(LOG_DEBUG, "CALLER NAME: %s NUM: %s\n",
06064       S_COR(ast->connected.id.name.valid, ast->connected.id.name.str, ""),
06065       S_COR(ast->connected.id.number.valid, ast->connected.id.number.str, ""));
06066 
06067    if (!p->pri) {
06068       ast_log(LOG_ERROR, "Could not find pri on channel %d\n", p->channel);
06069       return -1;
06070    }
06071 
06072    if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
06073       ast_log(LOG_WARNING, "sig_pri_call called on %s, neither down nor reserved\n", ast->name);
06074       return -1;
06075    }
06076 
06077    p->dialdest[0] = '\0';
06078    p->outgoing = 1;
06079 
06080    ast_copy_string(dest, rdest, sizeof(dest));
06081    AST_NONSTANDARD_APP_ARGS(args, dest, '/');
06082    if (ast_app_parse_options(sig_pri_call_opts, &opts, opt_args, args.opts)) {
06083       /* General invalid option syntax. */
06084       return -1;
06085    }
06086 
06087    c = args.ext;
06088    if (!c) {
06089       c = "";
06090    }
06091 
06092    /* setup dialed_subaddress if found */
06093    ast_party_subaddress_init(&dialed_subaddress);
06094    s = strchr(c, ':');
06095    if (s) {
06096       *s = '\0';
06097       s++;
06098       /* prefix */
06099       /* 'n' = NSAP */
06100       /* 'U' = odd, 'u'= even */
06101       /* Default = NSAP */
06102       switch (*s) {
06103       case 'U':
06104          dialed_subaddress.odd_even_indicator = 1;
06105          /* fall through */
06106       case 'u':
06107          s++;
06108          dialed_subaddress.type = 2;
06109          break;
06110       case 'N':
06111       case 'n':
06112          s++;
06113          /* default already covered with ast_party_subaddress_init */
06114          break;
06115       }
06116       dialed_subaddress.str = s;
06117       dialed_subaddress.valid = 1;
06118       s = NULL;
06119    }
06120 
06121    l = NULL;
06122    n = NULL;
06123    if (!p->hidecallerid) {
06124       if (ast->connected.id.number.valid) {
06125          /* If we get to the end of this loop without breaking, there's no
06126           * calleridnum.  This is done instead of testing for "unknown" or
06127           * the thousands of other ways that the calleridnum could be
06128           * invalid. */
06129          for (l = ast->connected.id.number.str; l && *l; l++) {
06130             if (strchr("0123456789", *l)) {
06131                l = ast->connected.id.number.str;
06132                break;
06133             }
06134          }
06135       } else {
06136          l = NULL;
06137       }
06138       if (!p->hidecalleridname) {
06139          n = ast->connected.id.name.valid ? ast->connected.id.name.str : NULL;
06140       }
06141    }
06142 
06143    if (strlen(c) < p->stripmsd) {
06144       ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
06145       return -1;
06146    }
06147    if (pri_grab(p, p->pri)) {
06148       ast_log(LOG_WARNING, "Failed to grab PRI!\n");
06149       return -1;
06150    }
06151    if (!(p->call = pri_new_call(p->pri->pri))) {
06152       ast_log(LOG_WARNING, "Unable to create call on channel %d\n", p->channel);
06153       pri_rel(p->pri);
06154       return -1;
06155    }
06156    if (!(sr = pri_sr_new())) {
06157       ast_log(LOG_WARNING, "Failed to allocate setup request channel %d\n", p->channel);
06158       pri_destroycall(p->pri->pri, p->call);
06159       p->call = NULL;
06160       pri_rel(p->pri);
06161       return -1;
06162    }
06163 
06164    sig_pri_set_digital(p, IS_DIGITAL(ast->transfercapability));   /* push up to parent for EC */
06165 
06166 #if defined(HAVE_PRI_CALL_WAITING)
06167    if (p->is_call_waiting) {
06168       /*
06169        * Indicate that this is a call waiting call.
06170        * i.e., Normal call but with no B channel.
06171        */
06172       pri_sr_set_channel(sr, 0, 0, 1);
06173    } else
06174 #endif   /* defined(HAVE_PRI_CALL_WAITING) */
06175    {
06176       /* Should the picked channel be used exclusively? */
06177       if (p->priexclusive || p->pri->nodetype == PRI_NETWORK) {
06178          exclusive = 1;
06179       } else {
06180          exclusive = 0;
06181       }
06182       pri_sr_set_channel(sr, PVT_TO_CHANNEL(p), exclusive, 1);
06183    }
06184 
06185    pri_sr_set_bearer(sr, p->digital ? PRI_TRANS_CAP_DIGITAL : ast->transfercapability,
06186       (p->digital ? -1 : layer1));
06187 
06188    if (p->pri->facilityenable)
06189       pri_facility_enable(p->pri->pri);
06190 
06191    ast_verb(3, "Requested transfer capability: 0x%.2x - %s\n", ast->transfercapability, ast_transfercapability2str(ast->transfercapability));
06192    dp_strip = 0;
06193    pridialplan = p->pri->dialplan - 1;
06194    if (pridialplan == -2 || pridialplan == -3) { /* compute dynamically */
06195       if (strncmp(c + p->stripmsd, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) {
06196          if (pridialplan == -2) {
06197             dp_strip = strlen(p->pri->internationalprefix);
06198          }
06199          pridialplan = PRI_INTERNATIONAL_ISDN;
06200       } else if (strncmp(c + p->stripmsd, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) {
06201          if (pridialplan == -2) {
06202             dp_strip = strlen(p->pri->nationalprefix);
06203          }
06204          pridialplan = PRI_NATIONAL_ISDN;
06205       } else {
06206          pridialplan = PRI_LOCAL_ISDN;
06207       }
06208    }
06209    while (c[p->stripmsd] > '9' && c[p->stripmsd] != '*' && c[p->stripmsd] != '#') {
06210       switch (c[p->stripmsd]) {
06211       case 'U':
06212          pridialplan = (PRI_TON_UNKNOWN << 4) | (pridialplan & 0xf);
06213          break;
06214       case 'I':
06215          pridialplan = (PRI_TON_INTERNATIONAL << 4) | (pridialplan & 0xf);
06216          break;
06217       case 'N':
06218          pridialplan = (PRI_TON_NATIONAL << 4) | (pridialplan & 0xf);
06219          break;
06220       case 'L':
06221          pridialplan = (PRI_TON_NET_SPECIFIC << 4) | (pridialplan & 0xf);
06222          break;
06223       case 'S':
06224          pridialplan = (PRI_TON_SUBSCRIBER << 4) | (pridialplan & 0xf);
06225          break;
06226       case 'V':
06227          pridialplan = (PRI_TON_ABBREVIATED << 4) | (pridialplan & 0xf);
06228          break;
06229       case 'R':
06230          pridialplan = (PRI_TON_RESERVED << 4) | (pridialplan & 0xf);
06231          break;
06232       case 'u':
06233          pridialplan = PRI_NPI_UNKNOWN | (pridialplan & 0xf0);
06234          break;
06235       case 'e':
06236          pridialplan = PRI_NPI_E163_E164 | (pridialplan & 0xf0);
06237          break;
06238       case 'x':
06239          pridialplan = PRI_NPI_X121 | (pridialplan & 0xf0);
06240          break;
06241       case 'f':
06242          pridialplan = PRI_NPI_F69 | (pridialplan & 0xf0);
06243          break;
06244       case 'n':
06245          pridialplan = PRI_NPI_NATIONAL | (pridialplan & 0xf0);
06246          break;
06247       case 'p':
06248          pridialplan = PRI_NPI_PRIVATE | (pridialplan & 0xf0);
06249          break;
06250       case 'r':
06251          pridialplan = PRI_NPI_RESERVED | (pridialplan & 0xf0);
06252          break;
06253       default:
06254          if (isalpha(c[p->stripmsd])) {
06255             ast_log(LOG_WARNING, "Unrecognized pridialplan %s modifier: %c\n",
06256                c[p->stripmsd] > 'Z' ? "NPI" : "TON", c[p->stripmsd]);
06257          }
06258          break;
06259       }
06260       c++;
06261    }
06262 #if defined(HAVE_PRI_SETUP_KEYPAD)
06263    if (ast_test_flag(&opts, OPT_KEYPAD)
06264       && !ast_strlen_zero(opt_args[OPT_ARG_KEYPAD])) {
06265       /* We have a keypad facility digits option with digits. */
06266       keypad = opt_args[OPT_ARG_KEYPAD];
06267       pri_sr_set_keypad_digits(sr, keypad);
06268    } else {
06269       keypad = NULL;
06270    }
06271    if (!keypad || !ast_strlen_zero(c + p->stripmsd + dp_strip))
06272 #endif   /* defined(HAVE_PRI_SETUP_KEYPAD) */
06273    {
06274       pri_sr_set_called(sr, c + p->stripmsd + dp_strip, pridialplan, s ? 1 : 0);
06275    }
06276 
06277 #if defined(HAVE_PRI_SUBADDR)
06278    if (dialed_subaddress.valid) {
06279       struct pri_party_subaddress subaddress;
06280 
06281       memset(&subaddress, 0, sizeof(subaddress));
06282       sig_pri_party_subaddress_from_ast(&subaddress, &dialed_subaddress);
06283       pri_sr_set_called_subaddress(sr, &subaddress);
06284    }
06285 #endif   /* defined(HAVE_PRI_SUBADDR) */
06286 #if defined(HAVE_PRI_REVERSE_CHARGE)
06287    if (ast_test_flag(&opts, OPT_REVERSE_CHARGE)) {
06288       pri_sr_set_reversecharge(sr, PRI_REVERSECHARGE_REQUESTED);
06289    }
06290 #endif   /* defined(HAVE_PRI_REVERSE_CHARGE) */
06291 #if defined(HAVE_PRI_AOC_EVENTS)
06292    if (ast_test_flag(&opts, OPT_AOC_REQUEST)
06293       && !ast_strlen_zero(opt_args[OPT_ARG_AOC_REQUEST])) {
06294       if (strchr(opt_args[OPT_ARG_AOC_REQUEST], 's')) {
06295          pri_sr_set_aoc_charging_request(sr, PRI_AOC_REQUEST_S);
06296       }
06297       if (strchr(opt_args[OPT_ARG_AOC_REQUEST], 'd')) {
06298          pri_sr_set_aoc_charging_request(sr, PRI_AOC_REQUEST_D);
06299       }
06300       if (strchr(opt_args[OPT_ARG_AOC_REQUEST], 'e')) {
06301          pri_sr_set_aoc_charging_request(sr, PRI_AOC_REQUEST_E);
06302       }
06303    }
06304 #endif   /* defined(HAVE_PRI_AOC_EVENTS) */
06305 
06306    /* Setup the user tag for party id's from this device for this call. */
06307    if (p->pri->append_msn_to_user_tag) {
06308       snprintf(p->user_tag, sizeof(p->user_tag), "%s_%s", p->pri->initial_user_tag,
06309          p->pri->nodetype == PRI_NETWORK
06310             ? c + p->stripmsd + dp_strip
06311             : S_COR(ast->connected.id.number.valid,
06312                ast->connected.id.number.str, ""));
06313    } else {
06314       ast_copy_string(p->user_tag, p->pri->initial_user_tag, sizeof(p->user_tag));
06315    }
06316 
06317    /*
06318     * Replace the caller id tag from the channel creation
06319     * with the actual tag value.
06320     */
06321    ast_free(ast->caller.id.tag);
06322    ast->caller.id.tag = ast_strdup(p->user_tag);
06323 
06324    ldp_strip = 0;
06325    prilocaldialplan = p->pri->localdialplan - 1;
06326    if ((l != NULL) && (prilocaldialplan == -2 || prilocaldialplan == -3)) { /* compute dynamically */
06327       if (strncmp(l, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) {
06328          if (prilocaldialplan == -2) {
06329             ldp_strip = strlen(p->pri->internationalprefix);
06330          }
06331          prilocaldialplan = PRI_INTERNATIONAL_ISDN;
06332       } else if (strncmp(l, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) {
06333          if (prilocaldialplan == -2) {
06334             ldp_strip = strlen(p->pri->nationalprefix);
06335          }
06336          prilocaldialplan = PRI_NATIONAL_ISDN;
06337       } else {
06338          prilocaldialplan = PRI_LOCAL_ISDN;
06339       }
06340    }
06341    if (l != NULL) {
06342       while (*l > '9' && *l != '*' && *l != '#') {
06343          switch (*l) {
06344          case 'U':
06345             prilocaldialplan = (PRI_TON_UNKNOWN << 4) | (prilocaldialplan & 0xf);
06346             break;
06347          case 'I':
06348             prilocaldialplan = (PRI_TON_INTERNATIONAL << 4) | (prilocaldialplan & 0xf);
06349             break;
06350          case 'N':
06351             prilocaldialplan = (PRI_TON_NATIONAL << 4) | (prilocaldialplan & 0xf);
06352             break;
06353          case 'L':
06354             prilocaldialplan = (PRI_TON_NET_SPECIFIC << 4) | (prilocaldialplan & 0xf);
06355             break;
06356          case 'S':
06357             prilocaldialplan = (PRI_TON_SUBSCRIBER << 4) | (prilocaldialplan & 0xf);
06358             break;
06359          case 'V':
06360             prilocaldialplan = (PRI_TON_ABBREVIATED << 4) | (prilocaldialplan & 0xf);
06361             break;
06362          case 'R':
06363             prilocaldialplan = (PRI_TON_RESERVED << 4) | (prilocaldialplan & 0xf);
06364             break;
06365          case 'u':
06366             prilocaldialplan = PRI_NPI_UNKNOWN | (prilocaldialplan & 0xf0);
06367             break;
06368          case 'e':
06369             prilocaldialplan = PRI_NPI_E163_E164 | (prilocaldialplan & 0xf0);
06370             break;
06371          case 'x':
06372             prilocaldialplan = PRI_NPI_X121 | (prilocaldialplan & 0xf0);
06373             break;
06374          case 'f':
06375             prilocaldialplan = PRI_NPI_F69 | (prilocaldialplan & 0xf0);
06376             break;
06377          case 'n':
06378             prilocaldialplan = PRI_NPI_NATIONAL | (prilocaldialplan & 0xf0);
06379             break;
06380          case 'p':
06381             prilocaldialplan = PRI_NPI_PRIVATE | (prilocaldialplan & 0xf0);
06382             break;
06383          case 'r':
06384             prilocaldialplan = PRI_NPI_RESERVED | (prilocaldialplan & 0xf0);
06385             break;
06386          default:
06387             if (isalpha(*l)) {
06388                ast_log(LOG_WARNING,
06389                   "Unrecognized prilocaldialplan %s modifier: %c\n",
06390                   *l > 'Z' ? "NPI" : "TON", *l);
06391             }
06392             break;
06393          }
06394          l++;
06395       }
06396    }
06397    pri_sr_set_caller(sr, l ? (l + ldp_strip) : NULL, n, prilocaldialplan,
06398       p->use_callingpres ? ast->connected.id.number.presentation : (l ? PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN : PRES_NUMBER_NOT_AVAILABLE));
06399 
06400 #if defined(HAVE_PRI_SUBADDR)
06401    if (ast->connected.id.subaddress.valid) {
06402       struct pri_party_subaddress subaddress;
06403 
06404       memset(&subaddress, 0, sizeof(subaddress));
06405       sig_pri_party_subaddress_from_ast(&subaddress, &ast->connected.id.subaddress);
06406       pri_sr_set_caller_subaddress(sr, &subaddress);
06407    }
06408 #endif   /* defined(HAVE_PRI_SUBADDR) */
06409 
06410    sig_pri_redirecting_update(p, ast);
06411 
06412 #ifdef SUPPORT_USERUSER
06413    /* User-user info */
06414    useruser = pbx_builtin_getvar_helper(p->owner, "USERUSERINFO");
06415    if (useruser)
06416       pri_sr_set_useruser(sr, useruser);
06417 #endif
06418 
06419 #if defined(HAVE_PRI_CCSS)
06420    if (ast_cc_is_recall(ast, &core_id, sig_pri_cc_type_name)) {
06421       struct ast_cc_monitor *monitor;
06422       char device_name[AST_CHANNEL_NAME];
06423 
06424       /* This is a CC recall call. */
06425       ast_channel_get_device_name(ast, device_name, sizeof(device_name));
06426       monitor = ast_cc_get_monitor_by_recall_core_id(core_id, device_name);
06427       if (monitor) {
06428          struct sig_pri_cc_monitor_instance *instance;
06429 
06430          instance = monitor->private_data;
06431 
06432          /* If this fails then we have monitor instance ambiguity. */
06433          ast_assert(p->pri == instance->pri);
06434 
06435          if (pri_cc_call(p->pri->pri, instance->cc_id, p->call, sr)) {
06436             /* The CC recall call failed for some reason. */
06437             ast_log(LOG_WARNING, "Unable to setup CC recall call to device %s\n",
06438                device_name);
06439             ao2_ref(monitor, -1);
06440             pri_rel(p->pri);
06441             pri_sr_free(sr);
06442             return -1;
06443          }
06444          ao2_ref(monitor, -1);
06445       } else {
06446          core_id = -1;
06447       }
06448    } else
06449 #endif   /* defined(HAVE_PRI_CCSS) */
06450    {
06451       core_id = -1;
06452    }
06453    if (core_id == -1 && pri_setup(p->pri->pri, p->call, sr)) {
06454       ast_log(LOG_WARNING, "Unable to setup call to %s (using %s)\n",
06455          c + p->stripmsd + dp_strip, dialplan2str(p->pri->dialplan));
06456       pri_rel(p->pri);
06457       pri_sr_free(sr);
06458       return -1;
06459    }
06460    pri_sr_free(sr);
06461    ast_setstate(ast, AST_STATE_DIALING);
06462    sig_pri_set_dialing(p, 1);
06463    pri_rel(p->pri);
06464    return 0;
06465 }

int sig_pri_cc_agent_callee_available ( struct ast_cc_agent agent  ) 

void sig_pri_cc_agent_destructor ( struct ast_cc_agent agent  ) 

int sig_pri_cc_agent_init ( struct ast_cc_agent agent,
struct sig_pri_chan pvt_chan 
)

int sig_pri_cc_agent_party_b_free ( struct ast_cc_agent agent  ) 

void sig_pri_cc_agent_req_ack ( struct ast_cc_agent agent  ) 

int sig_pri_cc_agent_start_monitoring ( struct ast_cc_agent agent  ) 

int sig_pri_cc_agent_start_offer_timer ( struct ast_cc_agent agent  ) 

int sig_pri_cc_agent_status_req ( struct ast_cc_agent agent  ) 

int sig_pri_cc_agent_stop_offer_timer ( struct ast_cc_agent agent  ) 

int sig_pri_cc_agent_stop_ringing ( struct ast_cc_agent agent  ) 

int sig_pri_cc_monitor_cancel_available_timer ( struct ast_cc_monitor monitor,
int *  sched_id 
)

void sig_pri_cc_monitor_destructor ( void *  monitor_pvt  ) 

int sig_pri_cc_monitor_req_cc ( struct ast_cc_monitor monitor,
int *  available_timer_id 
)

int sig_pri_cc_monitor_status_rsp ( struct ast_cc_monitor monitor,
enum ast_device_state  devstate 
)

int sig_pri_cc_monitor_suspend ( struct ast_cc_monitor monitor  ) 

int sig_pri_cc_monitor_unsuspend ( struct ast_cc_monitor monitor  ) 

void sig_pri_chan_alarm_notify ( struct sig_pri_chan p,
int  noalarm 
)

Definition at line 7193 of file sig_pri.c.

References ast_channel::_softhangup, ast_log(), AST_SOFTHANGUP_DEV, sig_pri_chan::call, LOG_WARNING, sig_pri_chan::owner, sig_pri_span::pri, sig_pri_chan::pri, pri_grab(), pri_rel(), and sig_pri_set_alarm().

Referenced by dahdi_handle_event(), and handle_init_event().

07194 {
07195    sig_pri_set_alarm(p, !noalarm);
07196    if (!noalarm) {
07197       if (!p->pri || !p->pri->pri || (pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0)) {
07198          /* T309 is not enabled : hangup calls when alarm occurs */
07199          if (p->call) {
07200             if (p->pri && p->pri->pri) {
07201                if (!pri_grab(p, p->pri)) {
07202                   pri_hangup(p->pri->pri, p->call, -1);
07203                   pri_destroycall(p->pri->pri, p->call);
07204                   p->call = NULL;
07205                   pri_rel(p->pri);
07206                } else
07207                   ast_log(LOG_WARNING, "Failed to grab PRI!\n");
07208             } else
07209                ast_log(LOG_WARNING, "The PRI Call has not been destroyed\n");
07210          }
07211          if (p->owner)
07212             p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
07213       }
07214    }
07215 }

void sig_pri_chan_delete ( struct sig_pri_chan doomed  ) 

Delete the sig_pri private channel structure.

Since:
1.8
Parameters:
doomed sig_pri private channel structure to delete.
Returns:
Nothing

Definition at line 7245 of file sig_pri.c.

References ast_free.

Referenced by destroy_dahdi_pvt().

07246 {
07247    ast_free(doomed);
07248 }

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 
)

Definition at line 7217 of file sig_pri.c.

References ast_calloc, and sig_pri_chan::pri.

07218 {
07219    struct sig_pri_chan *p;
07220 
07221    p = ast_calloc(1, sizeof(*p));
07222    if (!p)
07223       return p;
07224 
07225    p->logicalspan = logicalspan;
07226    p->prioffset = channo;
07227    p->mastertrunkgroup = trunkgroup;
07228 
07229    p->calls = callback;
07230    p->chan_pvt = pvt_data;
07231 
07232    p->pri = pri;
07233 
07234    return p;
07235 }

void sig_pri_cli_show_span ( int  fd,
int *  dchannels,
struct sig_pri_span pri 
)

Definition at line 7281 of file sig_pri.c.

References ast_cli(), build_status(), DAHDI_OVERLAPDIAL_INCOMING, sig_pri_span::dchanavail, sig_pri_span::dchans, free, sig_pri_span::overlapdial, sig_pri_span::pri, sig_pri_chan::pri, pri_order(), and status.

Referenced by handle_pri_show_span().

07282 {
07283    int x;
07284    char status[256];
07285 
07286    for (x = 0; x < SIG_PRI_NUM_DCHANS; x++) {
07287       if (pri->dchans[x]) {
07288 #ifdef PRI_DUMP_INFO_STR
07289          char *info_str = NULL;
07290 #endif
07291          ast_cli(fd, "%s D-channel: %d\n", pri_order(x), dchannels[x]);
07292          build_status(status, sizeof(status), pri->dchanavail[x], pri->dchans[x] == pri->pri);
07293          ast_cli(fd, "Status: %s\n", status);
07294 #ifdef PRI_DUMP_INFO_STR
07295          info_str = pri_dump_info_str(pri->pri);
07296          if (info_str) {
07297             ast_cli(fd, "%s", info_str);
07298             free(info_str);
07299          }
07300 #else
07301          pri_dump_info(pri->pri);
07302 #endif
07303          ast_cli(fd, "Overlap Recv: %s\n\n", (pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)?"Yes":"No");
07304          ast_cli(fd, "\n");
07305       }
07306    }
07307 }

void sig_pri_cli_show_spans ( int  fd,
int  span,
struct sig_pri_span pri 
)

Definition at line 7269 of file sig_pri.c.

References ast_cli(), build_status(), sig_pri_span::dchanavail, sig_pri_span::dchans, sig_pri_span::pri, sig_pri_chan::pri, and status.

Referenced by handle_pri_show_spans().

07270 {
07271    char status[256];
07272    int x;
07273    for (x = 0; x < SIG_PRI_NUM_DCHANS; x++) {
07274       if (pri->dchans[x]) {
07275          build_status(status, sizeof(status), pri->dchanavail[x], pri->dchans[x] == pri->pri);
07276          ast_cli(fd, "PRI span %d/%d: %s\n", span, x, status);
07277       }
07278    }
07279 }

int sig_pri_digit_begin ( struct sig_pri_chan pvt,
struct ast_channel ast,
char  digit 
)

Definition at line 6819 of file sig_pri.c.

References ast_channel::_state, ast_debug, ast_log(), AST_STATE_DIALING, sig_pri_chan::call, sig_pri_chan::dialdest, LOG_WARNING, sig_pri_span::pri, sig_pri_chan::pri, pri_grab(), pri_rel(), sig_pri_chan::proceeding, sig_pri_chan::setup_ack, and sig_pri_span::span.

Referenced by dahdi_digit_begin().

06820 {
06821    if ((ast->_state == AST_STATE_DIALING) && !pvt->proceeding) {
06822       if (pvt->setup_ack) {
06823          if (!pri_grab(pvt, pvt->pri)) {
06824             pri_information(pvt->pri->pri, pvt->call, digit);
06825             pri_rel(pvt->pri);
06826          } else {
06827             ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", pvt->pri->span);
06828          }
06829       } else if (strlen(pvt->dialdest) < sizeof(pvt->dialdest) - 1) {
06830          int res;
06831          ast_debug(1, "Queueing digit '%c' since setup_ack not yet received\n", digit);
06832          res = strlen(pvt->dialdest);
06833          pvt->dialdest[res++] = digit;
06834          pvt->dialdest[res] = '\0';
06835       }
06836       return 0;
06837    }
06838    return 1;
06839 }

void sig_pri_extract_called_num_subaddr ( struct sig_pri_chan p,
const char *  rdest,
char *  called,
size_t  called_buff_size 
)

Extract the called number and subaddress from the dial string.

Since:
1.8
Parameters:
p sig_pri channel structure.
rdest Dial string buffer to extract called number and subaddress.
called Buffer to fill with extracted <number>[:<subaddress>]
called_buff_size Size of buffer to fill.
Note:
Parsing must remain in sync with sig_pri_call().
Returns:
Nothing

Definition at line 5957 of file sig_pri.c.

References args, AST_APP_ARG, AST_DECLARE_APP_ARGS, AST_NONSTANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), ext, and sig_pri_chan::stripmsd.

Referenced by dahdi_request().

05958 {
05959    char *dial;
05960    char *number;
05961    char *subaddr;
05962    AST_DECLARE_APP_ARGS(args,
05963       AST_APP_ARG(group);  /* channel/group token */
05964       AST_APP_ARG(ext); /* extension token */
05965       //AST_APP_ARG(opts); /* options token */
05966       AST_APP_ARG(other);  /* Any remining unused arguments */
05967    );
05968 
05969    /* Get private copy of dial string and break it up. */
05970    dial = ast_strdupa(rdest);
05971    AST_NONSTANDARD_APP_ARGS(args, dial, '/');
05972 
05973    number = args.ext;
05974    if (!number) {
05975       number = "";
05976    }
05977 
05978    /* Find and extract dialed_subaddress */
05979    subaddr = strchr(number, ':');
05980    if (subaddr) {
05981       *subaddr++ = '\0';
05982 
05983       /* Skip subaddress type prefix. */
05984       switch (*subaddr) {
05985       case 'U':
05986       case 'u':
05987       case 'N':
05988       case 'n':
05989          ++subaddr;
05990          break;
05991       default:
05992          break;
05993       }
05994    }
05995 
05996    /* Skip type-of-number/dial-plan prefix characters. */
05997    if (strlen(number) < p->stripmsd) {
05998       number = "";
05999    } else {
06000       number += p->stripmsd;
06001       while (isalpha(*number)) {
06002          ++number;
06003       }
06004    }
06005 
06006    /* Fill buffer with extracted number and subaddress. */
06007    if (ast_strlen_zero(subaddr)) {
06008       /* Put in called number only since there is no subaddress. */
06009       snprintf(called, called_buff_size, "%s", number);
06010    } else {
06011       /* Put in called number and subaddress. */
06012       snprintf(called, called_buff_size, "%s:%s", number, subaddr);
06013    }
06014 }

void sig_pri_fixup ( struct ast_channel oldchan,
struct ast_channel newchan,
struct sig_pri_chan pchan 
)

Definition at line 7367 of file sig_pri.c.

References sig_pri_chan::owner.

07368 {
07369    if (pchan->owner == oldchan) {
07370       pchan->owner = newchan;
07371    }
07372 }

int sig_pri_hangup ( struct sig_pri_chan p,
struct ast_channel ast 
)

Definition at line 5855 of file sig_pri.c.

References sig_pri_chan::alerting, sig_pri_chan::alreadyhungup, ast_atomic_fetchadd_int(), ast_log(), sig_pri_chan::call, cause, sig_pri_chan::channel, sig_pri_chan::cid_name, sig_pri_chan::cid_num, sig_pri_chan::cid_subaddr, sig_pri_chan::exten, ast_channel::hangupcause, LOG_DEBUG, LOG_WARNING, sig_pri_chan::outgoing, sig_pri_chan::owner, pbx_builtin_getvar_helper(), sig_pri_span::pri, sig_pri_chan::pri, pri_grab(), pri_rel(), sig_pri_chan::proceeding, sig_pri_chan::progress, sig_pri_chan::setup_ack, sig_pri_set_dialing(), sig_pri_set_digital(), sig_pri_span_devstate_changed(), sig_pri_span::span, ast_channel::tech_pvt, and sig_pri_chan::user_tag.

Referenced by dahdi_hangup().

05856 {
05857    int res;
05858 #ifdef SUPPORT_USERUSER
05859    const char *useruser = pbx_builtin_getvar_helper(ast, "USERUSERINFO");
05860 #endif
05861 
05862    ast_log(LOG_DEBUG, "%s %d\n", __FUNCTION__, p->channel);
05863    if (!ast->tech_pvt) {
05864       ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
05865       return 0;
05866    }
05867 
05868    p->owner = NULL;
05869    p->outgoing = 0;
05870    sig_pri_set_digital(p, 0); /* push up to parent for EC*/
05871 #if defined(HAVE_PRI_CALL_WAITING)
05872    if (p->is_call_waiting) {
05873       p->is_call_waiting = 0;
05874       ast_atomic_fetchadd_int(&p->pri->num_call_waiting_calls, -1);
05875    }
05876 #endif   /* defined(HAVE_PRI_CALL_WAITING) */
05877    p->proceeding = 0;
05878    p->progress = 0;
05879    p->alerting = 0;
05880    p->setup_ack = 0;
05881    p->cid_num[0] = '\0';
05882    p->cid_subaddr[0] = '\0';
05883    p->cid_name[0] = '\0';
05884    p->user_tag[0] = '\0';
05885    p->exten[0] = '\0';
05886    sig_pri_set_dialing(p, 0);
05887 
05888    /* Make sure we have a call (or REALLY have a call in the case of a PRI) */
05889    if (!pri_grab(p, p->pri)) {
05890       if (p->call) {
05891          if (p->alreadyhungup) {
05892             ast_log(LOG_DEBUG, "Already hungup...  Calling hangup once, and clearing call\n");
05893 
05894 #ifdef SUPPORT_USERUSER
05895             pri_call_set_useruser(p->call, useruser);
05896 #endif
05897 
05898 #if defined(HAVE_PRI_AOC_EVENTS)
05899             if (p->holding_aoce) {
05900                pri_aoc_e_send(p->pri->pri, p->call, &p->aoc_e);
05901             }
05902 #endif   /* defined(HAVE_PRI_AOC_EVENTS) */
05903             pri_hangup(p->pri->pri, p->call, -1);
05904             p->call = NULL;
05905          } else {
05906             const char *cause = pbx_builtin_getvar_helper(ast,"PRI_CAUSE");
05907             int icause = ast->hangupcause ? ast->hangupcause : -1;
05908             ast_log(LOG_DEBUG, "Not yet hungup...  Calling hangup once with icause, and clearing call\n");
05909 
05910 #ifdef SUPPORT_USERUSER
05911             pri_call_set_useruser(p->call, useruser);
05912 #endif
05913 
05914             p->alreadyhungup = 1;
05915             if (cause) {
05916                if (atoi(cause))
05917                   icause = atoi(cause);
05918             }
05919 #if defined(HAVE_PRI_AOC_EVENTS)
05920             if (p->holding_aoce) {
05921                pri_aoc_e_send(p->pri->pri, p->call, &p->aoc_e);
05922             }
05923 #endif   /* defined(HAVE_PRI_AOC_EVENTS) */
05924             pri_hangup(p->pri->pri, p->call, icause);
05925          }
05926       }
05927       sig_pri_span_devstate_changed(p->pri);
05928       pri_rel(p->pri);
05929       res = 0;
05930    } else {
05931       ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->pri->span);
05932       res = -1;
05933    }
05934 
05935 #if defined(HAVE_PRI_AOC_EVENTS)
05936    p->aoc_s_request_invoke_id_valid = 0;
05937    p->holding_aoce = 0;
05938    p->waiting_for_aoce = 0;
05939 #endif   /* defined(HAVE_PRI_AOC_EVENTS) */
05940    ast->tech_pvt = NULL;
05941    return res;
05942 }

int sig_pri_indicate ( struct sig_pri_chan p,
struct ast_channel chan,
int  condition,
const void *  data,
size_t  datalen 
)

Definition at line 6467 of file sig_pri.c.

References ast_channel::_softhangup, ast_channel::_state, sig_pri_chan::alerting, AST_AOC_D, ast_aoc_decode(), ast_aoc_destroy_decoded(), AST_AOC_E, ast_aoc_get_msg_type(), ast_aoc_get_termination_request(), AST_AOC_REQUEST, AST_AOC_S, AST_CAUSE_CONGESTION, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_USER_BUSY, AST_CONTROL_AOC, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HOLD, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_REDIRECTING, AST_CONTROL_RINGING, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, ast_debug, ast_log(), ast_moh_start(), ast_moh_stop(), ast_setstate(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, sig_pri_chan::call, ast_channel::connected, sig_pri_chan::digital, ast_channel::hangupcause, ast_party_connected_line::id, LOG_DEBUG, LOG_WARNING, sig_pri_chan::mohinterpret, ast_channel::name, sig_pri_chan::no_b_channel, sig_pri_chan::outgoing, sig_pri_span::pri, sig_pri_chan::pri, pri_grab(), pri_rel(), sig_pri_chan::priindication_oob, sig_pri_chan::prioffset, sig_pri_chan::proceeding, sig_pri_chan::progress, PVT_TO_CHANNEL(), SIG_PRI_AOC_GRANT_D, SIG_PRI_AOC_GRANT_E, SIG_PRI_AOC_GRANT_S, sig_pri_party_id_from_ast(), sig_pri_play_tone(), sig_pri_redirecting_update(), sig_pri_set_dialing(), sig_pri_set_digital(), SIG_PRI_TONE_BUSY, SIG_PRI_TONE_CONGESTION, SIG_PRI_TONE_RINGTONE, and sig_pri_span::span.

Referenced by dahdi_indicate().

06468 {
06469    int res = -1;
06470 
06471    switch (condition) {
06472    case AST_CONTROL_BUSY:
06473       if (p->priindication_oob || p->no_b_channel) {
06474          chan->hangupcause = AST_CAUSE_USER_BUSY;
06475          chan->_softhangup |= AST_SOFTHANGUP_DEV;
06476          res = 0;
06477       } else if (!p->progress && p->pri && !p->outgoing) {
06478          if (p->pri->pri) {
06479             if (!pri_grab(p, p->pri)) {
06480 #ifdef HAVE_PRI_PROG_W_CAUSE
06481                pri_progress_with_cause(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1, PRI_CAUSE_USER_BUSY); /* cause = 17 */
06482 #else
06483                pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
06484 #endif
06485                pri_rel(p->pri);
06486             } else {
06487                ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->pri->span);
06488             }
06489          }
06490          p->progress = 1;
06491          res = sig_pri_play_tone(p, SIG_PRI_TONE_BUSY);
06492       }
06493       break;
06494    case AST_CONTROL_RINGING:
06495       if ((!p->alerting) && p->pri && !p->outgoing && (chan->_state != AST_STATE_UP)) {
06496          if (p->pri->pri) {
06497             if (!pri_grab(p, p->pri)) {
06498                pri_acknowledge(p->pri->pri,p->call, PVT_TO_CHANNEL(p),
06499                   p->no_b_channel || p->digital ? 0 : 1);
06500                pri_rel(p->pri);
06501             } else {
06502                ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->pri->span);
06503             }
06504          }
06505          p->alerting = 1;
06506       }
06507       res = sig_pri_play_tone(p, SIG_PRI_TONE_RINGTONE);
06508       if (chan->_state != AST_STATE_UP) {
06509          if (chan->_state != AST_STATE_RING)
06510             ast_setstate(chan, AST_STATE_RINGING);
06511       }
06512       break;
06513    case AST_CONTROL_PROCEEDING:
06514       ast_debug(1,"Received AST_CONTROL_PROCEEDING on %s\n",chan->name);
06515       if (!p->proceeding && p->pri && !p->outgoing) {
06516          if (p->pri->pri) {
06517             if (!pri_grab(p, p->pri)) {
06518                pri_proceeding(p->pri->pri,p->call, PVT_TO_CHANNEL(p),
06519                   p->no_b_channel || p->digital ? 0 : 1);
06520                p->proceeding = 1;
06521                if (!p->no_b_channel && !p->digital) {
06522                   sig_pri_set_dialing(p, 0);
06523                }
06524                pri_rel(p->pri);
06525             } else {
06526                ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->pri->span);
06527             }
06528          }
06529       }
06530       /* don't continue in ast_indicate */
06531       res = 0;
06532       break;
06533    case AST_CONTROL_PROGRESS:
06534       ast_debug(1,"Received AST_CONTROL_PROGRESS on %s\n",chan->name);
06535       sig_pri_set_digital(p, 0); /* Digital-only calls isn't allowing any inband progress messages */
06536       if (!p->progress && !p->alerting && p->pri && !p->outgoing && !p->no_b_channel) {
06537          if (p->pri->pri) {
06538             if (!pri_grab(p, p->pri)) {
06539 #ifdef HAVE_PRI_PROG_W_CAUSE
06540                pri_progress_with_cause(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1, -1);  /* no cause at all */
06541 #else
06542                pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
06543 #endif
06544                pri_rel(p->pri);
06545             } else {
06546                ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->pri->span);
06547             }
06548          }
06549          p->progress = 1;
06550       }
06551       /* don't continue in ast_indicate */
06552       res = 0;
06553       break;
06554    case AST_CONTROL_CONGESTION:
06555       chan->hangupcause = AST_CAUSE_CONGESTION;
06556       if (p->priindication_oob || p->no_b_channel) {
06557          chan->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
06558          chan->_softhangup |= AST_SOFTHANGUP_DEV;
06559          res = 0;
06560       } else if (!p->progress && p->pri && !p->outgoing) {
06561          if (p->pri->pri) {
06562             if (!pri_grab(p, p->pri)) {
06563 #ifdef HAVE_PRI_PROG_W_CAUSE
06564                pri_progress_with_cause(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1, PRI_CAUSE_SWITCH_CONGESTION); /* cause = 42 */
06565 #else
06566                pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
06567 #endif
06568                pri_rel(p->pri);
06569             } else {
06570                ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->pri->span);
06571             }
06572          }
06573          p->progress = 1;
06574          res = sig_pri_play_tone(p, SIG_PRI_TONE_CONGESTION);
06575       }
06576       break;
06577    case AST_CONTROL_HOLD:
06578       if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) {
06579          if (!pri_grab(p, p->pri)) {
06580             res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_HOLD);
06581             pri_rel(p->pri);
06582          } else {
06583             ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->pri->span);
06584          }
06585       } else
06586          ast_moh_start(chan, data, p->mohinterpret);
06587       break;
06588    case AST_CONTROL_UNHOLD:
06589       if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) {
06590          if (!pri_grab(p, p->pri)) {
06591             res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_RETRIEVAL);
06592             pri_rel(p->pri);
06593          }
06594       } else
06595          ast_moh_stop(chan);
06596       break;
06597    case AST_CONTROL_SRCUPDATE:
06598       res = 0;
06599       break;
06600    case -1:
06601       res = sig_pri_play_tone(p, -1);
06602       break;
06603    case AST_CONTROL_CONNECTED_LINE:
06604       ast_debug(1, "Received AST_CONTROL_CONNECTED_LINE on %s\n", chan->name);
06605       if (p->pri && !pri_grab(p, p->pri)) {
06606          struct pri_party_connected_line connected;
06607 
06608          memset(&connected, 0, sizeof(connected));
06609          sig_pri_party_id_from_ast(&connected.id, &chan->connected.id);
06610 
06611          pri_connected_line_update(p->pri->pri, p->call, &connected);
06612          pri_rel(p->pri);
06613       }
06614       break;
06615    case AST_CONTROL_REDIRECTING:
06616       ast_debug(1, "Received AST_CONTROL_REDIRECTING on %s\n", chan->name);
06617       if (p->pri && !pri_grab(p, p->pri)) {
06618          sig_pri_redirecting_update(p, chan);
06619          pri_rel(p->pri);
06620       }
06621       break;
06622    case AST_CONTROL_AOC:
06623 #if defined(HAVE_PRI_AOC_EVENTS)
06624       {
06625          struct ast_aoc_decoded *decoded
06626             = ast_aoc_decode((struct ast_aoc_encoded *) data, datalen, chan);
06627          ast_debug(1, "Received AST_CONTROL_AOC on %s\n", chan->name);
06628          if (decoded && p->pri && !pri_grab(p, p->pri)) {
06629             switch (ast_aoc_get_msg_type(decoded)) {
06630             case AST_AOC_S:
06631                if (p->pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_S) {
06632                   sig_pri_aoc_s_from_ast(p, decoded);
06633                }
06634                break;
06635             case AST_AOC_D:
06636                if (p->pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_D) {
06637                   sig_pri_aoc_d_from_ast(p, decoded);
06638                }
06639                break;
06640             case AST_AOC_E:
06641                if (p->pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_E) {
06642                   sig_pri_aoc_e_from_ast(p, decoded);
06643                }
06644                /* if hangup was delayed for this AOC-E msg, waiting_for_aoc
06645                 * will be set.  A hangup is already occuring via a timeout during
06646                 * this delay.  Instead of waiting for that timeout to occur, go ahead
06647                 * and initiate the softhangup since the delay is no longer necessary */
06648                if (p->waiting_for_aoce) {
06649                   p->waiting_for_aoce = 0;
06650                   ast_log(LOG_DEBUG,
06651                      "Received final AOC-E msg, continue with hangup on %s\n",
06652                      chan->name);
06653                   ast_softhangup_nolock(chan, AST_SOFTHANGUP_DEV);
06654                }
06655                break;
06656             case AST_AOC_REQUEST:
06657                /* We do not pass through AOC requests, So unless this
06658                 * is an AOC termination request it will be ignored */
06659                if (ast_aoc_get_termination_request(decoded)) {
06660                   pri_hangup(p->pri->pri, p->call, -1);
06661                }
06662                break;
06663             default:
06664                break;
06665             }
06666             pri_rel(p->pri);
06667          }
06668          ast_aoc_destroy_decoded(decoded);
06669       }
06670 #endif   /* defined(HAVE_PRI_AOC_EVENTS) */
06671       break;
06672    }
06673 
06674    return res;
06675 }

void sig_pri_init_pri ( struct sig_pri_span pri  ) 

Definition at line 5842 of file sig_pri.c.

References ast_mutex_init, AST_PTHREADT_NULL, and SIG_PRI_NUM_DCHANS.

Referenced by load_module().

05843 {
05844    int i;
05845 
05846    memset(pri, 0, sizeof(*pri));
05847 
05848    ast_mutex_init(&pri->lock);
05849 
05850    pri->master = AST_PTHREADT_NULL;
05851    for (i = 0; i < SIG_PRI_NUM_DCHANS; i++)
05852       pri->fds[i] = -1;
05853 }

int sig_pri_load ( const char *  cc_type_name  ) 

Load the sig_pri submodule.

Since:
1.8
Parameters:
cc_type_name CC type name to use when looking up agent/monitor.
Return values:
0 on success.
-1 on error.

Definition at line 7942 of file sig_pri.c.

References ao2_container_alloc.

Referenced by load_module().

07943 {
07944 #if defined(HAVE_PRI_CCSS)
07945    sig_pri_cc_type_name = cc_type_name;
07946    sig_pri_cc_monitors = ao2_container_alloc(37, sig_pri_cc_monitor_instance_hash_fn,
07947       sig_pri_cc_monitor_instance_cmp_fn);
07948    if (!sig_pri_cc_monitors) {
07949       return -1;
07950    }
07951 #endif   /* defined(HAVE_PRI_CCSS) */
07952    return 0;
07953 }

struct ast_channel* sig_pri_request ( struct sig_pri_chan p,
enum sig_pri_law  law,
const struct ast_channel requestor,
int  transfercapability 
)

Definition at line 912 of file sig_pri.c.

References ast_log(), AST_STATE_RESERVED, sig_pri_chan::channel, sig_pri_chan::exten, LOG_DEBUG, sig_pri_chan::outgoing, and sig_pri_new_ast_channel().

Referenced by dahdi_request(), and pri_dchannel().

00913 {
00914    struct ast_channel *ast;
00915 
00916    ast_log(LOG_DEBUG, "%s %d\n", __FUNCTION__, p->channel);
00917 
00918    p->outgoing = 1;
00919    ast = sig_pri_new_ast_channel(p, AST_STATE_RESERVED, law, transfercapability, p->exten, requestor);
00920    if (!ast) {
00921       p->outgoing = 0;
00922    }
00923    return ast;
00924 }

int sig_pri_start_pri ( struct sig_pri_span pri  ) 

Definition at line 7015 of file sig_pri.c.

References ARRAY_LEN, AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_MWI, ast_event_subscribe(), ast_event_unsubscribe(), ast_log(), ast_mutex_init, ast_str_alloca, ast_str_buffer(), ast_str_set(), ast_strip(), ast_strlen_zero(), sig_pri_span::dchans, sig_pri_span::enable_service_message_support, sig_pri_span::fds, HAVE_PRI_SERVICE_MESSAGES, sig_pri_span::lock, LOG_ERROR, sig_pri_span::nodetype, sig_pri_span::sig, SIG_BRI, SIG_BRI_PTMP, SIG_PRI_NUM_DCHANS, sig_pri_sort_pri_chans(), sig_pri_span::span, strsep(), and sig_pri_span::switchtype.

Referenced by setup_dahdi_int().

07016 {
07017    int x;
07018    int i;
07019 #if defined(HAVE_PRI_MWI)
07020    char *saveptr;
07021    char *mbox_number;
07022    char *mbox_context;
07023    struct ast_str *mwi_description = ast_str_alloca(64);
07024 #endif   /* defined(HAVE_PRI_MWI) */
07025 
07026 #if defined(HAVE_PRI_MWI)
07027    /* Prepare the mbox[] for use. */
07028    for (i = 0; i < ARRAY_LEN(pri->mbox); ++i) {
07029       if (pri->mbox[i].sub) {
07030          pri->mbox[i].sub = ast_event_unsubscribe(pri->mbox[i].sub);
07031       }
07032    }
07033 #endif   /* defined(HAVE_PRI_MWI) */
07034 
07035    ast_mutex_init(&pri->lock);
07036    sig_pri_sort_pri_chans(pri);
07037 
07038 #if defined(HAVE_PRI_MWI)
07039    /*
07040     * Split the mwi_mailboxes configuration string into the mbox[]:
07041     * mailbox_number[@context]{,mailbox_number[@context]}
07042     */
07043    i = 0;
07044    saveptr = pri->mwi_mailboxes;
07045    while (i < ARRAY_LEN(pri->mbox)) {
07046       mbox_number = strsep(&saveptr, ",");
07047       if (!mbox_number) {
07048          break;
07049       }
07050       /* Split the mailbox_number and context */
07051       mbox_context = strchr(mbox_number, '@');
07052       if (mbox_context) {
07053          *mbox_context++ = '\0';
07054          mbox_context = ast_strip(mbox_context);
07055       }
07056       mbox_number = ast_strip(mbox_number);
07057       if (ast_strlen_zero(mbox_number)) {
07058          /* There is no mailbox number.  Skip it. */
07059          continue;
07060       }
07061       if (ast_strlen_zero(mbox_context)) {
07062          /* There was no context so use the default. */
07063          mbox_context = "default";
07064       }
07065 
07066       /* Fill the mbox[] element. */
07067       ast_str_set(&mwi_description, -1, "%s span %d[%d] MWI mailbox %s@%s",
07068          sig_pri_cc_type_name, pri->span, i, mbox_number, mbox_context);
07069       pri->mbox[i].sub = ast_event_subscribe(AST_EVENT_MWI, sig_pri_mwi_event_cb,
07070          ast_str_buffer(mwi_description), pri,
07071          AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mbox_number,
07072          AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, mbox_context,
07073          AST_EVENT_IE_END);
07074       if (!pri->mbox[i].sub) {
07075          ast_log(LOG_ERROR, "%s span %d could not subscribe to MWI events for %s@%s.",
07076             sig_pri_cc_type_name, pri->span, mbox_number, mbox_context);
07077          continue;
07078       }
07079       pri->mbox[i].number = mbox_number;
07080       pri->mbox[i].context = mbox_context;
07081       ++i;
07082    }
07083 #endif   /* defined(HAVE_PRI_MWI) */
07084 
07085    for (i = 0; i < SIG_PRI_NUM_DCHANS; i++) {
07086       if (pri->fds[i] == -1) {
07087          break;
07088       }
07089 
07090       switch (pri->sig) {
07091       case SIG_BRI:
07092          pri->dchans[i] = pri_new_bri(pri->fds[i], 1, pri->nodetype, pri->switchtype);
07093          break;
07094       case SIG_BRI_PTMP:
07095          pri->dchans[i] = pri_new_bri(pri->fds[i], 0, pri->nodetype, pri->switchtype);
07096          break;
07097       default:
07098          pri->dchans[i] = pri_new(pri->fds[i], pri->nodetype, pri->switchtype);
07099 #if defined(HAVE_PRI_SERVICE_MESSAGES)
07100          if (pri->enable_service_message_support) {
07101             pri_set_service_message_support(pri->dchans[i], 1);
07102          }
07103 #endif   /* defined(HAVE_PRI_SERVICE_MESSAGES) */
07104          break;
07105       }
07106 
07107       pri_set_overlapdial(pri->dchans[i], (pri->overlapdial & DAHDI_OVERLAPDIAL_OUTGOING) ? 1 : 0);
07108 #ifdef HAVE_PRI_PROG_W_CAUSE
07109       pri_set_chan_mapping_logical(pri->dchans[i], pri->qsigchannelmapping == DAHDI_CHAN_MAPPING_LOGICAL);
07110 #endif
07111 #ifdef HAVE_PRI_INBANDDISCONNECT
07112       pri_set_inbanddisconnect(pri->dchans[i], pri->inbanddisconnect);
07113 #endif
07114       /* Enslave to master if appropriate */
07115       if (i)
07116          pri_enslave(pri->dchans[0], pri->dchans[i]);
07117       if (!pri->dchans[i]) {
07118          if (pri->fds[i] > 0)
07119             close(pri->fds[i]);
07120          pri->fds[i] = -1;
07121          ast_log(LOG_ERROR, "Unable to create PRI structure\n");
07122          return -1;
07123       }
07124       pri_set_debug(pri->dchans[i], SIG_PRI_DEBUG_DEFAULT);
07125       pri_set_nsf(pri->dchans[i], pri->nsf);
07126 #ifdef PRI_GETSET_TIMERS
07127       for (x = 0; x < PRI_MAX_TIMERS; x++) {
07128          if (pri->pritimers[x] != 0)
07129             pri_set_timer(pri->dchans[i], x, pri->pritimers[x]);
07130       }
07131 #endif
07132    }
07133 
07134    /* Assume primary is the one we use */
07135    pri->pri = pri->dchans[0];
07136 
07137 #if defined(HAVE_PRI_CALL_HOLD)
07138    pri_hold_enable(pri->pri, 1);
07139 #endif   /* defined(HAVE_PRI_CALL_HOLD) */
07140 #if defined(HAVE_PRI_CALL_REROUTING)
07141    pri_reroute_enable(pri->pri, 1);
07142 #endif   /* defined(HAVE_PRI_CALL_REROUTING) */
07143 #if defined(HAVE_PRI_HANGUP_FIX)
07144    pri_hangup_fix_enable(pri->pri, 1);
07145 #endif   /* defined(HAVE_PRI_HANGUP_FIX) */
07146 #if defined(HAVE_PRI_CCSS)
07147    pri_cc_enable(pri->pri, 1);
07148    pri_cc_recall_mode(pri->pri, pri->cc_ptmp_recall_mode);
07149    pri_cc_retain_signaling_req(pri->pri, pri->cc_qsig_signaling_link_req);
07150    pri_cc_retain_signaling_rsp(pri->pri, pri->cc_qsig_signaling_link_rsp);
07151 #endif   /* defined(HAVE_PRI_CCSS) */
07152 #if defined(HAVE_PRI_TRANSFER)
07153    pri_transfer_enable(pri->pri, 1);
07154 #endif   /* defined(HAVE_PRI_TRANSFER) */
07155 #if defined(HAVE_PRI_AOC_EVENTS)
07156    pri_aoc_events_enable(pri->pri, 1);
07157 #endif   /* defined(HAVE_PRI_AOC_EVENTS) */
07158 #if defined(HAVE_PRI_CALL_WAITING)
07159    pri_connect_ack_enable(pri->pri, 1);
07160 #endif   /* defined(HAVE_PRI_CALL_WAITING) */
07161 #if defined(HAVE_PRI_MCID)
07162    pri_mcid_enable(pri->pri, 1);
07163 #endif   /* defined(HAVE_PRI_MCID) */
07164 
07165    pri->resetpos = -1;
07166    if (ast_pthread_create_background(&pri->master, NULL, pri_dchannel, pri)) {
07167       for (i = 0; i < SIG_PRI_NUM_DCHANS; i++) {
07168          if (!pri->dchans[i])
07169             break;
07170          if (pri->fds[i] > 0)
07171             close(pri->fds[i]);
07172          pri->fds[i] = -1;
07173       }
07174       ast_log(LOG_ERROR, "Unable to spawn D-channel: %s\n", strerror(errno));
07175       return -1;
07176    }
07177 
07178 #if defined(HAVE_PRI_MWI)
07179    /*
07180     * Send the initial MWI indications from the event cache for this span.
07181     *
07182     * If we were loaded after app_voicemail the event would already be in
07183     * the cache.  If we were loaded before app_voicemail the event would not
07184     * be in the cache yet and app_voicemail will send the event when it
07185     * gets loaded.
07186     */
07187    sig_pri_mwi_cache_update(pri);
07188 #endif   /* defined(HAVE_PRI_MWI) */
07189 
07190    return 0;
07191 }

void sig_pri_stop_pri ( struct sig_pri_span pri  ) 

Stop PRI span.

Since:
1.8
Parameters:
pri Asterisk D channel control structure.
Returns:
Nothing

Definition at line 6950 of file sig_pri.c.

References ARRAY_LEN, and ast_event_unsubscribe().

Referenced by __unload_module().

06951 {
06952 #if defined(HAVE_PRI_MWI)
06953    int idx;
06954 #endif   /* defined(HAVE_PRI_MWI) */
06955 
06956 #if defined(HAVE_PRI_MWI)
06957    for (idx = 0; idx < ARRAY_LEN(pri->mbox); ++idx) {
06958       if (pri->mbox[idx].sub) {
06959          pri->mbox[idx].sub = ast_event_unsubscribe(pri->mbox[idx].sub);
06960       }
06961    }
06962 #endif   /* defined(HAVE_PRI_MWI) */
06963 }

void sig_pri_unload ( void   ) 

Unload the sig_pri submodule.

Since:
1.8
Returns:
Nothing

Definition at line 7961 of file sig_pri.c.

References ao2_ref.

Referenced by __unload_module().

07962 {
07963 #if defined(HAVE_PRI_CCSS)
07964    if (sig_pri_cc_monitors) {
07965       ao2_ref(sig_pri_cc_monitors, -1);
07966       sig_pri_cc_monitors = NULL;
07967    }
07968 #endif   /* defined(HAVE_PRI_CCSS) */
07969 }


Variable Documentation

const char dahdi_db[] = "dahdi/registry" [static]

The AstDB family.

Definition at line 168 of file sig_pri.h.

Referenced by destroy_all_channels().


Generated on Wed Apr 6 11:30:11 2011 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7