Mon Jun 27 16:51:21 2011

Asterisk developer's documentation


sig_pri.h File Reference

Interface header for PRI signaling module. More...

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

Go to the source code of this file.

Data Structures

struct  sig_pri_callback
struct  sig_pri_chan
struct  sig_pri_span

Defines

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

Enumerations

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

Variables

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


Detailed Description

Interface header for PRI signaling module.

Author:
Matthew Fredrickson <creslin@digium.com>

Definition in file sig_pri.h.


Define Documentation

#define DAHDI_CHAN_MAPPING_LOGICAL   1

Definition at line 157 of file sig_pri.h.

#define DAHDI_CHAN_MAPPING_PHYSICAL   0

Definition at line 156 of file sig_pri.h.

Referenced by dahdi_chan_conf_default().

#define DAHDI_OVERLAPDIAL_BOTH   (DAHDI_OVERLAPDIAL_INCOMING|DAHDI_OVERLAPDIAL_OUTGOING)

Definition at line 163 of file sig_pri.h.

#define DAHDI_OVERLAPDIAL_INCOMING   2

Definition at line 162 of file sig_pri.h.

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

#define DAHDI_OVERLAPDIAL_NONE   0

Definition at line 160 of file sig_pri.h.

#define DAHDI_OVERLAPDIAL_OUTGOING   1

Definition at line 161 of file sig_pri.h.

Referenced by dahdi_read().

#define SIG_BRI   (0x2000000 | DAHDI_SIG_CLEAR)

Definition at line 152 of file sig_pri.h.

#define SIG_BRI_PTMP   (0X4000000 | DAHDI_SIG_CLEAR)

Definition at line 153 of file sig_pri.h.

#define SIG_PRI   DAHDI_SIG_CLEAR

Definition at line 151 of file sig_pri.h.

#define SIG_PRI_AOC_GRANT_D   (1 << 1)

Definition at line 67 of file sig_pri.h.

Referenced by sig_pri_handle_subcmds(), and sig_pri_indicate().

#define SIG_PRI_AOC_GRANT_E   (1 << 2)

Definition at line 68 of file sig_pri.h.

Referenced by sig_pri_handle_subcmds(), and sig_pri_indicate().

#define SIG_PRI_AOC_GRANT_S   (1 << 0)

Definition at line 66 of file sig_pri.h.

Referenced by sig_pri_handle_subcmds(), and sig_pri_indicate().

#define SIG_PRI_DEBUG_DEFAULT   0

PRI debug message flags set on initial startup.

Definition at line 63 of file sig_pri.h.

#define SIG_PRI_DEBUG_INTENSE

Value:

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

Definition at line 53 of file sig_pri.h.

Referenced by handle_pri_debug().

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

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

Definition at line 49 of file sig_pri.h.

Referenced by handle_pri_debug().

#define SIG_PRI_MAX_CHANNELS   672

No more than a DS3 per trunk group

Definition at line 149 of file sig_pri.h.

#define SIG_PRI_NUM_DCHANS   4

No more than 4 d-channels

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

#define SRVST_DBKEY   "service-state"

Persistent Service State.

Definition at line 167 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 179 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 175 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 177 of file sig_pri.h.

Referenced by pri_check_restart().

#define SRVST_TYPE_OOS   "O"

The out-of-service SERVICE state.

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

01689 {
01690    pri->dchanavail[index] &= ~(DCHAN_NOTINALARM | DCHAN_UP);
01691    if (!before_start_pri)
01692       pri_find_dchan(pri);
01693 }

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

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

01696 {
01697    pri->dchanavail[index] |= DCHAN_NOTINALARM;
01698    if (!before_start_pri)
01699       pri_restart(pri->dchans[index]);
01700 }

int pri_is_up ( struct sig_pri_span pri  ) 

Definition at line 930 of file sig_pri.c.

References DCHAN_AVAILABLE, sig_pri_span::dchanavail, and SIG_PRI_NUM_DCHANS.

Referenced by pri_dchannel().

00931 {
00932    int x;
00933    for (x = 0; x < SIG_PRI_NUM_DCHANS; x++) {
00934       if (pri->dchanavail[x] == DCHAN_AVAILABLE)
00935          return 1;
00936    }
00937    return 0;
00938 }

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

Definition at line 7463 of file sig_pri.c.

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

07464 {
07465    int channel = PVT_TO_CHANNEL(p);
07466    int span = PRI_SPAN(channel);
07467 
07468    return pri_maintenance_service(pri, span, channel, changestatus);
07469 }

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

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

Referenced by dahdi_send_callrerouting_facility_exec().

07439 {
07440    int res = -1;
07441 
07442    sig_pri_lock_private(p);
07443 
07444    if (!p->pri || !p->call) {
07445       ast_log(LOG_DEBUG, "Unable to find pri or call on channel!\n");
07446       sig_pri_unlock_private(p);
07447       return -1;
07448    }
07449 
07450    if (!pri_grab(p, p->pri)) {
07451       res = pri_callrerouting_facility(p->pri->pri, p->call, destination, original, reason);
07452       pri_rel(p->pri);
07453    } else {
07454       ast_log(LOG_DEBUG, "Unable to grab pri to send callrerouting facility on span %d!\n", p->pri->span);
07455    }
07456 
07457    sig_pri_unlock_private(p);
07458 
07459    return res;
07460 }

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

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

07415 {
07416    sig_pri_lock_private(p);
07417 
07418    if (!p->pri || !p->call) {
07419       ast_debug(1, "Unable to find pri or call on channel!\n");
07420       sig_pri_unlock_private(p);
07421       return -1;
07422    }
07423 
07424    if (!pri_grab(p, p->pri)) {
07425       pri_keypad_facility(p->pri->pri, p->call, digits);
07426       pri_rel(p->pri);
07427    } else {
07428       ast_debug(1, "Unable to grab pri to send keypad facility!\n");
07429       sig_pri_unlock_private(p);
07430       return -1;
07431    }
07432 
07433    sig_pri_unlock_private(p);
07434 
07435    return 0;
07436 }

int sig_pri_answer ( struct sig_pri_chan p,
struct ast_channel ast 
)

Definition at line 6763 of file sig_pri.c.

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

06764 {
06765    int res = 0;
06766    /* Send a pri acknowledge */
06767    if (!pri_grab(p, p->pri)) {
06768 #if defined(HAVE_PRI_AOC_EVENTS)
06769       if (p->aoc_s_request_invoke_id_valid) {
06770          /* if AOC-S was requested and the invoke id is still present on answer.  That means
06771           * no AOC-S rate list was provided, so send a NULL response which will indicate that
06772           * AOC-S is not available */
06773          pri_aoc_s_request_response_send(p->pri->pri, p->call,
06774             p->aoc_s_request_invoke_id, NULL);
06775          p->aoc_s_request_invoke_id_valid = 0;
06776       }
06777 #endif   /* defined(HAVE_PRI_AOC_EVENTS) */
06778       if (p->call_level < SIG_PRI_CALL_LEVEL_CONNECT) {
06779          p->call_level = SIG_PRI_CALL_LEVEL_CONNECT;
06780       }
06781       sig_pri_set_dialing(p, 0);
06782       sig_pri_open_media(p);
06783       res = pri_answer(p->pri->pri, p->call, 0, !p->digital);
06784       pri_rel(p->pri);
06785    } else {
06786       res = -1;
06787    }
06788    ast_setstate(ast, AST_STATE_UP);
06789    return res;
06790 }

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

Definition at line 6867 of file sig_pri.c.

References sig_pri_chan::pri, and sig_pri_available_check().

Referenced by available().

06868 {
06869    struct sig_pri_chan *p = *pvt;
06870 
06871    if (!p->pri) {
06872       /* Something is wrong here.  A PRI channel without the pri pointer? */
06873       return 0;
06874    }
06875 
06876    if (
06877 #if defined(HAVE_PRI_CALL_WAITING)
06878       /*
06879        * Only do call waiting calls if we have any
06880        * call waiting call outstanding.  We do not
06881        * want new calls to steal a B channel
06882        * freed for an earlier call waiting call.
06883        */
06884       !p->pri->num_call_waiting_calls &&
06885 #endif   /* defined(HAVE_PRI_CALL_WAITING) */
06886       sig_pri_available_check(p)) {
06887       return 1;
06888    }
06889 
06890 #if defined(HAVE_PRI_CALL_WAITING)
06891    if (!is_specific_channel) {
06892       struct sig_pri_chan *cw;
06893 
06894       cw = sig_pri_cw_available(p->pri);
06895       if (cw) {
06896          /* We have a call waiting interface to use instead. */
06897          *pvt = cw;
06898          return 1;
06899       }
06900    }
06901 #endif   /* defined(HAVE_PRI_CALL_WAITING) */
06902    return 0;
06903 }

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 6091 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_chan::channel, ast_channel::connected, sig_pri_chan::dialdest, sig_pri_span::dialplan, dialplan2str(), sig_pri_chan::digital, ext, sig_pri_span::facilityenable, sig_pri_chan::hidecallerid, sig_pri_chan::hidecalleridname, ast_party_caller::id, ast_party_connected_line::id, sig_pri_span::initial_user_tag, sig_pri_span::internationalprefix, IS_DIGITAL, sig_pri_span::localdialplan, LOG_DEBUG, LOG_ERROR, LOG_WARNING, monitor, ast_channel::name, ast_party_id::name, sig_pri_span::nationalprefix, sig_pri_span::nodetype, ast_party_id::number, ast_party_subaddress::odd_even_indicator, OPT_AOC_REQUEST, OPT_ARG_AOC_REQUEST, OPT_ARG_ARRAY_SIZE, OPT_ARG_KEYPAD, OPT_KEYPAD, OPT_REVERSE_CHARGE, sig_pri_chan::outgoing, sig_pri_chan::owner, pbx_builtin_getvar_helper(), ast_party_number::presentation, sig_pri_span::pri, sig_pri_chan::pri, pri_grab(), pri_rel(), PRI_TRANS_CAP_DIGITAL, sig_pri_chan::priexclusive, PVT_TO_CHANNEL(), S_COR, SIG_PRI_CALL_LEVEL_SETUP, sig_pri_call_opts, sig_pri_party_subaddress_from_ast(), sig_pri_redirecting_update(), sig_pri_set_dialing(), sig_pri_set_digital(), ast_party_subaddress::str, ast_party_number::str, ast_party_name::str, sig_pri_chan::stripmsd, ast_party_id::subaddress, ast_party_id::tag, ast_channel::transfercapability, ast_party_subaddress::type, sig_pri_chan::use_callingpres, sig_pri_chan::user_tag, ast_party_subaddress::valid, ast_party_number::valid, and ast_party_name::valid.

Referenced by dahdi_call().

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

int sig_pri_cc_agent_callee_available ( struct ast_cc_agent agent  ) 

void sig_pri_cc_agent_destructor ( struct ast_cc_agent agent  ) 

int sig_pri_cc_agent_init ( struct ast_cc_agent agent,
struct sig_pri_chan pvt_chan 
)

int sig_pri_cc_agent_party_b_free ( struct ast_cc_agent agent  ) 

void sig_pri_cc_agent_req_rsp ( struct ast_cc_agent agent,
enum ast_cc_agent_response_reason  reason 
)

int sig_pri_cc_agent_start_monitoring ( struct ast_cc_agent agent  ) 

int sig_pri_cc_agent_start_offer_timer ( struct ast_cc_agent agent  ) 

int sig_pri_cc_agent_status_req ( struct ast_cc_agent agent  ) 

int sig_pri_cc_agent_stop_offer_timer ( struct ast_cc_agent agent  ) 

int sig_pri_cc_agent_stop_ringing ( struct ast_cc_agent agent  ) 

int sig_pri_cc_monitor_cancel_available_timer ( struct ast_cc_monitor monitor,
int *  sched_id 
)

void sig_pri_cc_monitor_destructor ( void *  monitor_pvt  ) 

int sig_pri_cc_monitor_req_cc ( struct ast_cc_monitor monitor,
int *  available_timer_id 
)

int sig_pri_cc_monitor_status_rsp ( struct ast_cc_monitor monitor,
enum ast_device_state  devstate 
)

int sig_pri_cc_monitor_suspend ( struct ast_cc_monitor monitor  ) 

int sig_pri_cc_monitor_unsuspend ( struct ast_cc_monitor monitor  ) 

void sig_pri_chan_alarm_notify ( struct sig_pri_chan p,
int  noalarm 
)

Definition at line 7296 of file sig_pri.c.

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

Referenced by dahdi_handle_event(), and handle_init_event().

07297 {
07298    sig_pri_set_alarm(p, !noalarm);
07299    if (!noalarm) {
07300       if (!p->pri || !p->pri->pri || (pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0)) {
07301          /* T309 is not enabled : hangup calls when alarm occurs */
07302          if (p->call) {
07303             if (p->pri && p->pri->pri) {
07304                if (!pri_grab(p, p->pri)) {
07305                   pri_hangup(p->pri->pri, p->call, -1);
07306                   pri_destroycall(p->pri->pri, p->call);
07307                   p->call = NULL;
07308                   pri_rel(p->pri);
07309                } else
07310                   ast_log(LOG_WARNING, "Failed to grab PRI!\n");
07311             } else
07312                ast_log(LOG_WARNING, "The PRI Call has not been destroyed\n");
07313          }
07314          if (p->owner)
07315             p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
07316       }
07317    }
07318 }

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

References ast_free.

Referenced by destroy_dahdi_pvt().

07349 {
07350    ast_free(doomed);
07351 }

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

References ast_calloc, and sig_pri_chan::pri.

07321 {
07322    struct sig_pri_chan *p;
07323 
07324    p = ast_calloc(1, sizeof(*p));
07325    if (!p)
07326       return p;
07327 
07328    p->logicalspan = logicalspan;
07329    p->prioffset = channo;
07330    p->mastertrunkgroup = trunkgroup;
07331 
07332    p->calls = callback;
07333    p->chan_pvt = pvt_data;
07334 
07335    p->pri = pri;
07336 
07337    return p;
07338 }

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

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

07385 {
07386    int x;
07387    char status[256];
07388 
07389    for (x = 0; x < SIG_PRI_NUM_DCHANS; x++) {
07390       if (pri->dchans[x]) {
07391 #ifdef PRI_DUMP_INFO_STR
07392          char *info_str = NULL;
07393 #endif
07394          ast_cli(fd, "%s D-channel: %d\n", pri_order(x), dchannels[x]);
07395          build_status(status, sizeof(status), pri->dchanavail[x], pri->dchans[x] == pri->pri);
07396          ast_cli(fd, "Status: %s\n", status);
07397          ast_mutex_lock(&pri->lock);
07398 #ifdef PRI_DUMP_INFO_STR
07399          info_str = pri_dump_info_str(pri->pri);
07400          if (info_str) {
07401             ast_cli(fd, "%s", info_str);
07402             free(info_str);
07403          }
07404 #else
07405          pri_dump_info(pri->pri);
07406 #endif
07407          ast_mutex_unlock(&pri->lock);
07408          ast_cli(fd, "Overlap Recv: %s\n\n", (pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)?"Yes":"No");
07409          ast_cli(fd, "\n");
07410       }
07411    }
07412 }

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

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

07373 {
07374    char status[256];
07375    int x;
07376    for (x = 0; x < SIG_PRI_NUM_DCHANS; x++) {
07377       if (pri->dchans[x]) {
07378          build_status(status, sizeof(status), pri->dchanavail[x], pri->dchans[x] == pri->pri);
07379          ast_cli(fd, "PRI span %d/%d: %s\n", span, x, status);
07380       }
07381    }
07382 }

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

Definition at line 6907 of file sig_pri.c.

References ast_channel::_state, ast_debug, ast_log(), AST_STATE_DIALING, sig_pri_chan::call, sig_pri_chan::call_level, sig_pri_chan::dialdest, LOG_WARNING, sig_pri_span::pri, sig_pri_chan::pri, pri_grab(), pri_rel(), 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().

06908 {
06909    if (ast->_state == AST_STATE_DIALING) {
06910       if (pvt->call_level < SIG_PRI_CALL_LEVEL_OVERLAP) {
06911          unsigned int len;
06912 
06913          len = strlen(pvt->dialdest);
06914          if (len < sizeof(pvt->dialdest) - 1) {
06915             ast_debug(1, "Queueing digit '%c' since setup_ack not yet received\n",
06916                digit);
06917             pvt->dialdest[len++] = digit;
06918             pvt->dialdest[len] = '\0';
06919          } else {
06920             ast_log(LOG_WARNING,
06921                "Span %d: Deferred digit buffer overflow for digit '%c'.\n",
06922                pvt->pri->span, digit);
06923          }
06924          return 0;
06925       }
06926       if (pvt->call_level < SIG_PRI_CALL_LEVEL_PROCEEDING) {
06927          if (!pri_grab(pvt, pvt->pri)) {
06928             pri_information(pvt->pri->pri, pvt->call, digit);
06929             pri_rel(pvt->pri);
06930          } else {
06931             ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", pvt->pri->span);
06932          }
06933          return 0;
06934       }
06935       if (pvt->call_level < SIG_PRI_CALL_LEVEL_CONNECT) {
06936          ast_log(LOG_WARNING,
06937             "Span %d: Digit '%c' may be ignored by peer. (Call level:%d)\n",
06938             pvt->pri->span, digit, pvt->call_level);
06939       }
06940    }
06941    return 1;
06942 }

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

06013 {
06014    char *dial;
06015    char *number;
06016    char *subaddr;
06017    AST_DECLARE_APP_ARGS(args,
06018       AST_APP_ARG(group);  /* channel/group token */
06019       AST_APP_ARG(ext); /* extension token */
06020       //AST_APP_ARG(opts); /* options token */
06021       AST_APP_ARG(other);  /* Any remining unused arguments */
06022    );
06023 
06024    /* Get private copy of dial string and break it up. */
06025    dial = ast_strdupa(rdest);
06026    AST_NONSTANDARD_APP_ARGS(args, dial, '/');
06027 
06028    number = args.ext;
06029    if (!number) {
06030       number = "";
06031    }
06032 
06033    /* Find and extract dialed_subaddress */
06034    subaddr = strchr(number, ':');
06035    if (subaddr) {
06036       *subaddr++ = '\0';
06037 
06038       /* Skip subaddress type prefix. */
06039       switch (*subaddr) {
06040       case 'U':
06041       case 'u':
06042       case 'N':
06043       case 'n':
06044          ++subaddr;
06045          break;
06046       default:
06047          break;
06048       }
06049    }
06050 
06051    /* Skip type-of-number/dial-plan prefix characters. */
06052    if (strlen(number) < p->stripmsd) {
06053       number = "";
06054    } else {
06055       number += p->stripmsd;
06056       while (isalpha(*number)) {
06057          ++number;
06058       }
06059    }
06060 
06061    /* Fill buffer with extracted number and subaddress. */
06062    if (ast_strlen_zero(subaddr)) {
06063       /* Put in called number only since there is no subaddress. */
06064       snprintf(called, called_buff_size, "%s", number);
06065    } else {
06066       /* Put in called number and subaddress. */
06067       snprintf(called, called_buff_size, "%s:%s", number, subaddr);
06068    }
06069 }

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

Definition at line 7472 of file sig_pri.c.

References sig_pri_chan::owner.

07473 {
07474    if (pchan->owner == oldchan) {
07475       pchan->owner = newchan;
07476    }
07477 }

int sig_pri_hangup ( struct sig_pri_chan p,
struct ast_channel ast 
)

Definition at line 5912 of file sig_pri.c.

References sig_pri_chan::alreadyhungup, ast_atomic_fetchadd_int(), ast_log(), 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, LOG_DEBUG, LOG_WARNING, sig_pri_chan::outgoing, sig_pri_chan::owner, pbx_builtin_getvar_helper(), sig_pri_span::pri, sig_pri_chan::pri, pri_grab(), pri_rel(), sig_pri_chan::progress, SIG_PRI_CALL_LEVEL_IDLE, sig_pri_set_dialing(), sig_pri_set_digital(), sig_pri_span_devstate_changed(), sig_pri_span::span, ast_channel::tech_pvt, and sig_pri_chan::user_tag.

Referenced by dahdi_hangup().

05913 {
05914    int res;
05915 #ifdef SUPPORT_USERUSER
05916    const char *useruser = pbx_builtin_getvar_helper(ast, "USERUSERINFO");
05917 #endif
05918 
05919    ast_log(LOG_DEBUG, "%s %d\n", __FUNCTION__, p->channel);
05920    if (!ast->tech_pvt) {
05921       ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
05922       return 0;
05923    }
05924 
05925    p->owner = NULL;
05926    p->outgoing = 0;
05927    sig_pri_set_digital(p, 0); /* push up to parent for EC*/
05928 #if defined(HAVE_PRI_CALL_WAITING)
05929    if (p->is_call_waiting) {
05930       p->is_call_waiting = 0;
05931       ast_atomic_fetchadd_int(&p->pri->num_call_waiting_calls, -1);
05932    }
05933 #endif   /* defined(HAVE_PRI_CALL_WAITING) */
05934    p->call_level = SIG_PRI_CALL_LEVEL_IDLE;
05935    p->progress = 0;
05936    p->cid_num[0] = '\0';
05937    p->cid_subaddr[0] = '\0';
05938    p->cid_name[0] = '\0';
05939    p->user_tag[0] = '\0';
05940    p->exten[0] = '\0';
05941    sig_pri_set_dialing(p, 0);
05942 
05943    /* Make sure we have a call (or REALLY have a call in the case of a PRI) */
05944    if (!pri_grab(p, p->pri)) {
05945       if (p->call) {
05946          if (p->alreadyhungup) {
05947             ast_log(LOG_DEBUG, "Already hungup...  Calling hangup once, and clearing call\n");
05948 
05949 #ifdef SUPPORT_USERUSER
05950             pri_call_set_useruser(p->call, useruser);
05951 #endif
05952 
05953 #if defined(HAVE_PRI_AOC_EVENTS)
05954             if (p->holding_aoce) {
05955                pri_aoc_e_send(p->pri->pri, p->call, &p->aoc_e);
05956             }
05957 #endif   /* defined(HAVE_PRI_AOC_EVENTS) */
05958             pri_hangup(p->pri->pri, p->call, -1);
05959             p->call = NULL;
05960          } else {
05961             const char *cause = pbx_builtin_getvar_helper(ast,"PRI_CAUSE");
05962             int icause = ast->hangupcause ? ast->hangupcause : -1;
05963             ast_log(LOG_DEBUG, "Not yet hungup...  Calling hangup once with icause, and clearing call\n");
05964 
05965 #ifdef SUPPORT_USERUSER
05966             pri_call_set_useruser(p->call, useruser);
05967 #endif
05968 
05969             p->alreadyhungup = 1;
05970             if (cause) {
05971                if (atoi(cause))
05972                   icause = atoi(cause);
05973             }
05974 #if defined(HAVE_PRI_AOC_EVENTS)
05975             if (p->holding_aoce) {
05976                pri_aoc_e_send(p->pri->pri, p->call, &p->aoc_e);
05977             }
05978 #endif   /* defined(HAVE_PRI_AOC_EVENTS) */
05979             pri_hangup(p->pri->pri, p->call, icause);
05980          }
05981       }
05982       sig_pri_span_devstate_changed(p->pri);
05983       pri_rel(p->pri);
05984       res = 0;
05985    } else {
05986       ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->pri->span);
05987       res = -1;
05988    }
05989 
05990 #if defined(HAVE_PRI_AOC_EVENTS)
05991    p->aoc_s_request_invoke_id_valid = 0;
05992    p->holding_aoce = 0;
05993    p->waiting_for_aoce = 0;
05994 #endif   /* defined(HAVE_PRI_AOC_EVENTS) */
05995    ast->tech_pvt = NULL;
05996    return res;
05997 }

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

Definition at line 6527 of file sig_pri.c.

References ast_channel::_softhangup, ast_channel::_state, 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_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_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, sig_pri_chan::digital, ast_channel::hangupcause, ast_party_connected_line::id, LOG_DEBUG, LOG_WARNING, sig_pri_chan::mohinterpret, ast_channel::name, sig_pri_chan::no_b_channel, sig_pri_chan::outgoing, sig_pri_span::pri, sig_pri_chan::pri, pri_grab(), pri_rel(), sig_pri_chan::priindication_oob, sig_pri_chan::prioffset, sig_pri_chan::progress, PVT_TO_CHANNEL(), SIG_PRI_AOC_GRANT_D, SIG_PRI_AOC_GRANT_E, SIG_PRI_AOC_GRANT_S, SIG_PRI_CALL_LEVEL_ALERTING, 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_span::span.

Referenced by dahdi_indicate().

06528 {
06529    int res = -1;
06530 
06531    switch (condition) {
06532    case AST_CONTROL_BUSY:
06533       if (p->priindication_oob || p->no_b_channel) {
06534          chan->hangupcause = AST_CAUSE_USER_BUSY;
06535          chan->_softhangup |= AST_SOFTHANGUP_DEV;
06536          res = 0;
06537          break;
06538       }
06539       res = sig_pri_play_tone(p, SIG_PRI_TONE_BUSY);
06540       if (p->call_level < SIG_PRI_CALL_LEVEL_ALERTING && !p->outgoing) {
06541          chan->hangupcause = AST_CAUSE_USER_BUSY;
06542          p->progress = 1;/* No need to send plain PROGRESS after this. */
06543          if (p->pri && p->pri->pri) {
06544             if (!pri_grab(p, p->pri)) {
06545 #ifdef HAVE_PRI_PROG_W_CAUSE
06546                pri_progress_with_cause(p->pri->pri, p->call, PVT_TO_CHANNEL(p), 1, chan->hangupcause);
06547 #else
06548                pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
06549 #endif
06550                pri_rel(p->pri);
06551             } else {
06552                ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->pri->span);
06553             }
06554          }
06555       }
06556       break;
06557    case AST_CONTROL_RINGING:
06558       if (p->call_level < SIG_PRI_CALL_LEVEL_ALERTING && !p->outgoing) {
06559          p->call_level = SIG_PRI_CALL_LEVEL_ALERTING;
06560          if (p->pri && p->pri->pri) {
06561             if (!pri_grab(p, p->pri)) {
06562                pri_acknowledge(p->pri->pri,p->call, PVT_TO_CHANNEL(p),
06563                   p->no_b_channel || p->digital ? 0 : 1);
06564                pri_rel(p->pri);
06565             } else {
06566                ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->pri->span);
06567             }
06568          }
06569       }
06570       res = sig_pri_play_tone(p, SIG_PRI_TONE_RINGTONE);
06571       if (chan->_state != AST_STATE_UP) {
06572          if (chan->_state != AST_STATE_RING)
06573             ast_setstate(chan, AST_STATE_RINGING);
06574       }
06575       break;
06576    case AST_CONTROL_PROCEEDING:
06577       ast_debug(1,"Received AST_CONTROL_PROCEEDING on %s\n",chan->name);
06578       if (p->call_level < SIG_PRI_CALL_LEVEL_PROCEEDING && !p->outgoing) {
06579          p->call_level = SIG_PRI_CALL_LEVEL_PROCEEDING;
06580          if (p->pri && p->pri->pri) {
06581             if (!pri_grab(p, p->pri)) {
06582                pri_proceeding(p->pri->pri,p->call, PVT_TO_CHANNEL(p),
06583                   p->no_b_channel || p->digital ? 0 : 1);
06584                if (!p->no_b_channel && !p->digital) {
06585                   sig_pri_set_dialing(p, 0);
06586                }
06587                pri_rel(p->pri);
06588             } else {
06589                ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->pri->span);
06590             }
06591          }
06592       }
06593       /* don't continue in ast_indicate */
06594       res = 0;
06595       break;
06596    case AST_CONTROL_PROGRESS:
06597       ast_debug(1,"Received AST_CONTROL_PROGRESS on %s\n",chan->name);
06598       sig_pri_set_digital(p, 0); /* Digital-only calls isn't allowing any inband progress messages */
06599       if (!p->progress && p->call_level < SIG_PRI_CALL_LEVEL_ALERTING && !p->outgoing
06600          && !p->no_b_channel) {
06601          p->progress = 1;/* No need to send plain PROGRESS again. */
06602          if (p->pri && p->pri->pri) {
06603             if (!pri_grab(p, p->pri)) {
06604 #ifdef HAVE_PRI_PROG_W_CAUSE
06605                pri_progress_with_cause(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1, -1);  /* no cause at all */
06606 #else
06607                pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
06608 #endif
06609                pri_rel(p->pri);
06610             } else {
06611                ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->pri->span);
06612             }
06613          }
06614       }
06615       /* don't continue in ast_indicate */
06616       res = 0;
06617       break;
06618    case AST_CONTROL_CONGESTION:
06619       if (p->priindication_oob || p->no_b_channel) {
06620          /* There are many cause codes that generate an AST_CONTROL_CONGESTION. */
06621          switch (chan->hangupcause) {
06622          case AST_CAUSE_USER_BUSY:
06623          case AST_CAUSE_NORMAL_CLEARING:
06624          case 0:/* Cause has not been set. */
06625             /* Supply a more appropriate cause. */
06626             chan->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
06627             break;
06628          default:
06629             break;
06630          }
06631          chan->_softhangup |= AST_SOFTHANGUP_DEV;
06632          res = 0;
06633          break;
06634       }
06635       res = sig_pri_play_tone(p, SIG_PRI_TONE_CONGESTION);
06636       if (p->call_level < SIG_PRI_CALL_LEVEL_ALERTING && !p->outgoing) {
06637          /* There are many cause codes that generate an AST_CONTROL_CONGESTION. */
06638          switch (chan->hangupcause) {
06639          case AST_CAUSE_USER_BUSY:
06640          case AST_CAUSE_NORMAL_CLEARING:
06641          case 0:/* Cause has not been set. */
06642             /* Supply a more appropriate cause. */
06643             chan->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
06644             break;
06645          default:
06646             break;
06647          }
06648          p->progress = 1;/* No need to send plain PROGRESS after this. */
06649          if (p->pri && p->pri->pri) {
06650             if (!pri_grab(p, p->pri)) {
06651 #ifdef HAVE_PRI_PROG_W_CAUSE
06652                pri_progress_with_cause(p->pri->pri, p->call, PVT_TO_CHANNEL(p), 1, chan->hangupcause);
06653 #else
06654                pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
06655 #endif
06656                pri_rel(p->pri);
06657             } else {
06658                ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->pri->span);
06659             }
06660          }
06661       }
06662       break;
06663    case AST_CONTROL_HOLD:
06664       if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) {
06665          if (!pri_grab(p, p->pri)) {
06666             res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_HOLD);
06667             pri_rel(p->pri);
06668          } else {
06669             ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->pri->span);
06670          }
06671       } else
06672          ast_moh_start(chan, data, p->mohinterpret);
06673       break;
06674    case AST_CONTROL_UNHOLD:
06675       if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) {
06676          if (!pri_grab(p, p->pri)) {
06677             res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_RETRIEVAL);
06678             pri_rel(p->pri);
06679          }
06680       } else
06681          ast_moh_stop(chan);
06682       break;
06683    case AST_CONTROL_SRCUPDATE:
06684       res = 0;
06685       break;
06686    case -1:
06687       res = sig_pri_play_tone(p, -1);
06688       break;
06689    case AST_CONTROL_CONNECTED_LINE:
06690       ast_debug(1, "Received AST_CONTROL_CONNECTED_LINE on %s\n", chan->name);
06691       if (p->pri && !pri_grab(p, p->pri)) {
06692          struct pri_party_connected_line connected;
06693 
06694          memset(&connected, 0, sizeof(connected));
06695          sig_pri_party_id_from_ast(&connected.id, &chan->connected.id);
06696 
06697          pri_connected_line_update(p->pri->pri, p->call, &connected);
06698          pri_rel(p->pri);
06699       }
06700       break;
06701    case AST_CONTROL_REDIRECTING:
06702       ast_debug(1, "Received AST_CONTROL_REDIRECTING on %s\n", chan->name);
06703       if (p->pri && !pri_grab(p, p->pri)) {
06704          sig_pri_redirecting_update(p, chan);
06705          pri_rel(p->pri);
06706       }
06707       break;
06708    case AST_CONTROL_AOC:
06709 #if defined(HAVE_PRI_AOC_EVENTS)
06710       {
06711          struct ast_aoc_decoded *decoded
06712             = ast_aoc_decode((struct ast_aoc_encoded *) data, datalen, chan);
06713          ast_debug(1, "Received AST_CONTROL_AOC on %s\n", chan->name);
06714          if (decoded && p->pri && !pri_grab(p, p->pri)) {
06715             switch (ast_aoc_get_msg_type(decoded)) {
06716             case AST_AOC_S:
06717                if (p->pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_S) {
06718                   sig_pri_aoc_s_from_ast(p, decoded);
06719                }
06720                break;
06721             case AST_AOC_D:
06722                if (p->pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_D) {
06723                   sig_pri_aoc_d_from_ast(p, decoded);
06724                }
06725                break;
06726             case AST_AOC_E:
06727                if (p->pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_E) {
06728                   sig_pri_aoc_e_from_ast(p, decoded);
06729                }
06730                /* if hangup was delayed for this AOC-E msg, waiting_for_aoc
06731                 * will be set.  A hangup is already occuring via a timeout during
06732                 * this delay.  Instead of waiting for that timeout to occur, go ahead
06733                 * and initiate the softhangup since the delay is no longer necessary */
06734                if (p->waiting_for_aoce) {
06735                   p->waiting_for_aoce = 0;
06736                   ast_log(LOG_DEBUG,
06737                      "Received final AOC-E msg, continue with hangup on %s\n",
06738                      chan->name);
06739                   ast_softhangup_nolock(chan, AST_SOFTHANGUP_DEV);
06740                }
06741                break;
06742             case AST_AOC_REQUEST:
06743                /* We do not pass through AOC requests, So unless this
06744                 * is an AOC termination request it will be ignored */
06745                if (ast_aoc_get_termination_request(decoded)) {
06746                   pri_hangup(p->pri->pri, p->call, -1);
06747                }
06748                break;
06749             default:
06750                break;
06751             }
06752             pri_rel(p->pri);
06753          }
06754          ast_aoc_destroy_decoded(decoded);
06755       }
06756 #endif   /* defined(HAVE_PRI_AOC_EVENTS) */
06757       break;
06758    }
06759 
06760    return res;
06761 }

void sig_pri_init_pri ( struct sig_pri_span pri  ) 

Definition at line 5899 of file sig_pri.c.

References ast_mutex_init, AST_PTHREADT_NULL, and SIG_PRI_NUM_DCHANS.

Referenced by load_module().

05900 {
05901    int i;
05902 
05903    memset(pri, 0, sizeof(*pri));
05904 
05905    ast_mutex_init(&pri->lock);
05906 
05907    pri->master = AST_PTHREADT_NULL;
05908    for (i = 0; i < SIG_PRI_NUM_DCHANS; i++)
05909       pri->fds[i] = -1;
05910 }

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

References ao2_container_alloc.

Referenced by load_module().

08085 {
08086 #if defined(HAVE_PRI_CCSS)
08087    sig_pri_cc_type_name = cc_type_name;
08088    sig_pri_cc_monitors = ao2_container_alloc(37, sig_pri_cc_monitor_instance_hash_fn,
08089       sig_pri_cc_monitor_instance_cmp_fn);
08090    if (!sig_pri_cc_monitors) {
08091       return -1;
08092    }
08093 #endif   /* defined(HAVE_PRI_CCSS) */
08094    return 0;
08095 }

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

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

int sig_pri_start_pri ( struct sig_pri_span pri  ) 

Definition at line 7118 of file sig_pri.c.

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

Referenced by setup_dahdi_int().

07119 {
07120    int x;
07121    int i;
07122 #if defined(HAVE_PRI_MWI)
07123    char *saveptr;
07124    char *mbox_number;
07125    char *mbox_context;
07126    struct ast_str *mwi_description = ast_str_alloca(64);
07127 #endif   /* defined(HAVE_PRI_MWI) */
07128 
07129 #if defined(HAVE_PRI_MWI)
07130    /* Prepare the mbox[] for use. */
07131    for (i = 0; i < ARRAY_LEN(pri->mbox); ++i) {
07132       if (pri->mbox[i].sub) {
07133          pri->mbox[i].sub = ast_event_unsubscribe(pri->mbox[i].sub);
07134       }
07135    }
07136 #endif   /* defined(HAVE_PRI_MWI) */
07137 
07138    ast_mutex_init(&pri->lock);
07139    sig_pri_sort_pri_chans(pri);
07140 
07141 #if defined(HAVE_PRI_MWI)
07142    /*
07143     * Split the mwi_mailboxes configuration string into the mbox[]:
07144     * mailbox_number[@context]{,mailbox_number[@context]}
07145     */
07146    i = 0;
07147    saveptr = pri->mwi_mailboxes;
07148    while (i < ARRAY_LEN(pri->mbox)) {
07149       mbox_number = strsep(&saveptr, ",");
07150       if (!mbox_number) {
07151          break;
07152       }
07153       /* Split the mailbox_number and context */
07154       mbox_context = strchr(mbox_number, '@');
07155       if (mbox_context) {
07156          *mbox_context++ = '\0';
07157          mbox_context = ast_strip(mbox_context);
07158       }
07159       mbox_number = ast_strip(mbox_number);
07160       if (ast_strlen_zero(mbox_number)) {
07161          /* There is no mailbox number.  Skip it. */
07162          continue;
07163       }
07164       if (ast_strlen_zero(mbox_context)) {
07165          /* There was no context so use the default. */
07166          mbox_context = "default";
07167       }
07168 
07169       /* Fill the mbox[] element. */
07170       ast_str_set(&mwi_description, -1, "%s span %d[%d] MWI mailbox %s@%s",
07171          sig_pri_cc_type_name, pri->span, i, mbox_number, mbox_context);
07172       pri->mbox[i].sub = ast_event_subscribe(AST_EVENT_MWI, sig_pri_mwi_event_cb,
07173          ast_str_buffer(mwi_description), pri,
07174          AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mbox_number,
07175          AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, mbox_context,
07176          AST_EVENT_IE_END);
07177       if (!pri->mbox[i].sub) {
07178          ast_log(LOG_ERROR, "%s span %d could not subscribe to MWI events for %s@%s.",
07179             sig_pri_cc_type_name, pri->span, mbox_number, mbox_context);
07180          continue;
07181       }
07182       pri->mbox[i].number = mbox_number;
07183       pri->mbox[i].context = mbox_context;
07184       ++i;
07185    }
07186 #endif   /* defined(HAVE_PRI_MWI) */
07187 
07188    for (i = 0; i < SIG_PRI_NUM_DCHANS; i++) {
07189       if (pri->fds[i] == -1) {
07190          break;
07191       }
07192 
07193       switch (pri->sig) {
07194       case SIG_BRI:
07195          pri->dchans[i] = pri_new_bri(pri->fds[i], 1, pri->nodetype, pri->switchtype);
07196          break;
07197       case SIG_BRI_PTMP:
07198          pri->dchans[i] = pri_new_bri(pri->fds[i], 0, pri->nodetype, pri->switchtype);
07199          break;
07200       default:
07201          pri->dchans[i] = pri_new(pri->fds[i], pri->nodetype, pri->switchtype);
07202 #if defined(HAVE_PRI_SERVICE_MESSAGES)
07203          if (pri->enable_service_message_support) {
07204             pri_set_service_message_support(pri->dchans[i], 1);
07205          }
07206 #endif   /* defined(HAVE_PRI_SERVICE_MESSAGES) */
07207          break;
07208       }
07209 
07210       pri_set_overlapdial(pri->dchans[i], (pri->overlapdial & DAHDI_OVERLAPDIAL_OUTGOING) ? 1 : 0);
07211 #ifdef HAVE_PRI_PROG_W_CAUSE
07212       pri_set_chan_mapping_logical(pri->dchans[i], pri->qsigchannelmapping == DAHDI_CHAN_MAPPING_LOGICAL);
07213 #endif
07214 #ifdef HAVE_PRI_INBANDDISCONNECT
07215       pri_set_inbanddisconnect(pri->dchans[i], pri->inbanddisconnect);
07216 #endif
07217       /* Enslave to master if appropriate */
07218       if (i)
07219          pri_enslave(pri->dchans[0], pri->dchans[i]);
07220       if (!pri->dchans[i]) {
07221          if (pri->fds[i] > 0)
07222             close(pri->fds[i]);
07223          pri->fds[i] = -1;
07224          ast_log(LOG_ERROR, "Unable to create PRI structure\n");
07225          return -1;
07226       }
07227       pri_set_debug(pri->dchans[i], SIG_PRI_DEBUG_DEFAULT);
07228       pri_set_nsf(pri->dchans[i], pri->nsf);
07229 #ifdef PRI_GETSET_TIMERS
07230       for (x = 0; x < PRI_MAX_TIMERS; x++) {
07231          if (pri->pritimers[x] != 0)
07232             pri_set_timer(pri->dchans[i], x, pri->pritimers[x]);
07233       }
07234 #endif
07235    }
07236 
07237    /* Assume primary is the one we use */
07238    pri->pri = pri->dchans[0];
07239 
07240 #if defined(HAVE_PRI_CALL_HOLD)
07241    pri_hold_enable(pri->pri, 1);
07242 #endif   /* defined(HAVE_PRI_CALL_HOLD) */
07243 #if defined(HAVE_PRI_CALL_REROUTING)
07244    pri_reroute_enable(pri->pri, 1);
07245 #endif   /* defined(HAVE_PRI_CALL_REROUTING) */
07246 #if defined(HAVE_PRI_HANGUP_FIX)
07247    pri_hangup_fix_enable(pri->pri, 1);
07248 #endif   /* defined(HAVE_PRI_HANGUP_FIX) */
07249 #if defined(HAVE_PRI_CCSS)
07250    pri_cc_enable(pri->pri, 1);
07251    pri_cc_recall_mode(pri->pri, pri->cc_ptmp_recall_mode);
07252    pri_cc_retain_signaling_req(pri->pri, pri->cc_qsig_signaling_link_req);
07253    pri_cc_retain_signaling_rsp(pri->pri, pri->cc_qsig_signaling_link_rsp);
07254 #endif   /* defined(HAVE_PRI_CCSS) */
07255 #if defined(HAVE_PRI_TRANSFER)
07256    pri_transfer_enable(pri->pri, 1);
07257 #endif   /* defined(HAVE_PRI_TRANSFER) */
07258 #if defined(HAVE_PRI_AOC_EVENTS)
07259    pri_aoc_events_enable(pri->pri, 1);
07260 #endif   /* defined(HAVE_PRI_AOC_EVENTS) */
07261 #if defined(HAVE_PRI_CALL_WAITING)
07262    pri_connect_ack_enable(pri->pri, 1);
07263 #endif   /* defined(HAVE_PRI_CALL_WAITING) */
07264 #if defined(HAVE_PRI_MCID)
07265    pri_mcid_enable(pri->pri, 1);
07266 #endif   /* defined(HAVE_PRI_MCID) */
07267 
07268    pri->resetpos = -1;
07269    if (ast_pthread_create_background(&pri->master, NULL, pri_dchannel, pri)) {
07270       for (i = 0; i < SIG_PRI_NUM_DCHANS; i++) {
07271          if (!pri->dchans[i])
07272             break;
07273          if (pri->fds[i] > 0)
07274             close(pri->fds[i]);
07275          pri->fds[i] = -1;
07276       }
07277       ast_log(LOG_ERROR, "Unable to spawn D-channel: %s\n", strerror(errno));
07278       return -1;
07279    }
07280 
07281 #if defined(HAVE_PRI_MWI)
07282    /*
07283     * Send the initial MWI indications from the event cache for this span.
07284     *
07285     * If we were loaded after app_voicemail the event would already be in
07286     * the cache.  If we were loaded before app_voicemail the event would not
07287     * be in the cache yet and app_voicemail will send the event when it
07288     * gets loaded.
07289     */
07290    sig_pri_mwi_cache_update(pri);
07291 #endif   /* defined(HAVE_PRI_MWI) */
07292 
07293    return 0;
07294 }

void sig_pri_stop_pri ( struct sig_pri_span pri  ) 

Stop PRI span.

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

Definition at line 7053 of file sig_pri.c.

References ARRAY_LEN, and ast_event_unsubscribe().

Referenced by __unload_module().

07054 {
07055 #if defined(HAVE_PRI_MWI)
07056    int idx;
07057 #endif   /* defined(HAVE_PRI_MWI) */
07058 
07059 #if defined(HAVE_PRI_MWI)
07060    for (idx = 0; idx < ARRAY_LEN(pri->mbox); ++idx) {
07061       if (pri->mbox[idx].sub) {
07062          pri->mbox[idx].sub = ast_event_unsubscribe(pri->mbox[idx].sub);
07063       }
07064    }
07065 #endif   /* defined(HAVE_PRI_MWI) */
07066 }

void sig_pri_unload ( void   ) 

Unload the sig_pri submodule.

Since:
1.8
Returns:
Nothing

Definition at line 8103 of file sig_pri.c.

References ao2_ref.

Referenced by __unload_module().

08104 {
08105 #if defined(HAVE_PRI_CCSS)
08106    if (sig_pri_cc_monitors) {
08107       ao2_ref(sig_pri_cc_monitors, -1);
08108       sig_pri_cc_monitors = NULL;
08109    }
08110 #endif   /* defined(HAVE_PRI_CCSS) */
08111 }


Variable Documentation

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

The AstDB family.

Definition at line 184 of file sig_pri.h.

Referenced by destroy_all_channels().


Generated on Mon Jun 27 16:51:21 2011 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7