Mon Mar 19 11:30:55 2012

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_mbox
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
#define SIG_PRI_MAX_CHANNELS   672
#define SIG_PRI_MAX_MWI_CONTEXT_LEN   10
#define SIG_PRI_MAX_MWI_MAILBOX_STR
 Maximum mwi_mailbox string length.
#define SIG_PRI_MAX_MWI_MAILBOXES   8
#define SIG_PRI_MAX_MWI_MBOX_NUMBER_LEN   10
#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_call_level {
  SIG_PRI_CALL_LEVEL_IDLE, SIG_PRI_CALL_LEVEL_SETUP, SIG_PRI_CALL_LEVEL_OVERLAP, SIG_PRI_CALL_LEVEL_PROCEEDING,
  SIG_PRI_CALL_LEVEL_ALERTING, SIG_PRI_CALL_LEVEL_CONNECT
}
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)
 Alert the caller that it is time to try recalling.
void sig_pri_cc_agent_destructor (struct ast_cc_agent *agent)
 Destroy private data on the agent.
int sig_pri_cc_agent_init (struct ast_cc_agent *agent, struct sig_pri_chan *pvt_chan)
 PRI CC agent initialization.
int sig_pri_cc_agent_party_b_free (struct ast_cc_agent *agent)
 Let the caller know that the callee has become free but that the caller cannot attempt to call back because he is either busy or there is congestion on his line.
void sig_pri_cc_agent_req_rsp (struct ast_cc_agent *agent, enum ast_cc_agent_response_reason reason)
 Response to a CC request.
int sig_pri_cc_agent_start_monitoring (struct ast_cc_agent *agent)
 Begin monitoring a busy device.
int sig_pri_cc_agent_start_offer_timer (struct ast_cc_agent *agent)
 Start the offer timer.
int sig_pri_cc_agent_status_req (struct ast_cc_agent *agent)
 Request the status of the agent's device.
int sig_pri_cc_agent_stop_offer_timer (struct ast_cc_agent *agent)
 Stop the offer timer.
int sig_pri_cc_agent_stop_ringing (struct ast_cc_agent *agent)
 Request for an agent's phone to stop ringing.
int sig_pri_cc_monitor_cancel_available_timer (struct ast_cc_monitor *monitor, int *sched_id)
 Cancel the running available timer.
void sig_pri_cc_monitor_destructor (void *monitor_pvt)
 Destroy PRI private data on the monitor.
int sig_pri_cc_monitor_req_cc (struct ast_cc_monitor *monitor, int *available_timer_id)
 Request CCSS.
int sig_pri_cc_monitor_status_rsp (struct ast_cc_monitor *monitor, enum ast_device_state devstate)
 Status response to an ast_cc_monitor_status_request().
int sig_pri_cc_monitor_suspend (struct ast_cc_monitor *monitor)
 Suspend monitoring.
int sig_pri_cc_monitor_unsuspend (struct ast_cc_monitor *monitor)
 Unsuspend monitoring.
void sig_pri_chan_alarm_notify (struct sig_pri_chan *p, int noalarm)
 Notify new alarm status.
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_channels (int fd, struct sig_pri_span *pri)
void sig_pri_cli_show_channels_header (int fd)
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_is_chan_available (struct sig_pri_chan *pvt)
 Determine if a private channel structure is available.
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)
void sig_pri_set_alarm (struct sig_pri_chan *p, int in_alarm)
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 167 of file sig_pri.h.

#define DAHDI_CHAN_MAPPING_PHYSICAL   0

Definition at line 166 of file sig_pri.h.

Referenced by dahdi_chan_conf_default().

#define DAHDI_OVERLAPDIAL_BOTH   (DAHDI_OVERLAPDIAL_INCOMING|DAHDI_OVERLAPDIAL_OUTGOING)

Definition at line 173 of file sig_pri.h.

#define DAHDI_OVERLAPDIAL_INCOMING   2

Definition at line 172 of file sig_pri.h.

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

#define DAHDI_OVERLAPDIAL_NONE   0

Definition at line 170 of file sig_pri.h.

#define DAHDI_OVERLAPDIAL_OUTGOING   1

Definition at line 171 of file sig_pri.h.

Referenced by dahdi_read().

#define SIG_BRI   (0x2000000 | DAHDI_SIG_CLEAR)

Definition at line 162 of file sig_pri.h.

#define SIG_BRI_PTMP   (0X4000000 | DAHDI_SIG_CLEAR)

Definition at line 163 of file sig_pri.h.

#define SIG_PRI   DAHDI_SIG_CLEAR

Definition at line 161 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_aoc_request_from_pri(), 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_aoc_request_from_pri(), 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_aoc_request_from_pri(), 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_CC | 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 42 of file sig_pri.h.

Referenced by handle_pri_debug().

#define SIG_PRI_DEBUG_NORMAL

Value:

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

Definition at line 37 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 159 of file sig_pri.h.

#define SIG_PRI_MAX_MWI_CONTEXT_LEN   10

Typical maximum length of mwi mailbox context

Definition at line 299 of file sig_pri.h.

#define SIG_PRI_MAX_MWI_MAILBOX_STR

Value:

Maximum mwi_mailbox string length.

max_length = mailboxes * (mbox_number + '@' + context + ',') The last ',' is a null terminator instead.

Definition at line 306 of file sig_pri.h.

#define SIG_PRI_MAX_MWI_MAILBOXES   8

Maximum number of mailboxes per span.

Definition at line 295 of file sig_pri.h.

#define SIG_PRI_MAX_MWI_MBOX_NUMBER_LEN   10

Typical maximum length of mwi mailbox number

Definition at line 297 of file sig_pri.h.

#define SIG_PRI_NUM_DCHANS   4

No more than 4 d-channels

Definition at line 158 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 191 of file sig_pri.h.

#define SRVST_DBKEY   "service-state"

Persistent Service State.

Definition at line 177 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 189 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 185 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 187 of file sig_pri.h.

Referenced by pri_check_restart().

#define SRVST_TYPE_OOS   "O"

The out-of-service SERVICE state.

Definition at line 179 of file sig_pri.h.


Enumeration Type Documentation

enum sig_pri_call_level

Call establishment life cycle level for simple comparisons.

Enumerator:
SIG_PRI_CALL_LEVEL_IDLE  Call does not exist.
SIG_PRI_CALL_LEVEL_SETUP  Call is present but has no response yet. (SETUP)
SIG_PRI_CALL_LEVEL_OVERLAP  Call is collecting digits for overlap dialing. (SETUP ACKNOWLEDGE)
SIG_PRI_CALL_LEVEL_PROCEEDING  Call routing is happening. (PROCEEDING)
SIG_PRI_CALL_LEVEL_ALERTING  Called party is being alerted of the call. (ALERTING)
SIG_PRI_CALL_LEVEL_CONNECT  Call is connected/answered. (CONNECT)

Definition at line 87 of file sig_pri.h.

00087                         {
00088    /*! Call does not exist. */
00089    SIG_PRI_CALL_LEVEL_IDLE,
00090    /*! Call is present but has no response yet. (SETUP) */
00091    SIG_PRI_CALL_LEVEL_SETUP,
00092    /*! Call is collecting digits for overlap dialing. (SETUP ACKNOWLEDGE) */
00093    SIG_PRI_CALL_LEVEL_OVERLAP,
00094    /*! Call routing is happening. (PROCEEDING) */
00095    SIG_PRI_CALL_LEVEL_PROCEEDING,
00096    /*! Called party is being alerted of the call. (ALERTING) */
00097    SIG_PRI_CALL_LEVEL_ALERTING,
00098    /*! Call is connected/answered. (CONNECT) */
00099    SIG_PRI_CALL_LEVEL_CONNECT,
00100 };

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 1967 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().

01968 {
01969    pri->dchanavail[index] &= ~(DCHAN_NOTINALARM | DCHAN_UP);
01970    if (!before_start_pri) {
01971       pri_find_dchan(pri);
01972    }
01973 }

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

Definition at line 1975 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().

01976 {
01977    pri->dchanavail[index] |= DCHAN_NOTINALARM;
01978    if (!before_start_pri)
01979       pri_restart(pri->dchans[index]);
01980 }

int pri_is_up ( struct sig_pri_span pri  ) 

Definition at line 995 of file sig_pri.c.

References DCHAN_AVAILABLE, sig_pri_span::dchanavail, and SIG_PRI_NUM_DCHANS.

Referenced by pri_dchannel().

00996 {
00997    int x;
00998    for (x = 0; x < SIG_PRI_NUM_DCHANS; x++) {
00999       if (pri->dchanavail[x] == DCHAN_AVAILABLE)
01000          return 1;
01001    }
01002    return 0;
01003 }

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

Definition at line 7877 of file sig_pri.c.

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

07878 {
07879    int channel = PVT_TO_CHANNEL(p);
07880    int span = PRI_SPAN(channel);
07881 
07882    return pri_maintenance_service(pri, span, channel, changestatus);
07883 }

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 7855 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(), and sig_pri_unlock_private().

Referenced by dahdi_send_callrerouting_facility_exec().

07856 {
07857    int res = -1;
07858 
07859    sig_pri_lock_private(p);
07860 
07861    if (!p->pri || !p->call) {
07862       ast_log(LOG_DEBUG, "Unable to find pri or call on channel!\n");
07863       sig_pri_unlock_private(p);
07864       return -1;
07865    }
07866 
07867    pri_grab(p, p->pri);
07868    res = pri_callrerouting_facility(p->pri->pri, p->call, destination, original, reason);
07869    pri_rel(p->pri);
07870 
07871    sig_pri_unlock_private(p);
07872 
07873    return res;
07874 }

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

Definition at line 7836 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().

07837 {
07838    sig_pri_lock_private(p);
07839 
07840    if (!p->pri || !p->call) {
07841       ast_debug(1, "Unable to find pri or call on channel!\n");
07842       sig_pri_unlock_private(p);
07843       return -1;
07844    }
07845 
07846    pri_grab(p, p->pri);
07847    pri_keypad_facility(p->pri->pri, p->call, digits);
07848    pri_rel(p->pri);
07849 
07850    sig_pri_unlock_private(p);
07851 
07852    return 0;
07853 }

int sig_pri_answer ( struct sig_pri_chan p,
struct ast_channel ast 
)

Definition at line 7131 of file sig_pri.c.

References sig_pri_chan::aoc_s_request_invoke_id, sig_pri_chan::aoc_s_request_invoke_id_valid, ast_setstate(), AST_STATE_UP, sig_pri_chan::call, sig_pri_chan::call_level, sig_pri_chan::digital, sig_pri_span::pri, sig_pri_chan::pri, pri_grab(), pri_rel(), SIG_PRI_CALL_LEVEL_CONNECT, sig_pri_open_media(), and sig_pri_set_dialing().

Referenced by dahdi_answer().

07132 {
07133    int res;
07134 
07135    /* Send a pri acknowledge */
07136    pri_grab(p, p->pri);
07137 #if defined(HAVE_PRI_AOC_EVENTS)
07138    if (p->aoc_s_request_invoke_id_valid) {
07139       /* if AOC-S was requested and the invoke id is still present on answer.  That means
07140        * no AOC-S rate list was provided, so send a NULL response which will indicate that
07141        * AOC-S is not available */
07142       pri_aoc_s_request_response_send(p->pri->pri, p->call,
07143          p->aoc_s_request_invoke_id, NULL);
07144       p->aoc_s_request_invoke_id_valid = 0;
07145    }
07146 #endif   /* defined(HAVE_PRI_AOC_EVENTS) */
07147    if (p->call_level < SIG_PRI_CALL_LEVEL_CONNECT) {
07148       p->call_level = SIG_PRI_CALL_LEVEL_CONNECT;
07149    }
07150    sig_pri_set_dialing(p, 0);
07151    sig_pri_open_media(p);
07152    res = pri_answer(p->pri->pri, p->call, 0, !p->digital);
07153    pri_rel(p->pri);
07154    ast_setstate(ast, AST_STATE_UP);
07155    return res;
07156 }

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

Definition at line 7226 of file sig_pri.c.

References sig_pri_chan::allocated, ast_mutex_lock, ast_mutex_unlock, HAVE_PRI_CALL_WAITING, sig_pri_span::lock, sig_pri_chan::pri, sig_pri_span::pri, sig_pri_available_check(), and sig_pri_cw_available().

Referenced by available().

07227 {
07228    struct sig_pri_chan *p = *pvt;
07229    struct sig_pri_span *pri;
07230 
07231    if (!p->pri) {
07232       /* Something is wrong here.  A PRI channel without the pri pointer? */
07233       return 0;
07234    }
07235    pri = p->pri;
07236 
07237    ast_mutex_lock(&pri->lock);
07238    if (
07239 #if defined(HAVE_PRI_CALL_WAITING)
07240       /*
07241        * Only do call waiting calls if we have any
07242        * call waiting call outstanding.  We do not
07243        * want new calls to steal a B channel
07244        * freed for an earlier call waiting call.
07245        */
07246       !pri->num_call_waiting_calls &&
07247 #endif   /* defined(HAVE_PRI_CALL_WAITING) */
07248       sig_pri_available_check(p)) {
07249       p->allocated = 1;
07250       ast_mutex_unlock(&pri->lock);
07251       return 1;
07252    }
07253 
07254 #if defined(HAVE_PRI_CALL_WAITING)
07255    if (!is_specific_channel) {
07256       struct sig_pri_chan *cw;
07257 
07258       cw = sig_pri_cw_available(pri);
07259       if (cw) {
07260          /* We have a call waiting interface to use instead. */
07261          cw->allocated = 1;
07262          *pvt = cw;
07263          ast_mutex_unlock(&pri->lock);
07264          return 1;
07265       }
07266    }
07267 #endif   /* defined(HAVE_PRI_CALL_WAITING) */
07268    ast_mutex_unlock(&pri->lock);
07269    return 0;
07270 }

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 6471 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, sig_pri_chan::call_level, ast_channel::caller, sig_pri_cc_monitor_instance::cc_id, 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, sig_pri_chan::is_call_waiting, 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, 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_cc_monitor_instance::pri, 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_LEVEL_SETUP, sig_pri_call_opts, sig_pri_cc_type_name, 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().

06472 {
06473    char dest[256]; /* must be same length as p->dialdest */
06474    struct ast_party_subaddress dialed_subaddress; /* Called subaddress */
06475    struct pri_sr *sr;
06476    char *c, *l, *n, *s;
06477 #ifdef SUPPORT_USERUSER
06478    const char *useruser;
06479 #endif
06480    int core_id;
06481    int pridialplan;
06482    int dp_strip;
06483    int prilocaldialplan;
06484    int ldp_strip;
06485    int exclusive;
06486 #if defined(HAVE_PRI_SETUP_KEYPAD)
06487    const char *keypad;
06488 #endif   /* defined(HAVE_PRI_SETUP_KEYPAD) */
06489    AST_DECLARE_APP_ARGS(args,
06490       AST_APP_ARG(group);  /* channel/group token */
06491       AST_APP_ARG(ext); /* extension token */
06492       AST_APP_ARG(opts);   /* options token */
06493       AST_APP_ARG(other);  /* Any remining unused arguments */
06494    );
06495    struct ast_flags opts;
06496    char *opt_args[OPT_ARG_ARRAY_SIZE];
06497 
06498    ast_log(LOG_DEBUG, "CALLER NAME: %s NUM: %s\n",
06499       S_COR(ast->connected.id.name.valid, ast->connected.id.name.str, ""),
06500       S_COR(ast->connected.id.number.valid, ast->connected.id.number.str, ""));
06501 
06502    if (!p->pri) {
06503       ast_log(LOG_ERROR, "Could not find pri on channel %d\n", p->channel);
06504       return -1;
06505    }
06506 
06507    if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
06508       ast_log(LOG_WARNING, "sig_pri_call called on %s, neither down nor reserved\n", ast->name);
06509       return -1;
06510    }
06511 
06512    p->dialdest[0] = '\0';
06513    p->outgoing = 1;
06514 
06515    ast_copy_string(dest, rdest, sizeof(dest));
06516    AST_NONSTANDARD_APP_ARGS(args, dest, '/');
06517    if (ast_app_parse_options(sig_pri_call_opts, &opts, opt_args, args.opts)) {
06518       /* General invalid option syntax. */
06519       return -1;
06520    }
06521 
06522    c = args.ext;
06523    if (!c) {
06524       c = "";
06525    }
06526 
06527    /* setup dialed_subaddress if found */
06528    ast_party_subaddress_init(&dialed_subaddress);
06529    s = strchr(c, ':');
06530    if (s) {
06531       *s = '\0';
06532       s++;
06533       /* prefix */
06534       /* 'n' = NSAP */
06535       /* 'u' = User Specified */
06536       /* Default = NSAP */
06537       switch (*s) {
06538       case 'U':
06539       case 'u':
06540          s++;
06541          dialed_subaddress.type = 2;
06542          break;
06543       case 'N':
06544       case 'n':
06545          s++;
06546          /* default already covered with ast_party_subaddress_init */
06547          break;
06548       }
06549       dialed_subaddress.str = s;
06550       dialed_subaddress.valid = 1;
06551       s = NULL;
06552    }
06553 
06554    l = NULL;
06555    n = NULL;
06556    if (!p->hidecallerid) {
06557       if (ast->connected.id.number.valid) {
06558          /* If we get to the end of this loop without breaking, there's no
06559           * calleridnum.  This is done instead of testing for "unknown" or
06560           * the thousands of other ways that the calleridnum could be
06561           * invalid. */
06562          for (l = ast->connected.id.number.str; l && *l; l++) {
06563             if (strchr("0123456789", *l)) {
06564                l = ast->connected.id.number.str;
06565                break;
06566             }
06567          }
06568       } else {
06569          l = NULL;
06570       }
06571       if (!p->hidecalleridname) {
06572          n = ast->connected.id.name.valid ? ast->connected.id.name.str : NULL;
06573       }
06574    }
06575 
06576    if (strlen(c) < p->stripmsd) {
06577       ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
06578       return -1;
06579    }
06580    pri_grab(p, p->pri);
06581    if (!(p->call = pri_new_call(p->pri->pri))) {
06582       ast_log(LOG_WARNING, "Unable to create call on channel %d\n", p->channel);
06583       pri_rel(p->pri);
06584       return -1;
06585    }
06586    if (!(sr = pri_sr_new())) {
06587       ast_log(LOG_WARNING, "Failed to allocate setup request channel %d\n", p->channel);
06588       pri_destroycall(p->pri->pri, p->call);
06589       p->call = NULL;
06590       pri_rel(p->pri);
06591       return -1;
06592    }
06593 
06594    sig_pri_set_digital(p, IS_DIGITAL(ast->transfercapability));   /* push up to parent for EC */
06595 
06596 #if defined(HAVE_PRI_CALL_WAITING)
06597    if (p->is_call_waiting) {
06598       /*
06599        * Indicate that this is a call waiting call.
06600        * i.e., Normal call but with no B channel.
06601        */
06602       pri_sr_set_channel(sr, 0, 0, 1);
06603    } else
06604 #endif   /* defined(HAVE_PRI_CALL_WAITING) */
06605    {
06606       /* Should the picked channel be used exclusively? */
06607       if (p->priexclusive || p->pri->nodetype == PRI_NETWORK) {
06608          exclusive = 1;
06609       } else {
06610          exclusive = 0;
06611       }
06612       pri_sr_set_channel(sr, PVT_TO_CHANNEL(p), exclusive, 1);
06613    }
06614 
06615    pri_sr_set_bearer(sr, p->digital ? PRI_TRANS_CAP_DIGITAL : ast->transfercapability,
06616       (p->digital ? -1 : layer1));
06617 
06618    if (p->pri->facilityenable)
06619       pri_facility_enable(p->pri->pri);
06620 
06621    ast_verb(3, "Requested transfer capability: 0x%.2x - %s\n", ast->transfercapability, ast_transfercapability2str(ast->transfercapability));
06622    dp_strip = 0;
06623    pridialplan = p->pri->dialplan - 1;
06624    if (pridialplan == -2 || pridialplan == -3) { /* compute dynamically */
06625       if (strncmp(c + p->stripmsd, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) {
06626          if (pridialplan == -2) {
06627             dp_strip = strlen(p->pri->internationalprefix);
06628          }
06629          pridialplan = PRI_INTERNATIONAL_ISDN;
06630       } else if (strncmp(c + p->stripmsd, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) {
06631          if (pridialplan == -2) {
06632             dp_strip = strlen(p->pri->nationalprefix);
06633          }
06634          pridialplan = PRI_NATIONAL_ISDN;
06635       } else {
06636          pridialplan = PRI_LOCAL_ISDN;
06637       }
06638    }
06639    while (c[p->stripmsd] > '9' && c[p->stripmsd] != '*' && c[p->stripmsd] != '#') {
06640       switch (c[p->stripmsd]) {
06641       case 'U':
06642          pridialplan = (PRI_TON_UNKNOWN << 4) | (pridialplan & 0xf);
06643          break;
06644       case 'I':
06645          pridialplan = (PRI_TON_INTERNATIONAL << 4) | (pridialplan & 0xf);
06646          break;
06647       case 'N':
06648          pridialplan = (PRI_TON_NATIONAL << 4) | (pridialplan & 0xf);
06649          break;
06650       case 'L':
06651          pridialplan = (PRI_TON_NET_SPECIFIC << 4) | (pridialplan & 0xf);
06652          break;
06653       case 'S':
06654          pridialplan = (PRI_TON_SUBSCRIBER << 4) | (pridialplan & 0xf);
06655          break;
06656       case 'V':
06657          pridialplan = (PRI_TON_ABBREVIATED << 4) | (pridialplan & 0xf);
06658          break;
06659       case 'R':
06660          pridialplan = (PRI_TON_RESERVED << 4) | (pridialplan & 0xf);
06661          break;
06662       case 'u':
06663          pridialplan = PRI_NPI_UNKNOWN | (pridialplan & 0xf0);
06664          break;
06665       case 'e':
06666          pridialplan = PRI_NPI_E163_E164 | (pridialplan & 0xf0);
06667          break;
06668       case 'x':
06669          pridialplan = PRI_NPI_X121 | (pridialplan & 0xf0);
06670          break;
06671       case 'f':
06672          pridialplan = PRI_NPI_F69 | (pridialplan & 0xf0);
06673          break;
06674       case 'n':
06675          pridialplan = PRI_NPI_NATIONAL | (pridialplan & 0xf0);
06676          break;
06677       case 'p':
06678          pridialplan = PRI_NPI_PRIVATE | (pridialplan & 0xf0);
06679          break;
06680       case 'r':
06681          pridialplan = PRI_NPI_RESERVED | (pridialplan & 0xf0);
06682          break;
06683       default:
06684          if (isalpha(c[p->stripmsd])) {
06685             ast_log(LOG_WARNING, "Unrecognized pridialplan %s modifier: %c\n",
06686                c[p->stripmsd] > 'Z' ? "NPI" : "TON", c[p->stripmsd]);
06687          }
06688          break;
06689       }
06690       c++;
06691    }
06692 #if defined(HAVE_PRI_SETUP_KEYPAD)
06693    if (ast_test_flag(&opts, OPT_KEYPAD)
06694       && !ast_strlen_zero(opt_args[OPT_ARG_KEYPAD])) {
06695       /* We have a keypad facility digits option with digits. */
06696       keypad = opt_args[OPT_ARG_KEYPAD];
06697       pri_sr_set_keypad_digits(sr, keypad);
06698    } else {
06699       keypad = NULL;
06700    }
06701    if (!keypad || !ast_strlen_zero(c + p->stripmsd + dp_strip))
06702 #endif   /* defined(HAVE_PRI_SETUP_KEYPAD) */
06703    {
06704       pri_sr_set_called(sr, c + p->stripmsd + dp_strip, pridialplan, s ? 1 : 0);
06705    }
06706 
06707 #if defined(HAVE_PRI_SUBADDR)
06708    if (dialed_subaddress.valid) {
06709       struct pri_party_subaddress subaddress;
06710 
06711       memset(&subaddress, 0, sizeof(subaddress));
06712       sig_pri_party_subaddress_from_ast(&subaddress, &dialed_subaddress);
06713       pri_sr_set_called_subaddress(sr, &subaddress);
06714    }
06715 #endif   /* defined(HAVE_PRI_SUBADDR) */
06716 #if defined(HAVE_PRI_REVERSE_CHARGE)
06717    if (ast_test_flag(&opts, OPT_REVERSE_CHARGE)) {
06718       pri_sr_set_reversecharge(sr, PRI_REVERSECHARGE_REQUESTED);
06719    }
06720 #endif   /* defined(HAVE_PRI_REVERSE_CHARGE) */
06721 #if defined(HAVE_PRI_AOC_EVENTS)
06722    if (ast_test_flag(&opts, OPT_AOC_REQUEST)
06723       && !ast_strlen_zero(opt_args[OPT_ARG_AOC_REQUEST])) {
06724       if (strchr(opt_args[OPT_ARG_AOC_REQUEST], 's')) {
06725          pri_sr_set_aoc_charging_request(sr, PRI_AOC_REQUEST_S);
06726       }
06727       if (strchr(opt_args[OPT_ARG_AOC_REQUEST], 'd')) {
06728          pri_sr_set_aoc_charging_request(sr, PRI_AOC_REQUEST_D);
06729       }
06730       if (strchr(opt_args[OPT_ARG_AOC_REQUEST], 'e')) {
06731          pri_sr_set_aoc_charging_request(sr, PRI_AOC_REQUEST_E);
06732       }
06733    }
06734 #endif   /* defined(HAVE_PRI_AOC_EVENTS) */
06735 
06736    /* Setup the user tag for party id's from this device for this call. */
06737    if (p->pri->append_msn_to_user_tag) {
06738       snprintf(p->user_tag, sizeof(p->user_tag), "%s_%s", p->pri->initial_user_tag,
06739          p->pri->nodetype == PRI_NETWORK
06740             ? c + p->stripmsd + dp_strip
06741             : S_COR(ast->connected.id.number.valid,
06742                ast->connected.id.number.str, ""));
06743    } else {
06744       ast_copy_string(p->user_tag, p->pri->initial_user_tag, sizeof(p->user_tag));
06745    }
06746 
06747    /*
06748     * Replace the caller id tag from the channel creation
06749     * with the actual tag value.
06750     */
06751    ast_free(ast->caller.id.tag);
06752    ast->caller.id.tag = ast_strdup(p->user_tag);
06753 
06754    ldp_strip = 0;
06755    prilocaldialplan = p->pri->localdialplan - 1;
06756    if ((l != NULL) && (prilocaldialplan == -2 || prilocaldialplan == -3)) { /* compute dynamically */
06757       if (strncmp(l, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) {
06758          if (prilocaldialplan == -2) {
06759             ldp_strip = strlen(p->pri->internationalprefix);
06760          }
06761          prilocaldialplan = PRI_INTERNATIONAL_ISDN;
06762       } else if (strncmp(l, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) {
06763          if (prilocaldialplan == -2) {
06764             ldp_strip = strlen(p->pri->nationalprefix);
06765          }
06766          prilocaldialplan = PRI_NATIONAL_ISDN;
06767       } else {
06768          prilocaldialplan = PRI_LOCAL_ISDN;
06769       }
06770    }
06771    if (l != NULL) {
06772       while (*l > '9' && *l != '*' && *l != '#') {
06773          switch (*l) {
06774          case 'U':
06775             prilocaldialplan = (PRI_TON_UNKNOWN << 4) | (prilocaldialplan & 0xf);
06776             break;
06777          case 'I':
06778             prilocaldialplan = (PRI_TON_INTERNATIONAL << 4) | (prilocaldialplan & 0xf);
06779             break;
06780          case 'N':
06781             prilocaldialplan = (PRI_TON_NATIONAL << 4) | (prilocaldialplan & 0xf);
06782             break;
06783          case 'L':
06784             prilocaldialplan = (PRI_TON_NET_SPECIFIC << 4) | (prilocaldialplan & 0xf);
06785             break;
06786          case 'S':
06787             prilocaldialplan = (PRI_TON_SUBSCRIBER << 4) | (prilocaldialplan & 0xf);
06788             break;
06789          case 'V':
06790             prilocaldialplan = (PRI_TON_ABBREVIATED << 4) | (prilocaldialplan & 0xf);
06791             break;
06792          case 'R':
06793             prilocaldialplan = (PRI_TON_RESERVED << 4) | (prilocaldialplan & 0xf);
06794             break;
06795          case 'u':
06796             prilocaldialplan = PRI_NPI_UNKNOWN | (prilocaldialplan & 0xf0);
06797             break;
06798          case 'e':
06799             prilocaldialplan = PRI_NPI_E163_E164 | (prilocaldialplan & 0xf0);
06800             break;
06801          case 'x':
06802             prilocaldialplan = PRI_NPI_X121 | (prilocaldialplan & 0xf0);
06803             break;
06804          case 'f':
06805             prilocaldialplan = PRI_NPI_F69 | (prilocaldialplan & 0xf0);
06806             break;
06807          case 'n':
06808             prilocaldialplan = PRI_NPI_NATIONAL | (prilocaldialplan & 0xf0);
06809             break;
06810          case 'p':
06811             prilocaldialplan = PRI_NPI_PRIVATE | (prilocaldialplan & 0xf0);
06812             break;
06813          case 'r':
06814             prilocaldialplan = PRI_NPI_RESERVED | (prilocaldialplan & 0xf0);
06815             break;
06816          default:
06817             if (isalpha(*l)) {
06818                ast_log(LOG_WARNING,
06819                   "Unrecognized prilocaldialplan %s modifier: %c\n",
06820                   *l > 'Z' ? "NPI" : "TON", *l);
06821             }
06822             break;
06823          }
06824          l++;
06825       }
06826    }
06827    pri_sr_set_caller(sr, l ? (l + ldp_strip) : NULL, n, prilocaldialplan,
06828       p->use_callingpres ? ast->connected.id.number.presentation : (l ? PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN : PRES_NUMBER_NOT_AVAILABLE));
06829 
06830 #if defined(HAVE_PRI_SUBADDR)
06831    if (ast->connected.id.subaddress.valid) {
06832       struct pri_party_subaddress subaddress;
06833 
06834       memset(&subaddress, 0, sizeof(subaddress));
06835       sig_pri_party_subaddress_from_ast(&subaddress, &ast->connected.id.subaddress);
06836       pri_sr_set_caller_subaddress(sr, &subaddress);
06837    }
06838 #endif   /* defined(HAVE_PRI_SUBADDR) */
06839 
06840    sig_pri_redirecting_update(p, ast);
06841 
06842 #ifdef SUPPORT_USERUSER
06843    /* User-user info */
06844    useruser = pbx_builtin_getvar_helper(p->owner, "USERUSERINFO");
06845    if (useruser)
06846       pri_sr_set_useruser(sr, useruser);
06847 #endif
06848 
06849 #if defined(HAVE_PRI_CCSS)
06850    if (ast_cc_is_recall(ast, &core_id, sig_pri_cc_type_name)) {
06851       struct ast_cc_monitor *monitor;
06852       char device_name[AST_CHANNEL_NAME];
06853 
06854       /* This is a CC recall call. */
06855       ast_channel_get_device_name(ast, device_name, sizeof(device_name));
06856       monitor = ast_cc_get_monitor_by_recall_core_id(core_id, device_name);
06857       if (monitor) {
06858          struct sig_pri_cc_monitor_instance *instance;
06859 
06860          instance = monitor->private_data;
06861 
06862          /* If this fails then we have monitor instance ambiguity. */
06863          ast_assert(p->pri == instance->pri);
06864 
06865          if (pri_cc_call(p->pri->pri, instance->cc_id, p->call, sr)) {
06866             /* The CC recall call failed for some reason. */
06867             ast_log(LOG_WARNING, "Unable to setup CC recall call to device %s\n",
06868                device_name);
06869             ao2_ref(monitor, -1);
06870             pri_destroycall(p->pri->pri, p->call);
06871             p->call = NULL;
06872             pri_rel(p->pri);
06873             pri_sr_free(sr);
06874             return -1;
06875          }
06876          ao2_ref(monitor, -1);
06877       } else {
06878          core_id = -1;
06879       }
06880    } else
06881 #endif   /* defined(HAVE_PRI_CCSS) */
06882    {
06883       core_id = -1;
06884    }
06885    if (core_id == -1 && pri_setup(p->pri->pri, p->call, sr)) {
06886       ast_log(LOG_WARNING, "Unable to setup call to %s (using %s)\n",
06887          c + p->stripmsd + dp_strip, dialplan2str(p->pri->dialplan));
06888       pri_destroycall(p->pri->pri, p->call);
06889       p->call = NULL;
06890       pri_rel(p->pri);
06891       pri_sr_free(sr);
06892       return -1;
06893    }
06894    p->call_level = SIG_PRI_CALL_LEVEL_SETUP;
06895    pri_sr_free(sr);
06896    ast_setstate(ast, AST_STATE_DIALING);
06897    sig_pri_set_dialing(p, 1);
06898    pri_rel(p->pri);
06899    return 0;
06900 }

int sig_pri_cc_agent_callee_available ( struct ast_cc_agent agent  ) 

Alert the caller that it is time to try recalling.

Since:
1.8
Parameters:
agent CC core agent control.
The core will call this function when it receives notice that a monitored party has become available.

The agent's job is to send a message to the caller to notify it of such a change. If the agent is able to discern that the caller is currently unavailable, then the agent should react by calling the ast_cc_caller_unavailable function.

Return values:
0 on success.
-1 on error.

Definition at line 8198 of file sig_pri.c.

References ast_mutex_lock, ast_mutex_unlock, sig_pri_cc_agent_prv::cc_id, sig_pri_span::lock, sig_pri_span::pri, sig_pri_cc_agent_prv::pri, and ast_cc_agent::private_data.

08199 {
08200    struct sig_pri_cc_agent_prv *cc_pvt;
08201 
08202    cc_pvt = agent->private_data;
08203    ast_mutex_lock(&cc_pvt->pri->lock);
08204    pri_cc_remote_user_free(cc_pvt->pri->pri, cc_pvt->cc_id);
08205    ast_mutex_unlock(&cc_pvt->pri->lock);
08206    return 0;
08207 }

void sig_pri_cc_agent_destructor ( struct ast_cc_agent agent  ) 

Destroy private data on the agent.

Since:
1.8
Parameters:
agent CC core agent control.
The core will call this function upon completion or failure of CC.

Note:
The agent private_data pointer may be NULL if the agent constructor failed.
Returns:
Nothing

Definition at line 8227 of file sig_pri.c.

References ast_free, ast_mutex_lock, ast_mutex_unlock, sig_pri_cc_agent_prv::cc_id, sig_pri_cc_agent_prv::cc_request_response_pending, sig_pri_span::lock, sig_pri_span::pri, sig_pri_cc_agent_prv::pri, and ast_cc_agent::private_data.

Referenced by dahdi_pri_cc_agent_destructor().

08228 {
08229    struct sig_pri_cc_agent_prv *cc_pvt;
08230    int res;
08231 
08232    cc_pvt = agent->private_data;
08233    if (!cc_pvt) {
08234       /* The agent constructor probably failed. */
08235       return;
08236    }
08237    ast_mutex_lock(&cc_pvt->pri->lock);
08238    res = -1;
08239    if (cc_pvt->cc_request_response_pending) {
08240       res = pri_cc_req_rsp(cc_pvt->pri->pri, cc_pvt->cc_id, 2/* short_term_denial */);
08241    }
08242    if (res) {
08243       pri_cc_cancel(cc_pvt->pri->pri, cc_pvt->cc_id);
08244    }
08245    ast_mutex_unlock(&cc_pvt->pri->lock);
08246    ast_free(cc_pvt);
08247 }

int sig_pri_cc_agent_init ( struct ast_cc_agent agent,
struct sig_pri_chan pvt_chan 
)

PRI CC agent initialization.

Since:
1.8
Parameters:
agent CC core agent control.
pvt_chan Original channel the agent will attempt to recall.
This callback is called when the CC core is initialized. Agents should allocate any private data necessary for the call and assign it to the private_data on the agent. Additionally, if any ast_cc_agent_flags are pertinent to the specific agent type, they should be set in this function as well.

Return values:
0 on success.
-1 on error.

Definition at line 7910 of file sig_pri.c.

References ast_calloc, ast_free, ast_mutex_lock, ast_mutex_unlock, sig_pri_chan::call, sig_pri_span::lock, sig_pri_span::pri, sig_pri_chan::pri, and ast_cc_agent::private_data.

Referenced by dahdi_pri_cc_agent_init().

07911 {
07912    struct sig_pri_cc_agent_prv *cc_pvt;
07913 
07914    cc_pvt = ast_calloc(1, sizeof(*cc_pvt));
07915    if (!cc_pvt) {
07916       return -1;
07917    }
07918 
07919    ast_mutex_lock(&pvt_chan->pri->lock);
07920    cc_pvt->pri = pvt_chan->pri;
07921    cc_pvt->cc_id = pri_cc_available(pvt_chan->pri->pri, pvt_chan->call);
07922    ast_mutex_unlock(&pvt_chan->pri->lock);
07923    if (cc_pvt->cc_id == -1) {
07924       ast_free(cc_pvt);
07925       return -1;
07926    }
07927    agent->private_data = cc_pvt;
07928    return 0;
07929 }

int sig_pri_cc_agent_party_b_free ( struct ast_cc_agent agent  ) 

Let the caller know that the callee has become free but that the caller cannot attempt to call back because he is either busy or there is congestion on his line.

Since:
1.8
Parameters:
agent CC core agent control.
This is something that really only affects a scenario where a phone places a call over ISDN PTMP to Asterisk, who then connects over PTMP again to the ISDN network. For most agent types, there is no need to implement this callback at all because they don't really need to actually do anything in this situation. If you're having trouble understanding what the purpose of this callback is, then you can be safe simply not implementing it.

Return values:
0 on success.
-1 on error.

Definition at line 8142 of file sig_pri.c.

References ast_mutex_lock, ast_mutex_unlock, sig_pri_cc_agent_prv::cc_id, sig_pri_span::lock, sig_pri_span::pri, sig_pri_cc_agent_prv::pri, and ast_cc_agent::private_data.

08143 {
08144    struct sig_pri_cc_agent_prv *cc_pvt;
08145 
08146    cc_pvt = agent->private_data;
08147    ast_mutex_lock(&cc_pvt->pri->lock);
08148    pri_cc_b_free(cc_pvt->pri->pri, cc_pvt->cc_id);
08149    ast_mutex_unlock(&cc_pvt->pri->lock);
08150    return 0;
08151 }

void sig_pri_cc_agent_req_rsp ( struct ast_cc_agent agent,
enum ast_cc_agent_response_reason  reason 
)

Response to a CC request.

Since:
1.8
Parameters:
agent CC core agent control.
reason CC request response status.
When the core receives knowledge that a called party has accepted a CC request, it will call this callback. The core may also call this if there is some error when attempting to process the incoming CC request.

The duty of this is to issue a propper response to a CC request from the caller by acknowledging receipt of that request or rejecting it.

Returns:
Nothing

Definition at line 8003 of file sig_pri.c.

References AST_CC_AGENT_RESPONSE_FAILURE_INVALID, AST_CC_AGENT_RESPONSE_FAILURE_TOO_MANY, AST_CC_AGENT_RESPONSE_SUCCESS, ast_cc_failed(), ast_mutex_lock, ast_mutex_unlock, sig_pri_cc_agent_prv::cc_id, sig_pri_cc_agent_prv::cc_request_response_pending, ast_cc_agent::core_id, sig_pri_span::lock, sig_pri_span::pri, sig_pri_cc_agent_prv::pri, ast_cc_agent::private_data, sig_pri_cc_type_name, and status.

08004 {
08005    struct sig_pri_cc_agent_prv *cc_pvt;
08006    int res;
08007    int status;
08008    const char *failed_msg;
08009    static const char *failed_to_send = "Failed to send the CC request response.";
08010    static const char *not_accepted = "The core declined the CC request.";
08011 
08012    cc_pvt = agent->private_data;
08013    ast_mutex_lock(&cc_pvt->pri->lock);
08014    if (cc_pvt->cc_request_response_pending) {
08015       cc_pvt->cc_request_response_pending = 0;
08016 
08017       /* Convert core response reason to ISDN response status. */
08018       status = 2;/* short_term_denial */
08019       switch (reason) {
08020       case AST_CC_AGENT_RESPONSE_SUCCESS:
08021          status = 0;/* success */
08022          break;
08023       case AST_CC_AGENT_RESPONSE_FAILURE_INVALID:
08024          status = 2;/* short_term_denial */
08025          break;
08026       case AST_CC_AGENT_RESPONSE_FAILURE_TOO_MANY:
08027          status = 5;/* queue_full */
08028          break;
08029       }
08030 
08031       res = pri_cc_req_rsp(cc_pvt->pri->pri, cc_pvt->cc_id, status);
08032       if (!status) {
08033          /* CC core request was accepted. */
08034          if (res) {
08035             failed_msg = failed_to_send;
08036          } else {
08037             failed_msg = NULL;
08038          }
08039       } else {
08040          /* CC core request was declined. */
08041          if (res) {
08042             failed_msg = failed_to_send;
08043          } else {
08044             failed_msg = not_accepted;
08045          }
08046       }
08047    } else {
08048       failed_msg = NULL;
08049    }
08050    ast_mutex_unlock(&cc_pvt->pri->lock);
08051    if (failed_msg) {
08052       ast_cc_failed(agent->core_id, "%s agent: %s", sig_pri_cc_type_name, failed_msg);
08053    }
08054 }

int sig_pri_cc_agent_start_monitoring ( struct ast_cc_agent agent  ) 

Begin monitoring a busy device.

Since:
1.8
Parameters:
agent CC core agent control.
The core will call this callback if the callee becomes available but the caller has reported that he is busy. The agent should begin monitoring the caller's device. When the caller becomes available again, the agent should call ast_cc_agent_caller_available.

Return values:
0 on success.
-1 on error.

Definition at line 8171 of file sig_pri.c.

08172 {
08173    /* libpri already knows when and how it needs to monitor Party A. */
08174    return 0;
08175 }

int sig_pri_cc_agent_start_offer_timer ( struct ast_cc_agent agent  ) 

Start the offer timer.

Since:
1.8
Parameters:
agent CC core agent control.
This is called by the core when the caller hangs up after a call for which CC may be requested. The agent should begin the timer as configured.

The primary reason why this functionality is left to the specific agent implementations is due to the differing use of schedulers throughout the code. Some channel drivers may already have a scheduler context they wish to use, and amongst those, some may use the ast_sched API while others may use the ast_sched_thread API, which are incompatible.

Return values:
0 on success.
-1 on error.

Definition at line 7954 of file sig_pri.c.

07955 {
07956    /* libpri maintains it's own offer timer in the form of T_RETENTION. */
07957    return 0;
07958 }

int sig_pri_cc_agent_status_req ( struct ast_cc_agent agent  ) 

Request the status of the agent's device.

Since:
1.8
Parameters:
agent CC core agent control.
Asynchronous request for the status of any caller which may be a valid caller for the CC transaction. Status responses should be made using the ast_cc_status_response function.

Return values:
0 on success.
-1 on error.

Definition at line 8073 of file sig_pri.c.

References ast_mutex_lock, ast_mutex_unlock, sig_pri_cc_agent_prv::cc_id, sig_pri_span::lock, sig_pri_span::pri, sig_pri_cc_agent_prv::pri, and ast_cc_agent::private_data.

08074 {
08075    struct sig_pri_cc_agent_prv *cc_pvt;
08076 
08077    cc_pvt = agent->private_data;
08078    ast_mutex_lock(&cc_pvt->pri->lock);
08079    pri_cc_status_req(cc_pvt->pri->pri, cc_pvt->cc_id);
08080    ast_mutex_unlock(&cc_pvt->pri->lock);
08081    return 0;
08082 }

int sig_pri_cc_agent_stop_offer_timer ( struct ast_cc_agent agent  ) 

Stop the offer timer.

Since:
1.8
Parameters:
agent CC core agent control.
This callback is called by the CC core when the caller has requested CC.

Return values:
0 on success.
-1 on error.

Definition at line 7975 of file sig_pri.c.

07976 {
07977    /* libpri maintains it's own offer timer in the form of T_RETENTION. */
07978    return 0;
07979 }

int sig_pri_cc_agent_stop_ringing ( struct ast_cc_agent agent  ) 

Request for an agent's phone to stop ringing.

Since:
1.8
Parameters:
agent CC core agent control.
The usefulness of this is quite limited. The only specific known case for this is if Asterisk requests CC over an ISDN PTMP link as the TE side. If other phones are in the same recall group as the Asterisk server, and one of those phones picks up the recall notice, then Asterisk will receive a "stop ringing" notification from the NT side of the PTMP link. This indication needs to be passed to the phone on the other side of the Asterisk server which originally placed the call so that it will stop ringing. Since the phone may be of any type, it is necessary to have a callback that the core can know about.

Return values:
0 on success.
-1 on error.

Definition at line 8108 of file sig_pri.c.

References ast_mutex_lock, ast_mutex_unlock, sig_pri_cc_agent_prv::cc_id, sig_pri_span::lock, sig_pri_span::pri, sig_pri_cc_agent_prv::pri, and ast_cc_agent::private_data.

08109 {
08110    struct sig_pri_cc_agent_prv *cc_pvt;
08111 
08112    cc_pvt = agent->private_data;
08113    ast_mutex_lock(&cc_pvt->pri->lock);
08114    pri_cc_stop_alerting(cc_pvt->pri->pri, cc_pvt->cc_id);
08115    ast_mutex_unlock(&cc_pvt->pri->lock);
08116    return 0;
08117 }

int sig_pri_cc_monitor_cancel_available_timer ( struct ast_cc_monitor monitor,
int *  sched_id 
)

Cancel the running available timer.

Since:
1.8
Parameters:
monitor CC core monitor control.
sched_id Available timer scheduler id to cancel. Will never be NULL for a device monitor.
In most cases, this function will likely consist of just a call to AST_SCHED_DEL. It might have been possible to do this within the core, but unfortunately the mixture of sched_thread and sched usage in Asterisk prevents such usage.

Return values:
0 on success
-1 on failure.

Definition at line 8453 of file sig_pri.c.

08454 {
08455    /*
08456     * libpri maintains it's own available timer as one of:
08457     * T_CCBS2/T_CCBS5/T_CCBS6/QSIG_CCBS_T2
08458     * T_CCNR2/T_CCNR5/T_CCNR6/QSIG_CCNR_T2
08459     */
08460    return 0;
08461 }

void sig_pri_cc_monitor_destructor ( void *  monitor_pvt  ) 

Destroy PRI private data on the monitor.

Since:
1.8
Parameters:
monitor_pvt CC device monitor private data pointer.
Implementers of this callback are responsible for destroying all heap-allocated data in the monitor's private_data pointer, including the private_data itself.

Definition at line 8476 of file sig_pri.c.

References ao2_ref, ao2_unlink, and sig_pri_cc_monitors.

08477 {
08478    struct sig_pri_cc_monitor_instance *instance;
08479 
08480    instance = monitor_pvt;
08481    if (!instance) {
08482       return;
08483    }
08484    ao2_unlink(sig_pri_cc_monitors, instance);
08485    ao2_ref(instance, -1);
08486 }

int sig_pri_cc_monitor_req_cc ( struct ast_cc_monitor monitor,
int *  available_timer_id 
)

Request CCSS.

Since:
1.8
Parameters:
monitor CC core monitor control.
available_timer_id Where to put the available timer scheduler id. Will never be NULL for a device monitor.
Perform whatever steps are necessary in order to request CC. In addition, the monitor implementation is responsible for starting the available timer in this callback. The scheduler ID for the callback must be stored in the parent_link's child_avail_id field.

Return values:
0 on success
-1 on failure.

Definition at line 8309 of file sig_pri.c.

References AST_CC_CCBS, AST_CC_CCNR, ast_mutex_lock, ast_mutex_unlock, sig_pri_cc_monitor_instance::cc_id, sig_pri_span::lock, monitor, sig_pri_span::pri, and sig_pri_cc_monitor_instance::pri.

08310 {
08311    struct sig_pri_cc_monitor_instance *instance;
08312    int cc_mode;
08313    int res;
08314 
08315    switch (monitor->service_offered) {
08316    case AST_CC_CCBS:
08317       cc_mode = 0;/* CCBS */
08318       break;
08319    case AST_CC_CCNR:
08320       cc_mode = 1;/* CCNR */
08321       break;
08322    default:
08323       /* CC service not supported by ISDN. */
08324       return -1;
08325    }
08326 
08327    instance = monitor->private_data;
08328 
08329    /* libpri handles it's own available timer. */
08330    ast_mutex_lock(&instance->pri->lock);
08331    res = pri_cc_req(instance->pri->pri, instance->cc_id, cc_mode);
08332    ast_mutex_unlock(&instance->pri->lock);
08333 
08334    return res;
08335 }

int sig_pri_cc_monitor_status_rsp ( struct ast_cc_monitor monitor,
enum ast_device_state  devstate 
)

Status response to an ast_cc_monitor_status_request().

Since:
1.8
Parameters:
monitor CC core monitor control.
devstate Current status of a Party A device.
Alert a monitor as to the status of the agent for which the monitor had previously requested a status request.

Note:
Zero or more responses may come as a result.
Return values:
0 on success
-1 on failure.

Definition at line 8408 of file sig_pri.c.

References AST_DEVICE_BUSY, AST_DEVICE_INUSE, AST_DEVICE_NOT_INUSE, AST_DEVICE_UNKNOWN, ast_mutex_lock, ast_mutex_unlock, sig_pri_cc_monitor_instance::cc_id, sig_pri_span::lock, monitor, sig_pri_span::pri, and sig_pri_cc_monitor_instance::pri.

08409 {
08410    struct sig_pri_cc_monitor_instance *instance;
08411    int cc_status;
08412 
08413    switch (devstate) {
08414    case AST_DEVICE_UNKNOWN:
08415    case AST_DEVICE_NOT_INUSE:
08416       cc_status = 0;/* free */
08417       break;
08418    case AST_DEVICE_BUSY:
08419    case AST_DEVICE_INUSE:
08420       cc_status = 1;/* busy */
08421       break;
08422    default:
08423       /* Don't know how to interpret this device state into free/busy status. */
08424       return 0;
08425    }
08426    instance = monitor->private_data;
08427    ast_mutex_lock(&instance->pri->lock);
08428    pri_cc_status_req_rsp(instance->pri->pri, instance->cc_id, cc_status);
08429    ast_mutex_unlock(&instance->pri->lock);
08430 
08431    return 0;
08432 }

int sig_pri_cc_monitor_suspend ( struct ast_cc_monitor monitor  ) 

Suspend monitoring.

Since:
1.8
Parameters:
monitor CC core monitor control.
Implementers must perform the necessary steps to suspend monitoring.

Return values:
0 on success
-1 on failure.

Definition at line 8352 of file sig_pri.c.

References ast_mutex_lock, ast_mutex_unlock, sig_pri_cc_monitor_instance::cc_id, sig_pri_span::lock, monitor, sig_pri_span::pri, and sig_pri_cc_monitor_instance::pri.

08353 {
08354    struct sig_pri_cc_monitor_instance *instance;
08355 
08356    instance = monitor->private_data;
08357    ast_mutex_lock(&instance->pri->lock);
08358    pri_cc_status(instance->pri->pri, instance->cc_id, 1/* busy */);
08359    ast_mutex_unlock(&instance->pri->lock);
08360 
08361    return 0;
08362 }

int sig_pri_cc_monitor_unsuspend ( struct ast_cc_monitor monitor  ) 

Unsuspend monitoring.

Since:
1.8
Parameters:
monitor CC core monitor control.
Perform the necessary steps to unsuspend monitoring.

Return values:
0 on success
-1 on failure.

Definition at line 8378 of file sig_pri.c.

References ast_mutex_lock, ast_mutex_unlock, sig_pri_cc_monitor_instance::cc_id, sig_pri_span::lock, monitor, sig_pri_span::pri, and sig_pri_cc_monitor_instance::pri.

08379 {
08380    struct sig_pri_cc_monitor_instance *instance;
08381 
08382    instance = monitor->private_data;
08383    ast_mutex_lock(&instance->pri->lock);
08384    pri_cc_status(instance->pri->pri, instance->cc_id, 0/* free */);
08385    ast_mutex_unlock(&instance->pri->lock);
08386 
08387    return 0;
08388 }

void sig_pri_chan_alarm_notify ( struct sig_pri_chan p,
int  noalarm 
)

Notify new alarm status.

Parameters:
p Channel private pointer.
noalarm Non-zero if not in alarm mode.
Note:
Assumes the sig_pri_lock_private(p) is already obtained.
Returns:
Nothing

Definition at line 7674 of file sig_pri.c.

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

Referenced by dahdi_handle_event(), and handle_init_event().

07675 {
07676    pri_grab(p, p->pri);
07677    sig_pri_set_alarm(p, !noalarm);
07678    if (!noalarm) {
07679       if (pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0) {
07680          /* T309 is not enabled : destroy calls when alarm occurs */
07681          if (p->call) {
07682             pri_destroycall(p->pri->pri, p->call);
07683             p->call = NULL;
07684          }
07685          if (p->owner)
07686             p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
07687       }
07688    }
07689    sig_pri_span_devstate_changed(p->pri);
07690    pri_rel(p->pri);
07691 }

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 7721 of file sig_pri.c.

References ast_free.

Referenced by destroy_dahdi_pvt().

07722 {
07723    ast_free(doomed);
07724 }

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 7693 of file sig_pri.c.

References ast_calloc, and sig_pri_chan::pri.

07694 {
07695    struct sig_pri_chan *p;
07696 
07697    p = ast_calloc(1, sizeof(*p));
07698    if (!p)
07699       return p;
07700 
07701    p->logicalspan = logicalspan;
07702    p->prioffset = channo;
07703    p->mastertrunkgroup = trunkgroup;
07704 
07705    p->calls = callback;
07706    p->chan_pvt = pvt_data;
07707 
07708    p->pri = pri;
07709 
07710    return p;
07711 }

void sig_pri_cli_show_channels ( int  fd,
struct sig_pri_span pri 
)

Definition at line 7734 of file sig_pri.c.

References ast_channel_unlock, ast_cli(), ast_mutex_lock, ast_mutex_unlock, sig_pri_chan::call, sig_pri_chan::call_level, sig_pri_chan::channel, sig_pri_span::lock, ast_channel::name, sig_pri_chan::no_b_channel, sig_pri_span::numchans, sig_pri_chan::owner, sig_pri_chan::pri, sig_pri_span::pvts, sig_pri_call_level2str(), sig_pri_is_chan_available(), sig_pri_lock_owner(), sig_pri_lock_private(), SIG_PRI_SC_LINE, sig_pri_unlock_private(), and sig_pri_span::span.

Referenced by handle_pri_show_channels().

07735 {
07736    char line[256];
07737    int idx;
07738    struct sig_pri_chan *pvt;
07739 
07740    ast_mutex_lock(&pri->lock);
07741    for (idx = 0; idx < pri->numchans; ++idx) {
07742       if (!pri->pvts[idx]) {
07743          continue;
07744       }
07745       pvt = pri->pvts[idx];
07746       sig_pri_lock_private(pvt);
07747       sig_pri_lock_owner(pri, idx);
07748       if (pvt->no_b_channel && sig_pri_is_chan_available(pvt)) {
07749          /* Don't show held/call-waiting channels if they are not in use. */
07750          sig_pri_unlock_private(pvt);
07751          continue;
07752       }
07753 
07754       snprintf(line, sizeof(line), SIG_PRI_SC_LINE,
07755          pri->span,
07756          pvt->channel,
07757          pvt->no_b_channel ? "No" : "Yes",/* Has media */
07758          sig_pri_is_chan_available(pvt) ? "Yes" : "No",
07759          sig_pri_call_level2str(pvt->call_level),
07760          pvt->call ? "Yes" : "No",
07761          pvt->owner ? pvt->owner->name : "");
07762 
07763       if (pvt->owner) {
07764          ast_channel_unlock(pvt->owner);
07765       }
07766       sig_pri_unlock_private(pvt);
07767 
07768       ast_mutex_unlock(&pri->lock);
07769       ast_cli(fd, "%s\n", line);
07770       ast_mutex_lock(&pri->lock);
07771    }
07772    ast_mutex_unlock(&pri->lock);
07773 }

void sig_pri_cli_show_channels_header ( int  fd  ) 

Definition at line 7728 of file sig_pri.c.

References ast_cli(), and SIG_PRI_SC_HEADER.

Referenced by handle_pri_show_channels().

07729 {
07730    ast_cli(fd, SIG_PRI_SC_HEADER, "PRI",  "",     "B",    "Chan", "Call",  "PRI",  "Channel");
07731    ast_cli(fd, SIG_PRI_SC_HEADER, "Span", "Chan", "Chan", "Idle", "Level", "Call", "Name");
07732 }

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

Definition at line 7806 of file sig_pri.c.

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

Referenced by handle_pri_show_span().

07807 {
07808    int x;
07809    char status[256];
07810 
07811    for (x = 0; x < SIG_PRI_NUM_DCHANS; x++) {
07812       if (pri->dchans[x]) {
07813 #ifdef PRI_DUMP_INFO_STR
07814          char *info_str = NULL;
07815 #endif
07816          ast_cli(fd, "%s D-channel: %d\n", pri_order(x), dchannels[x]);
07817          build_status(status, sizeof(status), pri->dchanavail[x], pri->dchans[x] == pri->pri);
07818          ast_cli(fd, "Status: %s\n", status);
07819          ast_mutex_lock(&pri->lock);
07820 #ifdef PRI_DUMP_INFO_STR
07821          info_str = pri_dump_info_str(pri->pri);
07822          if (info_str) {
07823             ast_cli(fd, "%s", info_str);
07824             free(info_str);
07825          }
07826 #else
07827          pri_dump_info(pri->pri);
07828 #endif
07829          ast_mutex_unlock(&pri->lock);
07830          ast_cli(fd, "Overlap Recv: %s\n\n", (pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)?"Yes":"No");
07831          ast_cli(fd, "\n");
07832       }
07833    }
07834 }

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

Definition at line 7794 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().

07795 {
07796    char status[256];
07797    int x;
07798    for (x = 0; x < SIG_PRI_NUM_DCHANS; x++) {
07799       if (pri->dchans[x]) {
07800          build_status(status, sizeof(status), pri->dchanavail[x], pri->dchans[x] == pri->pri);
07801          ast_cli(fd, "PRI span %d/%d: %s\n", span, x, status);
07802       }
07803    }
07804 }

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

Definition at line 7274 of file sig_pri.c.

References ast_channel::_state, ast_debug, ast_log(), AST_STATE_DIALING, sig_pri_chan::call_level, sig_pri_chan::dialdest, LOG_WARNING, sig_pri_chan::pri, pri_grab(), pri_rel(), sig_pri_call_level2str(), SIG_PRI_CALL_LEVEL_CONNECT, SIG_PRI_CALL_LEVEL_OVERLAP, SIG_PRI_CALL_LEVEL_PROCEEDING, and sig_pri_span::span.

Referenced by dahdi_digit_begin().

07275 {
07276    if (ast->_state == AST_STATE_DIALING) {
07277       if (pvt->call_level < SIG_PRI_CALL_LEVEL_OVERLAP) {
07278          unsigned int len;
07279 
07280          len = strlen(pvt->dialdest);
07281          if (len < sizeof(pvt->dialdest) - 1) {
07282             ast_debug(1, "Queueing digit '%c' since setup_ack not yet received\n",
07283                digit);
07284             pvt->dialdest[len++] = digit;
07285             pvt->dialdest[len] = '\0';
07286          } else {
07287             ast_log(LOG_WARNING,
07288                "Span %d: Deferred digit buffer overflow for digit '%c'.\n",
07289                pvt->pri->span, digit);
07290          }
07291          return 0;
07292       }
07293       if (pvt->call_level < SIG_PRI_CALL_LEVEL_PROCEEDING) {
07294          pri_grab(pvt, pvt->pri);
07295          pri_information(pvt->pri->pri, pvt->call, digit);
07296          pri_rel(pvt->pri);
07297          return 0;
07298       }
07299       if (pvt->call_level < SIG_PRI_CALL_LEVEL_CONNECT) {
07300          ast_log(LOG_WARNING,
07301             "Span %d: Digit '%c' may be ignored by peer. (Call level:%d(%s))\n",
07302             pvt->pri->span, digit, pvt->call_level,
07303             sig_pri_call_level2str(pvt->call_level));
07304       }
07305    }
07306    return 1;
07307 }

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 6392 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().

06393 {
06394    char *dial;
06395    char *number;
06396    char *subaddr;
06397    AST_DECLARE_APP_ARGS(args,
06398       AST_APP_ARG(group);  /* channel/group token */
06399       AST_APP_ARG(ext); /* extension token */
06400       //AST_APP_ARG(opts); /* options token */
06401       AST_APP_ARG(other);  /* Any remining unused arguments */
06402    );
06403 
06404    /* Get private copy of dial string and break it up. */
06405    dial = ast_strdupa(rdest);
06406    AST_NONSTANDARD_APP_ARGS(args, dial, '/');
06407 
06408    number = args.ext;
06409    if (!number) {
06410       number = "";
06411    }
06412 
06413    /* Find and extract dialed_subaddress */
06414    subaddr = strchr(number, ':');
06415    if (subaddr) {
06416       *subaddr++ = '\0';
06417 
06418       /* Skip subaddress type prefix. */
06419       switch (*subaddr) {
06420       case 'U':
06421       case 'u':
06422       case 'N':
06423       case 'n':
06424          ++subaddr;
06425          break;
06426       default:
06427          break;
06428       }
06429    }
06430 
06431    /* Skip type-of-number/dial-plan prefix characters. */
06432    if (strlen(number) < p->stripmsd) {
06433       number = "";
06434    } else {
06435       number += p->stripmsd;
06436       while (isalpha(*number)) {
06437          ++number;
06438       }
06439    }
06440 
06441    /* Fill buffer with extracted number and subaddress. */
06442    if (ast_strlen_zero(subaddr)) {
06443       /* Put in called number only since there is no subaddress. */
06444       snprintf(called, called_buff_size, "%s", number);
06445    } else {
06446       /* Put in called number and subaddress. */
06447       snprintf(called, called_buff_size, "%s:%s", number, subaddr);
06448    }
06449 }

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

Definition at line 7886 of file sig_pri.c.

References sig_pri_chan::owner.

07887 {
07888    if (pchan->owner == oldchan) {
07889       pchan->owner = newchan;
07890    }
07891 }

int sig_pri_hangup ( struct sig_pri_chan p,
struct ast_channel ast 
)

Definition at line 6301 of file sig_pri.c.

References sig_pri_chan::allocated, sig_pri_chan::alreadyhungup, sig_pri_chan::aoc_e, sig_pri_chan::aoc_s_request_invoke_id_valid, ast_atomic_fetchadd_int(), ast_debug, ast_log(), ast_strlen_zero(), sig_pri_chan::call, sig_pri_chan::call_level, 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, sig_pri_chan::holding_aoce, sig_pri_chan::is_call_waiting, LOG_WARNING, sig_pri_span::num_call_waiting_calls, 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::progress, SIG_PRI_CALL_LEVEL_IDLE, sig_pri_set_dialing(), sig_pri_set_digital(), sig_pri_span_devstate_changed(), ast_channel::tech_pvt, sig_pri_chan::user_tag, and sig_pri_chan::waiting_for_aoce.

Referenced by dahdi_hangup().

06302 {
06303    ast_debug(1, "%s %d\n", __FUNCTION__, p->channel);
06304    if (!ast->tech_pvt) {
06305       ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
06306       return 0;
06307    }
06308 
06309    p->outgoing = 0;
06310    sig_pri_set_digital(p, 0); /* push up to parent for EC*/
06311 #if defined(HAVE_PRI_CALL_WAITING)
06312    if (p->is_call_waiting) {
06313       p->is_call_waiting = 0;
06314       ast_atomic_fetchadd_int(&p->pri->num_call_waiting_calls, -1);
06315    }
06316 #endif   /* defined(HAVE_PRI_CALL_WAITING) */
06317    p->call_level = SIG_PRI_CALL_LEVEL_IDLE;
06318    p->progress = 0;
06319    p->cid_num[0] = '\0';
06320    p->cid_subaddr[0] = '\0';
06321    p->cid_name[0] = '\0';
06322    p->user_tag[0] = '\0';
06323    p->exten[0] = '\0';
06324    sig_pri_set_dialing(p, 0);
06325 
06326    /* Make sure we really have a call */
06327    pri_grab(p, p->pri);
06328    if (p->call) {
06329 #if defined(SUPPORT_USERUSER)
06330       const char *useruser = pbx_builtin_getvar_helper(ast, "USERUSERINFO");
06331 
06332       if (!ast_strlen_zero(useruser)) {
06333          pri_call_set_useruser(p->call, useruser);
06334       }
06335 #endif   /* defined(SUPPORT_USERUSER) */
06336 
06337 #if defined(HAVE_PRI_AOC_EVENTS)
06338       if (p->holding_aoce) {
06339          pri_aoc_e_send(p->pri->pri, p->call, &p->aoc_e);
06340       }
06341 #endif   /* defined(HAVE_PRI_AOC_EVENTS) */
06342 
06343       if (p->alreadyhungup) {
06344          ast_debug(1, "Already hungup...  Calling hangup once, and clearing call\n");
06345 
06346          pri_hangup(p->pri->pri, p->call, -1);
06347          p->call = NULL;
06348       } else {
06349          const char *cause = pbx_builtin_getvar_helper(ast,"PRI_CAUSE");
06350          int icause = ast->hangupcause ? ast->hangupcause : -1;
06351 
06352          p->alreadyhungup = 1;
06353          if (!ast_strlen_zero(cause)) {
06354             if (atoi(cause)) {
06355                icause = atoi(cause);
06356             }
06357          }
06358          ast_debug(1,
06359             "Not yet hungup...  Calling hangup with cause %d, and clearing call\n",
06360             icause);
06361 
06362          pri_hangup(p->pri->pri, p->call, icause);
06363       }
06364    }
06365 #if defined(HAVE_PRI_AOC_EVENTS)
06366    p->aoc_s_request_invoke_id_valid = 0;
06367    p->holding_aoce = 0;
06368    p->waiting_for_aoce = 0;
06369 #endif   /* defined(HAVE_PRI_AOC_EVENTS) */
06370 
06371    p->allocated = 0;
06372    p->owner = NULL;
06373 
06374    sig_pri_span_devstate_changed(p->pri);
06375    pri_rel(p->pri);
06376    return 0;
06377 }

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

Definition at line 6902 of file sig_pri.c.

References ast_channel::_softhangup, ast_channel::_state, sig_pri_span::aoc_passthrough_flag, 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_INVALID_NUMBER_FORMAT, AST_CAUSE_NORMAL_CLEARING, 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_INCOMPLETE, 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, sig_pri_chan::call_level, ast_channel::connected, DAHDI_OVERLAPDIAL_INCOMING, sig_pri_chan::digital, ast_channel::hangupcause, ast_party_connected_line::id, LOG_DEBUG, sig_pri_chan::mohinterpret, ast_channel::name, sig_pri_chan::no_b_channel, sig_pri_chan::outgoing, sig_pri_span::overlapdial, sig_pri_span::pri, sig_pri_chan::pri, pri_grab(), pri_rel(), sig_pri_chan::priindication_oob, sig_pri_chan::prioffset, sig_pri_chan::progress, PVT_TO_CHANNEL(), sig_pri_aoc_d_from_ast(), sig_pri_aoc_e_from_ast(), SIG_PRI_AOC_GRANT_D, SIG_PRI_AOC_GRANT_E, SIG_PRI_AOC_GRANT_S, sig_pri_aoc_s_from_ast(), SIG_PRI_CALL_LEVEL_ALERTING, SIG_PRI_CALL_LEVEL_CONNECT, SIG_PRI_CALL_LEVEL_PROCEEDING, 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_chan::waiting_for_aoce.

Referenced by dahdi_indicate().

06903 {
06904    int res = -1;
06905 
06906    switch (condition) {
06907    case AST_CONTROL_BUSY:
06908       if (p->priindication_oob || p->no_b_channel) {
06909          chan->hangupcause = AST_CAUSE_USER_BUSY;
06910          chan->_softhangup |= AST_SOFTHANGUP_DEV;
06911          res = 0;
06912          break;
06913       }
06914       res = sig_pri_play_tone(p, SIG_PRI_TONE_BUSY);
06915       if (p->call_level < SIG_PRI_CALL_LEVEL_ALERTING && !p->outgoing) {
06916          chan->hangupcause = AST_CAUSE_USER_BUSY;
06917          p->progress = 1;/* No need to send plain PROGRESS after this. */
06918          if (p->pri && p->pri->pri) {
06919             pri_grab(p, p->pri);
06920 #ifdef HAVE_PRI_PROG_W_CAUSE
06921             pri_progress_with_cause(p->pri->pri, p->call, PVT_TO_CHANNEL(p), 1, chan->hangupcause);
06922 #else
06923             pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
06924 #endif
06925             pri_rel(p->pri);
06926          }
06927       }
06928       break;
06929    case AST_CONTROL_RINGING:
06930       if (p->call_level < SIG_PRI_CALL_LEVEL_ALERTING && !p->outgoing) {
06931          p->call_level = SIG_PRI_CALL_LEVEL_ALERTING;
06932          if (p->pri && p->pri->pri) {
06933             pri_grab(p, p->pri);
06934             pri_acknowledge(p->pri->pri,p->call, PVT_TO_CHANNEL(p),
06935                p->no_b_channel || p->digital ? 0 : 1);
06936             pri_rel(p->pri);
06937          }
06938       }
06939       res = sig_pri_play_tone(p, SIG_PRI_TONE_RINGTONE);
06940       if (chan->_state != AST_STATE_UP) {
06941          if (chan->_state != AST_STATE_RING)
06942             ast_setstate(chan, AST_STATE_RINGING);
06943       }
06944       break;
06945    case AST_CONTROL_PROCEEDING:
06946       ast_debug(1,"Received AST_CONTROL_PROCEEDING on %s\n",chan->name);
06947       if (p->call_level < SIG_PRI_CALL_LEVEL_PROCEEDING && !p->outgoing) {
06948          p->call_level = SIG_PRI_CALL_LEVEL_PROCEEDING;
06949          if (p->pri && p->pri->pri) {
06950             pri_grab(p, p->pri);
06951             pri_proceeding(p->pri->pri,p->call, PVT_TO_CHANNEL(p),
06952                p->no_b_channel || p->digital ? 0 : 1);
06953             if (!p->no_b_channel && !p->digital) {
06954                sig_pri_set_dialing(p, 0);
06955             }
06956             pri_rel(p->pri);
06957          }
06958       }
06959       /* don't continue in ast_indicate */
06960       res = 0;
06961       break;
06962    case AST_CONTROL_PROGRESS:
06963       ast_debug(1,"Received AST_CONTROL_PROGRESS on %s\n",chan->name);
06964       sig_pri_set_digital(p, 0); /* Digital-only calls isn't allowing any inband progress messages */
06965       if (!p->progress && p->call_level < SIG_PRI_CALL_LEVEL_ALERTING && !p->outgoing
06966          && !p->no_b_channel) {
06967          p->progress = 1;/* No need to send plain PROGRESS again. */
06968          if (p->pri && p->pri->pri) {
06969             pri_grab(p, p->pri);
06970 #ifdef HAVE_PRI_PROG_W_CAUSE
06971             pri_progress_with_cause(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1, -1);  /* no cause at all */
06972 #else
06973             pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
06974 #endif
06975             pri_rel(p->pri);
06976          }
06977       }
06978       /* don't continue in ast_indicate */
06979       res = 0;
06980       break;
06981    case AST_CONTROL_INCOMPLETE:
06982       /* If we are connected or if we support overlap dialing, wait for additional digits */
06983       if (p->call_level == SIG_PRI_CALL_LEVEL_CONNECT || (p->pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)) {
06984          res = 0;
06985          break;
06986       }
06987       /* Otherwise, treat as congestion */
06988       chan->hangupcause = AST_CAUSE_INVALID_NUMBER_FORMAT;
06989       /* Falls through */
06990    case AST_CONTROL_CONGESTION:
06991       if (p->priindication_oob || p->no_b_channel) {
06992          /* There are many cause codes that generate an AST_CONTROL_CONGESTION. */
06993          switch (chan->hangupcause) {
06994          case AST_CAUSE_USER_BUSY:
06995          case AST_CAUSE_NORMAL_CLEARING:
06996          case 0:/* Cause has not been set. */
06997             /* Supply a more appropriate cause. */
06998             chan->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
06999             break;
07000          default:
07001             break;
07002          }
07003          chan->_softhangup |= AST_SOFTHANGUP_DEV;
07004          res = 0;
07005          break;
07006       }
07007       res = sig_pri_play_tone(p, SIG_PRI_TONE_CONGESTION);
07008       if (p->call_level < SIG_PRI_CALL_LEVEL_ALERTING && !p->outgoing) {
07009          /* There are many cause codes that generate an AST_CONTROL_CONGESTION. */
07010          switch (chan->hangupcause) {
07011          case AST_CAUSE_USER_BUSY:
07012          case AST_CAUSE_NORMAL_CLEARING:
07013          case 0:/* Cause has not been set. */
07014             /* Supply a more appropriate cause. */
07015             chan->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
07016             break;
07017          default:
07018             break;
07019          }
07020          p->progress = 1;/* No need to send plain PROGRESS after this. */
07021          if (p->pri && p->pri->pri) {
07022             pri_grab(p, p->pri);
07023 #ifdef HAVE_PRI_PROG_W_CAUSE
07024             pri_progress_with_cause(p->pri->pri, p->call, PVT_TO_CHANNEL(p), 1, chan->hangupcause);
07025 #else
07026             pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
07027 #endif
07028             pri_rel(p->pri);
07029          }
07030       }
07031       break;
07032    case AST_CONTROL_HOLD:
07033       if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) {
07034          pri_grab(p, p->pri);
07035          res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_HOLD);
07036          pri_rel(p->pri);
07037       } else
07038          ast_moh_start(chan, data, p->mohinterpret);
07039       break;
07040    case AST_CONTROL_UNHOLD:
07041       if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) {
07042          pri_grab(p, p->pri);
07043          res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_RETRIEVAL);
07044          pri_rel(p->pri);
07045       } else
07046          ast_moh_stop(chan);
07047       break;
07048    case AST_CONTROL_SRCUPDATE:
07049       res = 0;
07050       break;
07051    case -1:
07052       res = sig_pri_play_tone(p, -1);
07053       break;
07054    case AST_CONTROL_CONNECTED_LINE:
07055       ast_debug(1, "Received AST_CONTROL_CONNECTED_LINE on %s\n", chan->name);
07056       if (p->pri) {
07057          struct pri_party_connected_line connected;
07058 
07059          pri_grab(p, p->pri);
07060          memset(&connected, 0, sizeof(connected));
07061          sig_pri_party_id_from_ast(&connected.id, &chan->connected.id);
07062 
07063          pri_connected_line_update(p->pri->pri, p->call, &connected);
07064          pri_rel(p->pri);
07065       }
07066       break;
07067    case AST_CONTROL_REDIRECTING:
07068       ast_debug(1, "Received AST_CONTROL_REDIRECTING on %s\n", chan->name);
07069       if (p->pri) {
07070          pri_grab(p, p->pri);
07071          sig_pri_redirecting_update(p, chan);
07072          pri_rel(p->pri);
07073       }
07074       break;
07075    case AST_CONTROL_AOC:
07076 #if defined(HAVE_PRI_AOC_EVENTS)
07077       {
07078          struct ast_aoc_decoded *decoded
07079             = ast_aoc_decode((struct ast_aoc_encoded *) data, datalen, chan);
07080          ast_debug(1, "Received AST_CONTROL_AOC on %s\n", chan->name);
07081          if (decoded && p->pri) {
07082             pri_grab(p, p->pri);
07083             switch (ast_aoc_get_msg_type(decoded)) {
07084             case AST_AOC_S:
07085                if (p->pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_S) {
07086                   sig_pri_aoc_s_from_ast(p, decoded);
07087                }
07088                break;
07089             case AST_AOC_D:
07090                if (p->pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_D) {
07091                   sig_pri_aoc_d_from_ast(p, decoded);
07092                }
07093                break;
07094             case AST_AOC_E:
07095                if (p->pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_E) {
07096                   sig_pri_aoc_e_from_ast(p, decoded);
07097                }
07098                /* if hangup was delayed for this AOC-E msg, waiting_for_aoc
07099                 * will be set.  A hangup is already occuring via a timeout during
07100                 * this delay.  Instead of waiting for that timeout to occur, go ahead
07101                 * and initiate the softhangup since the delay is no longer necessary */
07102                if (p->waiting_for_aoce) {
07103                   p->waiting_for_aoce = 0;
07104                   ast_log(LOG_DEBUG,
07105                      "Received final AOC-E msg, continue with hangup on %s\n",
07106                      chan->name);
07107                   ast_softhangup_nolock(chan, AST_SOFTHANGUP_DEV);
07108                }
07109                break;
07110             case AST_AOC_REQUEST:
07111                /* We do not pass through AOC requests, So unless this
07112                 * is an AOC termination request it will be ignored */
07113                if (ast_aoc_get_termination_request(decoded)) {
07114                   pri_hangup(p->pri->pri, p->call, -1);
07115                }
07116                break;
07117             default:
07118                break;
07119             }
07120             pri_rel(p->pri);
07121          }
07122          ast_aoc_destroy_decoded(decoded);
07123       }
07124 #endif   /* defined(HAVE_PRI_AOC_EVENTS) */
07125       break;
07126    }
07127 
07128    return res;
07129 }

void sig_pri_init_pri ( struct sig_pri_span pri  ) 

Definition at line 6288 of file sig_pri.c.

References ast_mutex_init, AST_PTHREADT_NULL, and SIG_PRI_NUM_DCHANS.

Referenced by load_module().

06289 {
06290    int i;
06291 
06292    memset(pri, 0, sizeof(*pri));
06293 
06294    ast_mutex_init(&pri->lock);
06295 
06296    pri->master = AST_PTHREADT_NULL;
06297    for (i = 0; i < SIG_PRI_NUM_DCHANS; i++)
06298       pri->fds[i] = -1;
06299 }

int sig_pri_is_chan_available ( struct sig_pri_chan pvt  ) 

Determine if a private channel structure is available.

Since:
1.8
Parameters:
pvt Channel to determine if available.
Returns:
TRUE if the channel is available.

Definition at line 1127 of file sig_pri.c.

References sig_pri_chan::service_status, and sig_pri_is_chan_in_use().

Referenced by dahdi_pri_update_span_devstate(), pri_dchannel(), pri_find_empty_chan(), pri_find_empty_nobch(), pri_fixup_principle(), sig_pri_available_check(), sig_pri_cli_show_channels(), and sig_pri_handle_retrieve().

01128 {
01129    return !sig_pri_is_chan_in_use(pvt)
01130 #if defined(HAVE_PRI_SERVICE_MESSAGES)
01131       /* And not out-of-service */
01132       && !pvt->service_status
01133 #endif   /* defined(HAVE_PRI_SERVICE_MESSAGES) */
01134       ;
01135 }

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 8498 of file sig_pri.c.

References ao2_container_alloc, sig_pri_cc_monitor_instance_cmp_fn(), sig_pri_cc_monitor_instance_hash_fn(), sig_pri_cc_monitors, and sig_pri_cc_type_name.

Referenced by load_module().

08499 {
08500 #if defined(HAVE_PRI_CCSS)
08501    sig_pri_cc_type_name = cc_type_name;
08502    sig_pri_cc_monitors = ao2_container_alloc(37, sig_pri_cc_monitor_instance_hash_fn,
08503       sig_pri_cc_monitor_instance_cmp_fn);
08504    if (!sig_pri_cc_monitors) {
08505       return -1;
08506    }
08507 #endif   /* defined(HAVE_PRI_CCSS) */
08508    return 0;
08509 }

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 981 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().

00982 {
00983    struct ast_channel *ast;
00984 
00985    ast_log(LOG_DEBUG, "%s %d\n", __FUNCTION__, p->channel);
00986 
00987    p->outgoing = 1;
00988    ast = sig_pri_new_ast_channel(p, AST_STATE_RESERVED, law, transfercapability, p->exten, requestor);
00989    if (!ast) {
00990       p->outgoing = 0;
00991    }
00992    return ast;
00993 }

void sig_pri_set_alarm ( struct sig_pri_chan p,
int  in_alarm 
)

Definition at line 181 of file sig_pri.c.

References sig_pri_chan::calls, sig_pri_chan::chan_pvt, sig_pri_chan::inalarm, sig_pri_chan::resetting, and sig_pri_callback::set_alarm.

Referenced by sig_pri_chan_alarm_notify().

00182 {
00183    /*
00184     * Clear the channel restart flag when the channel alarm changes
00185     * to prevent the flag from getting stuck when the link goes
00186     * down.
00187     */
00188    p->resetting = 0;
00189 
00190    p->inalarm = in_alarm;
00191    if (p->calls->set_alarm) {
00192       p->calls->set_alarm(p->chan_pvt, in_alarm);
00193    }
00194 }

int sig_pri_start_pri ( struct sig_pri_span pri  ) 

Definition at line 7483 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_mbox::context, 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::mbox, sig_pri_span::mwi_mailboxes, sig_pri_span::nodetype, sig_pri_mbox::number, sig_pri_span::sig, SIG_BRI, SIG_BRI_PTMP, sig_pri_cc_type_name, sig_pri_mwi_event_cb(), SIG_PRI_NUM_DCHANS, sig_pri_sort_pri_chans(), sig_pri_span::span, strsep(), sig_pri_mbox::sub, and sig_pri_span::switchtype.

Referenced by setup_dahdi_int().

07484 {
07485    int x;
07486    int i;
07487 #if defined(HAVE_PRI_MWI)
07488    char *saveptr;
07489    char *mbox_number;
07490    char *mbox_context;
07491    struct ast_str *mwi_description = ast_str_alloca(64);
07492 #endif   /* defined(HAVE_PRI_MWI) */
07493 
07494 #if defined(HAVE_PRI_MWI)
07495    /* Prepare the mbox[] for use. */
07496    for (i = 0; i < ARRAY_LEN(pri->mbox); ++i) {
07497       if (pri->mbox[i].sub) {
07498          pri->mbox[i].sub = ast_event_unsubscribe(pri->mbox[i].sub);
07499       }
07500    }
07501 #endif   /* defined(HAVE_PRI_MWI) */
07502 
07503    ast_mutex_init(&pri->lock);
07504    sig_pri_sort_pri_chans(pri);
07505 
07506 #if defined(HAVE_PRI_MWI)
07507    /*
07508     * Split the mwi_mailboxes configuration string into the mbox[]:
07509     * mailbox_number[@context]{,mailbox_number[@context]}
07510     */
07511    i = 0;
07512    saveptr = pri->mwi_mailboxes;
07513    while (i < ARRAY_LEN(pri->mbox)) {
07514       mbox_number = strsep(&saveptr, ",");
07515       if (!mbox_number) {
07516          break;
07517       }
07518       /* Split the mailbox_number and context */
07519       mbox_context = strchr(mbox_number, '@');
07520       if (mbox_context) {
07521          *mbox_context++ = '\0';
07522          mbox_context = ast_strip(mbox_context);
07523       }
07524       mbox_number = ast_strip(mbox_number);
07525       if (ast_strlen_zero(mbox_number)) {
07526          /* There is no mailbox number.  Skip it. */
07527          continue;
07528       }
07529       if (ast_strlen_zero(mbox_context)) {
07530          /* There was no context so use the default. */
07531          mbox_context = "default";
07532       }
07533 
07534       /* Fill the mbox[] element. */
07535       ast_str_set(&mwi_description, -1, "%s span %d[%d] MWI mailbox %s@%s",
07536          sig_pri_cc_type_name, pri->span, i, mbox_number, mbox_context);
07537       pri->mbox[i].sub = ast_event_subscribe(AST_EVENT_MWI, sig_pri_mwi_event_cb,
07538          ast_str_buffer(mwi_description), pri,
07539          AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mbox_number,
07540          AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, mbox_context,
07541          AST_EVENT_IE_END);
07542       if (!pri->mbox[i].sub) {
07543          ast_log(LOG_ERROR, "%s span %d could not subscribe to MWI events for %s@%s.",
07544             sig_pri_cc_type_name, pri->span, mbox_number, mbox_context);
07545          continue;
07546       }
07547       pri->mbox[i].number = mbox_number;
07548       pri->mbox[i].context = mbox_context;
07549       ++i;
07550    }
07551 #endif   /* defined(HAVE_PRI_MWI) */
07552 
07553    for (i = 0; i < SIG_PRI_NUM_DCHANS; i++) {
07554       if (pri->fds[i] == -1) {
07555          break;
07556       }
07557 
07558       switch (pri->sig) {
07559       case SIG_BRI:
07560          pri->dchans[i] = pri_new_bri(pri->fds[i], 1, pri->nodetype, pri->switchtype);
07561          break;
07562       case SIG_BRI_PTMP:
07563          pri->dchans[i] = pri_new_bri(pri->fds[i], 0, pri->nodetype, pri->switchtype);
07564          break;
07565       default:
07566          pri->dchans[i] = pri_new(pri->fds[i], pri->nodetype, pri->switchtype);
07567 #if defined(HAVE_PRI_SERVICE_MESSAGES)
07568          if (pri->enable_service_message_support) {
07569             pri_set_service_message_support(pri->dchans[i], 1);
07570          }
07571 #endif   /* defined(HAVE_PRI_SERVICE_MESSAGES) */
07572          break;
07573       }
07574 
07575       pri_set_overlapdial(pri->dchans[i], (pri->overlapdial & DAHDI_OVERLAPDIAL_OUTGOING) ? 1 : 0);
07576 #ifdef HAVE_PRI_PROG_W_CAUSE
07577       pri_set_chan_mapping_logical(pri->dchans[i], pri->qsigchannelmapping == DAHDI_CHAN_MAPPING_LOGICAL);
07578 #endif
07579 #ifdef HAVE_PRI_INBANDDISCONNECT
07580       pri_set_inbanddisconnect(pri->dchans[i], pri->inbanddisconnect);
07581 #endif
07582       /* Enslave to master if appropriate */
07583       if (i)
07584          pri_enslave(pri->dchans[0], pri->dchans[i]);
07585       if (!pri->dchans[i]) {
07586          if (pri->fds[i] > 0)
07587             close(pri->fds[i]);
07588          pri->fds[i] = -1;
07589          ast_log(LOG_ERROR, "Unable to create PRI structure\n");
07590          return -1;
07591       }
07592       pri_set_debug(pri->dchans[i], SIG_PRI_DEBUG_DEFAULT);
07593       pri_set_nsf(pri->dchans[i], pri->nsf);
07594 #ifdef PRI_GETSET_TIMERS
07595       for (x = 0; x < PRI_MAX_TIMERS; x++) {
07596          if (pri->pritimers[x] != 0)
07597             pri_set_timer(pri->dchans[i], x, pri->pritimers[x]);
07598       }
07599 #endif
07600    }
07601 
07602    /* Assume primary is the one we use */
07603    pri->pri = pri->dchans[0];
07604 
07605 #if defined(HAVE_PRI_CALL_HOLD)
07606    pri_hold_enable(pri->pri, 1);
07607 #endif   /* defined(HAVE_PRI_CALL_HOLD) */
07608 #if defined(HAVE_PRI_CALL_REROUTING)
07609    pri_reroute_enable(pri->pri, 1);
07610 #endif   /* defined(HAVE_PRI_CALL_REROUTING) */
07611 #if defined(HAVE_PRI_HANGUP_FIX)
07612    pri_hangup_fix_enable(pri->pri, 1);
07613 #endif   /* defined(HAVE_PRI_HANGUP_FIX) */
07614 #if defined(HAVE_PRI_CCSS)
07615    pri_cc_enable(pri->pri, 1);
07616    pri_cc_recall_mode(pri->pri, pri->cc_ptmp_recall_mode);
07617    pri_cc_retain_signaling_req(pri->pri, pri->cc_qsig_signaling_link_req);
07618    pri_cc_retain_signaling_rsp(pri->pri, pri->cc_qsig_signaling_link_rsp);
07619 #endif   /* defined(HAVE_PRI_CCSS) */
07620 #if defined(HAVE_PRI_TRANSFER)
07621    pri_transfer_enable(pri->pri, 1);
07622 #endif   /* defined(HAVE_PRI_TRANSFER) */
07623 #if defined(HAVE_PRI_AOC_EVENTS)
07624    pri_aoc_events_enable(pri->pri, 1);
07625 #endif   /* defined(HAVE_PRI_AOC_EVENTS) */
07626 #if defined(HAVE_PRI_CALL_WAITING)
07627    pri_connect_ack_enable(pri->pri, 1);
07628 #endif   /* defined(HAVE_PRI_CALL_WAITING) */
07629 #if defined(HAVE_PRI_MCID)
07630    pri_mcid_enable(pri->pri, 1);
07631 #endif   /* defined(HAVE_PRI_MCID) */
07632 #if defined(HAVE_PRI_L2_PERSISTENCE)
07633    pri_persistent_layer2_option(pri->pri, pri->l2_persistence);
07634 #endif   /* defined(HAVE_PRI_L2_PERSISTENCE) */
07635 
07636    pri->resetpos = -1;
07637    if (ast_pthread_create_background(&pri->master, NULL, pri_dchannel, pri)) {
07638       for (i = 0; i < SIG_PRI_NUM_DCHANS; i++) {
07639          if (!pri->dchans[i])
07640             break;
07641          if (pri->fds[i] > 0)
07642             close(pri->fds[i]);
07643          pri->fds[i] = -1;
07644       }
07645       ast_log(LOG_ERROR, "Unable to spawn D-channel: %s\n", strerror(errno));
07646       return -1;
07647    }
07648 
07649 #if defined(HAVE_PRI_MWI)
07650    /*
07651     * Send the initial MWI indications from the event cache for this span.
07652     *
07653     * If we were loaded after app_voicemail the event would already be in
07654     * the cache.  If we were loaded before app_voicemail the event would not
07655     * be in the cache yet and app_voicemail will send the event when it
07656     * gets loaded.
07657     */
07658    sig_pri_mwi_cache_update(pri);
07659 #endif   /* defined(HAVE_PRI_MWI) */
07660 
07661    return 0;
07662 }

void sig_pri_stop_pri ( struct sig_pri_span pri  ) 

Stop PRI span.

Since:
1.8
Parameters:
pri PRI span control structure.
Returns:
Nothing

Definition at line 7418 of file sig_pri.c.

References ARRAY_LEN, ast_event_unsubscribe(), sig_pri_span::mbox, and sig_pri_mbox::sub.

Referenced by __unload_module().

07419 {
07420 #if defined(HAVE_PRI_MWI)
07421    int idx;
07422 #endif   /* defined(HAVE_PRI_MWI) */
07423 
07424 #if defined(HAVE_PRI_MWI)
07425    for (idx = 0; idx < ARRAY_LEN(pri->mbox); ++idx) {
07426       if (pri->mbox[idx].sub) {
07427          pri->mbox[idx].sub = ast_event_unsubscribe(pri->mbox[idx].sub);
07428       }
07429    }
07430 #endif   /* defined(HAVE_PRI_MWI) */
07431 }

void sig_pri_unload ( void   ) 

Unload the sig_pri submodule.

Since:
1.8
Returns:
Nothing

Definition at line 8517 of file sig_pri.c.

References ao2_ref, and sig_pri_cc_monitors.

Referenced by __unload_module().

08518 {
08519 #if defined(HAVE_PRI_CCSS)
08520    if (sig_pri_cc_monitors) {
08521       ao2_ref(sig_pri_cc_monitors, -1);
08522       sig_pri_cc_monitors = NULL;
08523    }
08524 #endif   /* defined(HAVE_PRI_CCSS) */
08525 }


Variable Documentation

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

The AstDB family.

Definition at line 194 of file sig_pri.h.

Referenced by destroy_all_channels().


Generated on Mon Mar 19 11:30:55 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7