#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_chan * | sig_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_channel * | sig_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. |
Definition in file sig_pri.h.
#define DAHDI_CHAN_MAPPING_PHYSICAL 0 |
#define DAHDI_OVERLAPDIAL_BOTH (DAHDI_OVERLAPDIAL_INCOMING|DAHDI_OVERLAPDIAL_OUTGOING) |
#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_OUTGOING 1 |
#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 |
#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)
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)
Definition at line 37 of file sig_pri.h.
Referenced by handle_pri_debug().
#define SIG_PRI_MAX_CHANNELS 672 |
#define SIG_PRI_MAX_MWI_CONTEXT_LEN 10 |
#define SIG_PRI_MAX_MWI_MAILBOX_STR |
Value:
(SIG_PRI_MAX_MWI_MAILBOXES \ * (SIG_PRI_MAX_MWI_MBOX_NUMBER_LEN + 1 + SIG_PRI_MAX_MWI_CONTEXT_LEN + 1))
max_length = mailboxes * (mbox_number + '@' + context + ',') The last ',' is a null terminator instead.
#define SIG_PRI_MAX_MWI_MAILBOXES 8 |
#define SIG_PRI_MAX_MWI_MBOX_NUMBER_LEN 10 |
#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) |
#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.
#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" |
enum sig_pri_call_level |
Call establishment life cycle level for simple comparisons.
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 |
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 |
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.
00070 { 00071 SIG_PRI_TONE_RINGTONE = 0, 00072 SIG_PRI_TONE_STUTTER, 00073 SIG_PRI_TONE_CONGESTION, 00074 SIG_PRI_TONE_DIALTONE, 00075 SIG_PRI_TONE_DIALRECALL, 00076 SIG_PRI_TONE_INFO, 00077 SIG_PRI_TONE_BUSY, 00078 };
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 | |||
) |
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.
agent | CC core agent control. |
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.
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.
agent | CC core agent control. |
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.
agent | CC core agent control. | |
pvt_chan | Original channel the agent will attempt to recall. |
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.
agent | CC core agent control. |
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.
agent | CC core agent control. | |
reason | CC request response status. |
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.
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.
agent | CC core agent control. |
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.
agent | CC core agent control. |
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.
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.
agent | CC core agent control. |
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.
agent | CC core agent control. |
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.
agent | CC core agent control. |
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.
monitor | CC core monitor control. | |
sched_id | Available timer scheduler id to cancel. Will never be NULL for a device monitor. |
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.
monitor_pvt | CC device monitor private data pointer. |
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.
monitor | CC core monitor control. | |
available_timer_id | Where to put the available timer scheduler id. Will never be NULL for a device monitor. |
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().
monitor | CC core monitor control. | |
devstate | Current status of a Party A device. |
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.
monitor | CC core monitor control. |
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.
monitor | CC core monitor control. |
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.
p | Channel private pointer. | |
noalarm | Non-zero if not in alarm mode. |
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.
doomed | sig_pri private channel structure to delete. |
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.
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. |
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 | |||
) |
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.
pvt | Channel to determine if 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.
cc_type_name | CC type name to use when looking up agent/monitor. |
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.
pri | PRI span control structure. |
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.
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 }
const char dahdi_db[] = "dahdi/registry" [static] |