#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_DEFER_DIAL, SIG_PRI_CALL_LEVEL_CONNECT } |
enum | sig_pri_law { SIG_PRI_DEFLAW = 0, SIG_PRI_ULAW, SIG_PRI_ALAW } |
enum | sig_pri_reset_state { SIG_PRI_RESET_IDLE, SIG_PRI_RESET_ACTIVE, SIG_PRI_RESET_NO_ACK } |
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) |
void | sig_pri_dial_complete (struct sig_pri_chan *pvt, struct ast_channel *ast) |
DTMF dial string complete. | |
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_alarm_ignored (struct sig_pri_span *pri) |
Determine if layer 1 alarms are ignored. | |
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 197 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 183 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 202 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 214 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 212 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 dialing 'w' deferred digits. (CONNECT) */ 00099 SIG_PRI_CALL_LEVEL_DEFER_DIAL, 00100 /*! Call is connected/answered. (CONNECT) */ 00101 SIG_PRI_CALL_LEVEL_CONNECT, 00102 };
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_reset_state |
Definition at line 104 of file sig_pri.h.
00104 { 00105 /*! \brief The channel is not being RESTARTed. */ 00106 SIG_PRI_RESET_IDLE, 00107 /*! 00108 * \brief The channel is being RESTARTed. 00109 * \note Waiting for a RESTART ACKNOWLEDGE from the peer. 00110 */ 00111 SIG_PRI_RESET_ACTIVE, 00112 /*! 00113 * \brief Peer may not be sending the expected RESTART ACKNOWLEDGE. 00114 * 00115 * \details We have already received a SETUP on this channel. 00116 * If another SETUP comes in on this channel then the peer 00117 * considers this channel useable. Assume that the peer is 00118 * never going to give us a RESTART ACKNOWLEDGE and assume that 00119 * we have received one. This is not according to Q.931, but 00120 * some peers occasionally fail to send a RESTART ACKNOWLEDGE. 00121 */ 00122 SIG_PRI_RESET_NO_ACK, 00123 };
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 2001 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().
02002 { 02003 pri->dchanavail[index] &= ~(DCHAN_NOTINALARM | DCHAN_UP); 02004 if (!before_start_pri) { 02005 pri_find_dchan(pri); 02006 } 02007 }
void pri_event_noalarm | ( | struct sig_pri_span * | pri, | |
int | index, | |||
int | before_start_pri | |||
) |
Definition at line 2009 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().
02010 { 02011 pri->dchanavail[index] |= DCHAN_NOTINALARM; 02012 if (!before_start_pri) 02013 pri_restart(pri->dchans[index]); 02014 }
int pri_is_up | ( | struct sig_pri_span * | pri | ) |
Definition at line 1026 of file sig_pri.c.
References DCHAN_AVAILABLE, sig_pri_span::dchanavail, and SIG_PRI_NUM_DCHANS.
Referenced by pri_dchannel().
01027 { 01028 int x; 01029 for (x = 0; x < SIG_PRI_NUM_DCHANS; x++) { 01030 if (pri->dchanavail[x] == DCHAN_AVAILABLE) 01031 return 1; 01032 } 01033 return 0; 01034 }
int pri_maintenance_bservice | ( | struct pri * | pri, | |
struct sig_pri_chan * | p, | |||
int | changestatus | |||
) |
Definition at line 8031 of file sig_pri.c.
References sig_pri_chan::channel, PRI_SPAN, and PVT_TO_CHANNEL().
08032 { 08033 int channel = PVT_TO_CHANNEL(p); 08034 int span = PRI_SPAN(channel); 08035 08036 return pri_maintenance_service(pri, span, channel, changestatus); 08037 }
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 8009 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().
08010 { 08011 int res; 08012 08013 sig_pri_lock_private(p); 08014 08015 if (!p->pri || !p->call) { 08016 ast_log(LOG_DEBUG, "Unable to find pri or call on channel!\n"); 08017 sig_pri_unlock_private(p); 08018 return -1; 08019 } 08020 08021 pri_grab(p, p->pri); 08022 res = pri_callrerouting_facility(p->pri->pri, p->call, destination, original, reason); 08023 pri_rel(p->pri); 08024 08025 sig_pri_unlock_private(p); 08026 08027 return res; 08028 }
int pri_send_keypad_facility_exec | ( | struct sig_pri_chan * | p, | |
const char * | digits | |||
) |
Definition at line 7990 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().
07991 { 07992 sig_pri_lock_private(p); 07993 07994 if (!p->pri || !p->call) { 07995 ast_debug(1, "Unable to find pri or call on channel!\n"); 07996 sig_pri_unlock_private(p); 07997 return -1; 07998 } 07999 08000 pri_grab(p, p->pri); 08001 pri_keypad_facility(p->pri->pri, p->call, digits); 08002 pri_rel(p->pri); 08003 08004 sig_pri_unlock_private(p); 08005 08006 return 0; 08007 }
int sig_pri_answer | ( | struct sig_pri_chan * | p, | |
struct ast_channel * | ast | |||
) |
Definition at line 7239 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().
07240 { 07241 int res; 07242 07243 /* Send a pri acknowledge */ 07244 pri_grab(p, p->pri); 07245 #if defined(HAVE_PRI_AOC_EVENTS) 07246 if (p->aoc_s_request_invoke_id_valid) { 07247 /* if AOC-S was requested and the invoke id is still present on answer. That means 07248 * no AOC-S rate list was provided, so send a NULL response which will indicate that 07249 * AOC-S is not available */ 07250 pri_aoc_s_request_response_send(p->pri->pri, p->call, 07251 p->aoc_s_request_invoke_id, NULL); 07252 p->aoc_s_request_invoke_id_valid = 0; 07253 } 07254 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 07255 if (p->call_level < SIG_PRI_CALL_LEVEL_CONNECT) { 07256 p->call_level = SIG_PRI_CALL_LEVEL_CONNECT; 07257 } 07258 sig_pri_set_dialing(p, 0); 07259 sig_pri_open_media(p); 07260 res = pri_answer(p->pri->pri, p->call, 0, !p->digital); 07261 pri_rel(p->pri); 07262 ast_setstate(ast, AST_STATE_UP); 07263 return res; 07264 }
int sig_pri_available | ( | struct sig_pri_chan ** | pvt, | |
int | is_specific_channel | |||
) |
Definition at line 7334 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().
07335 { 07336 struct sig_pri_chan *p = *pvt; 07337 struct sig_pri_span *pri; 07338 07339 if (!p->pri) { 07340 /* Something is wrong here. A PRI channel without the pri pointer? */ 07341 return 0; 07342 } 07343 pri = p->pri; 07344 07345 ast_mutex_lock(&pri->lock); 07346 if ( 07347 #if defined(HAVE_PRI_CALL_WAITING) 07348 /* 07349 * Only do call waiting calls if we have any 07350 * call waiting call outstanding. We do not 07351 * want new calls to steal a B channel 07352 * freed for an earlier call waiting call. 07353 */ 07354 !pri->num_call_waiting_calls && 07355 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 07356 sig_pri_available_check(p)) { 07357 p->allocated = 1; 07358 ast_mutex_unlock(&pri->lock); 07359 return 1; 07360 } 07361 07362 #if defined(HAVE_PRI_CALL_WAITING) 07363 if (!is_specific_channel) { 07364 struct sig_pri_chan *cw; 07365 07366 cw = sig_pri_cw_available(pri); 07367 if (cw) { 07368 /* We have a call waiting interface to use instead. */ 07369 cw->allocated = 1; 07370 *pvt = cw; 07371 ast_mutex_unlock(&pri->lock); 07372 return 1; 07373 } 07374 } 07375 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 07376 ast_mutex_unlock(&pri->lock); 07377 return 0; 07378 }
int sig_pri_call | ( | struct sig_pri_chan * | p, | |
struct ast_channel * | ast, | |||
char * | rdest, | |||
int | timeout, | |||
int | layer1 | |||
) |
Definition at line 6564 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::deferred_digits, 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::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(), sig_pri_set_outgoing(), 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().
06565 { 06566 char dest[256]; /* must be same length as p->dialdest */ 06567 struct ast_party_subaddress dialed_subaddress; /* Called subaddress */ 06568 struct pri_sr *sr; 06569 char *c, *l, *n, *s; 06570 #ifdef SUPPORT_USERUSER 06571 const char *useruser; 06572 #endif 06573 int core_id; 06574 int pridialplan; 06575 int dp_strip; 06576 int prilocaldialplan; 06577 int ldp_strip; 06578 int exclusive; 06579 #if defined(HAVE_PRI_SETUP_KEYPAD) 06580 const char *keypad; 06581 #endif /* defined(HAVE_PRI_SETUP_KEYPAD) */ 06582 AST_DECLARE_APP_ARGS(args, 06583 AST_APP_ARG(group); /* channel/group token */ 06584 AST_APP_ARG(ext); /* extension token */ 06585 AST_APP_ARG(opts); /* options token */ 06586 AST_APP_ARG(other); /* Any remining unused arguments */ 06587 ); 06588 struct ast_flags opts; 06589 char *opt_args[OPT_ARG_ARRAY_SIZE]; 06590 06591 ast_log(LOG_DEBUG, "CALLER NAME: %s NUM: %s\n", 06592 S_COR(ast->connected.id.name.valid, ast->connected.id.name.str, ""), 06593 S_COR(ast->connected.id.number.valid, ast->connected.id.number.str, "")); 06594 06595 if (!p->pri) { 06596 ast_log(LOG_ERROR, "Could not find pri on channel %d\n", p->channel); 06597 return -1; 06598 } 06599 06600 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { 06601 ast_log(LOG_WARNING, "sig_pri_call called on %s, neither down nor reserved\n", ast->name); 06602 return -1; 06603 } 06604 06605 p->dialdest[0] = '\0'; 06606 sig_pri_set_outgoing(p, 1); 06607 06608 ast_copy_string(dest, rdest, sizeof(dest)); 06609 AST_NONSTANDARD_APP_ARGS(args, dest, '/'); 06610 if (ast_app_parse_options(sig_pri_call_opts, &opts, opt_args, args.opts)) { 06611 /* General invalid option syntax. */ 06612 return -1; 06613 } 06614 06615 c = args.ext; 06616 if (!c) { 06617 c = ""; 06618 } 06619 06620 /* setup dialed_subaddress if found */ 06621 ast_party_subaddress_init(&dialed_subaddress); 06622 s = strchr(c, ':'); 06623 if (s) { 06624 *s = '\0'; 06625 s++; 06626 /* prefix */ 06627 /* 'n' = NSAP */ 06628 /* 'u' = User Specified */ 06629 /* Default = NSAP */ 06630 switch (*s) { 06631 case 'U': 06632 case 'u': 06633 s++; 06634 dialed_subaddress.type = 2; 06635 break; 06636 case 'N': 06637 case 'n': 06638 s++; 06639 /* default already covered with ast_party_subaddress_init */ 06640 break; 06641 } 06642 dialed_subaddress.str = s; 06643 dialed_subaddress.valid = 1; 06644 } 06645 06646 l = NULL; 06647 n = NULL; 06648 if (!p->hidecallerid) { 06649 if (ast->connected.id.number.valid) { 06650 /* If we get to the end of this loop without breaking, there's no 06651 * calleridnum. This is done instead of testing for "unknown" or 06652 * the thousands of other ways that the calleridnum could be 06653 * invalid. */ 06654 for (l = ast->connected.id.number.str; l && *l; l++) { 06655 if (strchr("0123456789", *l)) { 06656 l = ast->connected.id.number.str; 06657 break; 06658 } 06659 } 06660 } else { 06661 l = NULL; 06662 } 06663 if (!p->hidecalleridname) { 06664 n = ast->connected.id.name.valid ? ast->connected.id.name.str : NULL; 06665 } 06666 } 06667 06668 if (strlen(c) < p->stripmsd) { 06669 ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd); 06670 return -1; 06671 } 06672 06673 /* Extract any 'w' deferred digits. */ 06674 s = strchr(c + p->stripmsd, 'w'); 06675 if (s) { 06676 *s++ = '\0'; 06677 ast_copy_string(p->deferred_digits, s, sizeof(p->deferred_digits)); 06678 /* 06679 * Since we have a 'w', this means that there will not be any 06680 * more normal dialed digits. Therefore, the sending complete 06681 * ie needs to be sent with any normal digits. 06682 */ 06683 } else { 06684 p->deferred_digits[0] = '\0'; 06685 } 06686 06687 pri_grab(p, p->pri); 06688 if (!(p->call = pri_new_call(p->pri->pri))) { 06689 ast_log(LOG_WARNING, "Unable to create call on channel %d\n", p->channel); 06690 pri_rel(p->pri); 06691 return -1; 06692 } 06693 if (!(sr = pri_sr_new())) { 06694 ast_log(LOG_WARNING, "Failed to allocate setup request on channel %d\n", 06695 p->channel); 06696 pri_destroycall(p->pri->pri, p->call); 06697 p->call = NULL; 06698 pri_rel(p->pri); 06699 return -1; 06700 } 06701 06702 sig_pri_set_digital(p, IS_DIGITAL(ast->transfercapability)); /* push up to parent for EC */ 06703 06704 #if defined(HAVE_PRI_CALL_WAITING) 06705 if (p->is_call_waiting) { 06706 /* 06707 * Indicate that this is a call waiting call. 06708 * i.e., Normal call but with no B channel. 06709 */ 06710 pri_sr_set_channel(sr, 0, 0, 1); 06711 } else 06712 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 06713 { 06714 /* Should the picked channel be used exclusively? */ 06715 if (p->priexclusive || p->pri->nodetype == PRI_NETWORK) { 06716 exclusive = 1; 06717 } else { 06718 exclusive = 0; 06719 } 06720 pri_sr_set_channel(sr, PVT_TO_CHANNEL(p), exclusive, 1); 06721 } 06722 06723 pri_sr_set_bearer(sr, p->digital ? PRI_TRANS_CAP_DIGITAL : ast->transfercapability, 06724 (p->digital ? -1 : layer1)); 06725 06726 if (p->pri->facilityenable) 06727 pri_facility_enable(p->pri->pri); 06728 06729 ast_verb(3, "Requested transfer capability: 0x%.2x - %s\n", ast->transfercapability, ast_transfercapability2str(ast->transfercapability)); 06730 dp_strip = 0; 06731 pridialplan = p->pri->dialplan - 1; 06732 if (pridialplan == -2 || pridialplan == -3) { /* compute dynamically */ 06733 if (strncmp(c + p->stripmsd, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) { 06734 if (pridialplan == -2) { 06735 dp_strip = strlen(p->pri->internationalprefix); 06736 } 06737 pridialplan = PRI_INTERNATIONAL_ISDN; 06738 } else if (strncmp(c + p->stripmsd, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) { 06739 if (pridialplan == -2) { 06740 dp_strip = strlen(p->pri->nationalprefix); 06741 } 06742 pridialplan = PRI_NATIONAL_ISDN; 06743 } else { 06744 pridialplan = PRI_LOCAL_ISDN; 06745 } 06746 } 06747 while (c[p->stripmsd] > '9' && c[p->stripmsd] != '*' && c[p->stripmsd] != '#') { 06748 switch (c[p->stripmsd]) { 06749 case 'U': 06750 pridialplan = (PRI_TON_UNKNOWN << 4) | (pridialplan & 0xf); 06751 break; 06752 case 'I': 06753 pridialplan = (PRI_TON_INTERNATIONAL << 4) | (pridialplan & 0xf); 06754 break; 06755 case 'N': 06756 pridialplan = (PRI_TON_NATIONAL << 4) | (pridialplan & 0xf); 06757 break; 06758 case 'L': 06759 pridialplan = (PRI_TON_NET_SPECIFIC << 4) | (pridialplan & 0xf); 06760 break; 06761 case 'S': 06762 pridialplan = (PRI_TON_SUBSCRIBER << 4) | (pridialplan & 0xf); 06763 break; 06764 case 'V': 06765 pridialplan = (PRI_TON_ABBREVIATED << 4) | (pridialplan & 0xf); 06766 break; 06767 case 'R': 06768 pridialplan = (PRI_TON_RESERVED << 4) | (pridialplan & 0xf); 06769 break; 06770 case 'u': 06771 pridialplan = PRI_NPI_UNKNOWN | (pridialplan & 0xf0); 06772 break; 06773 case 'e': 06774 pridialplan = PRI_NPI_E163_E164 | (pridialplan & 0xf0); 06775 break; 06776 case 'x': 06777 pridialplan = PRI_NPI_X121 | (pridialplan & 0xf0); 06778 break; 06779 case 'f': 06780 pridialplan = PRI_NPI_F69 | (pridialplan & 0xf0); 06781 break; 06782 case 'n': 06783 pridialplan = PRI_NPI_NATIONAL | (pridialplan & 0xf0); 06784 break; 06785 case 'p': 06786 pridialplan = PRI_NPI_PRIVATE | (pridialplan & 0xf0); 06787 break; 06788 case 'r': 06789 pridialplan = PRI_NPI_RESERVED | (pridialplan & 0xf0); 06790 break; 06791 default: 06792 if (isalpha(c[p->stripmsd])) { 06793 ast_log(LOG_WARNING, "Unrecognized pridialplan %s modifier: %c\n", 06794 c[p->stripmsd] > 'Z' ? "NPI" : "TON", c[p->stripmsd]); 06795 } 06796 break; 06797 } 06798 c++; 06799 } 06800 #if defined(HAVE_PRI_SETUP_KEYPAD) 06801 if (ast_test_flag(&opts, OPT_KEYPAD) 06802 && !ast_strlen_zero(opt_args[OPT_ARG_KEYPAD])) { 06803 /* We have a keypad facility digits option with digits. */ 06804 keypad = opt_args[OPT_ARG_KEYPAD]; 06805 pri_sr_set_keypad_digits(sr, keypad); 06806 } else { 06807 keypad = NULL; 06808 } 06809 if (!keypad || !ast_strlen_zero(c + p->stripmsd + dp_strip)) 06810 #endif /* defined(HAVE_PRI_SETUP_KEYPAD) */ 06811 { 06812 pri_sr_set_called(sr, c + p->stripmsd + dp_strip, pridialplan, s ? 1 : 0); 06813 } 06814 06815 #if defined(HAVE_PRI_SUBADDR) 06816 if (dialed_subaddress.valid) { 06817 struct pri_party_subaddress subaddress; 06818 06819 memset(&subaddress, 0, sizeof(subaddress)); 06820 sig_pri_party_subaddress_from_ast(&subaddress, &dialed_subaddress); 06821 pri_sr_set_called_subaddress(sr, &subaddress); 06822 } 06823 #endif /* defined(HAVE_PRI_SUBADDR) */ 06824 #if defined(HAVE_PRI_REVERSE_CHARGE) 06825 if (ast_test_flag(&opts, OPT_REVERSE_CHARGE)) { 06826 pri_sr_set_reversecharge(sr, PRI_REVERSECHARGE_REQUESTED); 06827 } 06828 #endif /* defined(HAVE_PRI_REVERSE_CHARGE) */ 06829 #if defined(HAVE_PRI_AOC_EVENTS) 06830 if (ast_test_flag(&opts, OPT_AOC_REQUEST) 06831 && !ast_strlen_zero(opt_args[OPT_ARG_AOC_REQUEST])) { 06832 if (strchr(opt_args[OPT_ARG_AOC_REQUEST], 's')) { 06833 pri_sr_set_aoc_charging_request(sr, PRI_AOC_REQUEST_S); 06834 } 06835 if (strchr(opt_args[OPT_ARG_AOC_REQUEST], 'd')) { 06836 pri_sr_set_aoc_charging_request(sr, PRI_AOC_REQUEST_D); 06837 } 06838 if (strchr(opt_args[OPT_ARG_AOC_REQUEST], 'e')) { 06839 pri_sr_set_aoc_charging_request(sr, PRI_AOC_REQUEST_E); 06840 } 06841 } 06842 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 06843 06844 /* Setup the user tag for party id's from this device for this call. */ 06845 if (p->pri->append_msn_to_user_tag) { 06846 snprintf(p->user_tag, sizeof(p->user_tag), "%s_%s", p->pri->initial_user_tag, 06847 p->pri->nodetype == PRI_NETWORK 06848 ? c + p->stripmsd + dp_strip 06849 : S_COR(ast->connected.id.number.valid, 06850 ast->connected.id.number.str, "")); 06851 } else { 06852 ast_copy_string(p->user_tag, p->pri->initial_user_tag, sizeof(p->user_tag)); 06853 } 06854 06855 /* 06856 * Replace the caller id tag from the channel creation 06857 * with the actual tag value. 06858 */ 06859 ast_free(ast->caller.id.tag); 06860 ast->caller.id.tag = ast_strdup(p->user_tag); 06861 06862 ldp_strip = 0; 06863 prilocaldialplan = p->pri->localdialplan - 1; 06864 if ((l != NULL) && (prilocaldialplan == -2 || prilocaldialplan == -3)) { /* compute dynamically */ 06865 if (strncmp(l, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) { 06866 if (prilocaldialplan == -2) { 06867 ldp_strip = strlen(p->pri->internationalprefix); 06868 } 06869 prilocaldialplan = PRI_INTERNATIONAL_ISDN; 06870 } else if (strncmp(l, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) { 06871 if (prilocaldialplan == -2) { 06872 ldp_strip = strlen(p->pri->nationalprefix); 06873 } 06874 prilocaldialplan = PRI_NATIONAL_ISDN; 06875 } else { 06876 prilocaldialplan = PRI_LOCAL_ISDN; 06877 } 06878 } 06879 if (l != NULL) { 06880 while (*l > '9' && *l != '*' && *l != '#') { 06881 switch (*l) { 06882 case 'U': 06883 prilocaldialplan = (PRI_TON_UNKNOWN << 4) | (prilocaldialplan & 0xf); 06884 break; 06885 case 'I': 06886 prilocaldialplan = (PRI_TON_INTERNATIONAL << 4) | (prilocaldialplan & 0xf); 06887 break; 06888 case 'N': 06889 prilocaldialplan = (PRI_TON_NATIONAL << 4) | (prilocaldialplan & 0xf); 06890 break; 06891 case 'L': 06892 prilocaldialplan = (PRI_TON_NET_SPECIFIC << 4) | (prilocaldialplan & 0xf); 06893 break; 06894 case 'S': 06895 prilocaldialplan = (PRI_TON_SUBSCRIBER << 4) | (prilocaldialplan & 0xf); 06896 break; 06897 case 'V': 06898 prilocaldialplan = (PRI_TON_ABBREVIATED << 4) | (prilocaldialplan & 0xf); 06899 break; 06900 case 'R': 06901 prilocaldialplan = (PRI_TON_RESERVED << 4) | (prilocaldialplan & 0xf); 06902 break; 06903 case 'u': 06904 prilocaldialplan = PRI_NPI_UNKNOWN | (prilocaldialplan & 0xf0); 06905 break; 06906 case 'e': 06907 prilocaldialplan = PRI_NPI_E163_E164 | (prilocaldialplan & 0xf0); 06908 break; 06909 case 'x': 06910 prilocaldialplan = PRI_NPI_X121 | (prilocaldialplan & 0xf0); 06911 break; 06912 case 'f': 06913 prilocaldialplan = PRI_NPI_F69 | (prilocaldialplan & 0xf0); 06914 break; 06915 case 'n': 06916 prilocaldialplan = PRI_NPI_NATIONAL | (prilocaldialplan & 0xf0); 06917 break; 06918 case 'p': 06919 prilocaldialplan = PRI_NPI_PRIVATE | (prilocaldialplan & 0xf0); 06920 break; 06921 case 'r': 06922 prilocaldialplan = PRI_NPI_RESERVED | (prilocaldialplan & 0xf0); 06923 break; 06924 default: 06925 if (isalpha(*l)) { 06926 ast_log(LOG_WARNING, 06927 "Unrecognized prilocaldialplan %s modifier: %c\n", 06928 *l > 'Z' ? "NPI" : "TON", *l); 06929 } 06930 break; 06931 } 06932 l++; 06933 } 06934 } 06935 pri_sr_set_caller(sr, l ? (l + ldp_strip) : NULL, n, prilocaldialplan, 06936 p->use_callingpres ? ast->connected.id.number.presentation : (l ? PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN : PRES_NUMBER_NOT_AVAILABLE)); 06937 06938 #if defined(HAVE_PRI_SUBADDR) 06939 if (ast->connected.id.subaddress.valid) { 06940 struct pri_party_subaddress subaddress; 06941 06942 memset(&subaddress, 0, sizeof(subaddress)); 06943 sig_pri_party_subaddress_from_ast(&subaddress, &ast->connected.id.subaddress); 06944 pri_sr_set_caller_subaddress(sr, &subaddress); 06945 } 06946 #endif /* defined(HAVE_PRI_SUBADDR) */ 06947 06948 sig_pri_redirecting_update(p, ast); 06949 06950 #ifdef SUPPORT_USERUSER 06951 /* User-user info */ 06952 useruser = pbx_builtin_getvar_helper(p->owner, "USERUSERINFO"); 06953 if (useruser) 06954 pri_sr_set_useruser(sr, useruser); 06955 #endif 06956 06957 #if defined(HAVE_PRI_CCSS) 06958 if (ast_cc_is_recall(ast, &core_id, sig_pri_cc_type_name)) { 06959 struct ast_cc_monitor *monitor; 06960 char device_name[AST_CHANNEL_NAME]; 06961 06962 /* This is a CC recall call. */ 06963 ast_channel_get_device_name(ast, device_name, sizeof(device_name)); 06964 monitor = ast_cc_get_monitor_by_recall_core_id(core_id, device_name); 06965 if (monitor) { 06966 struct sig_pri_cc_monitor_instance *instance; 06967 06968 instance = monitor->private_data; 06969 06970 /* If this fails then we have monitor instance ambiguity. */ 06971 ast_assert(p->pri == instance->pri); 06972 06973 if (pri_cc_call(p->pri->pri, instance->cc_id, p->call, sr)) { 06974 /* The CC recall call failed for some reason. */ 06975 ast_log(LOG_WARNING, "Unable to setup CC recall call to device %s\n", 06976 device_name); 06977 ao2_ref(monitor, -1); 06978 pri_destroycall(p->pri->pri, p->call); 06979 p->call = NULL; 06980 pri_rel(p->pri); 06981 pri_sr_free(sr); 06982 return -1; 06983 } 06984 ao2_ref(monitor, -1); 06985 } else { 06986 core_id = -1; 06987 } 06988 } else 06989 #endif /* defined(HAVE_PRI_CCSS) */ 06990 { 06991 core_id = -1; 06992 } 06993 if (core_id == -1 && pri_setup(p->pri->pri, p->call, sr)) { 06994 ast_log(LOG_WARNING, "Unable to setup call to %s (using %s)\n", 06995 c + p->stripmsd + dp_strip, dialplan2str(p->pri->dialplan)); 06996 pri_destroycall(p->pri->pri, p->call); 06997 p->call = NULL; 06998 pri_rel(p->pri); 06999 pri_sr_free(sr); 07000 return -1; 07001 } 07002 p->call_level = SIG_PRI_CALL_LEVEL_SETUP; 07003 pri_sr_free(sr); 07004 ast_setstate(ast, AST_STATE_DIALING); 07005 sig_pri_set_dialing(p, 1); 07006 pri_rel(p->pri); 07007 return 0; 07008 }
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 8352 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.
08353 { 08354 struct sig_pri_cc_agent_prv *cc_pvt; 08355 08356 cc_pvt = agent->private_data; 08357 ast_mutex_lock(&cc_pvt->pri->lock); 08358 pri_cc_remote_user_free(cc_pvt->pri->pri, cc_pvt->cc_id); 08359 ast_mutex_unlock(&cc_pvt->pri->lock); 08360 return 0; 08361 }
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 8381 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().
08382 { 08383 struct sig_pri_cc_agent_prv *cc_pvt; 08384 int res; 08385 08386 cc_pvt = agent->private_data; 08387 if (!cc_pvt) { 08388 /* The agent constructor probably failed. */ 08389 return; 08390 } 08391 ast_mutex_lock(&cc_pvt->pri->lock); 08392 res = -1; 08393 if (cc_pvt->cc_request_response_pending) { 08394 res = pri_cc_req_rsp(cc_pvt->pri->pri, cc_pvt->cc_id, 2/* short_term_denial */); 08395 } 08396 if (res) { 08397 pri_cc_cancel(cc_pvt->pri->pri, cc_pvt->cc_id); 08398 } 08399 ast_mutex_unlock(&cc_pvt->pri->lock); 08400 ast_free(cc_pvt); 08401 }
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 8064 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().
08065 { 08066 struct sig_pri_cc_agent_prv *cc_pvt; 08067 08068 cc_pvt = ast_calloc(1, sizeof(*cc_pvt)); 08069 if (!cc_pvt) { 08070 return -1; 08071 } 08072 08073 ast_mutex_lock(&pvt_chan->pri->lock); 08074 cc_pvt->pri = pvt_chan->pri; 08075 cc_pvt->cc_id = pri_cc_available(pvt_chan->pri->pri, pvt_chan->call); 08076 ast_mutex_unlock(&pvt_chan->pri->lock); 08077 if (cc_pvt->cc_id == -1) { 08078 ast_free(cc_pvt); 08079 return -1; 08080 } 08081 agent->private_data = cc_pvt; 08082 return 0; 08083 }
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 8296 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.
08297 { 08298 struct sig_pri_cc_agent_prv *cc_pvt; 08299 08300 cc_pvt = agent->private_data; 08301 ast_mutex_lock(&cc_pvt->pri->lock); 08302 pri_cc_b_free(cc_pvt->pri->pri, cc_pvt->cc_id); 08303 ast_mutex_unlock(&cc_pvt->pri->lock); 08304 return 0; 08305 }
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 8157 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.
08158 { 08159 struct sig_pri_cc_agent_prv *cc_pvt; 08160 int res; 08161 int status; 08162 const char *failed_msg; 08163 static const char *failed_to_send = "Failed to send the CC request response."; 08164 static const char *not_accepted = "The core declined the CC request."; 08165 08166 cc_pvt = agent->private_data; 08167 ast_mutex_lock(&cc_pvt->pri->lock); 08168 if (cc_pvt->cc_request_response_pending) { 08169 cc_pvt->cc_request_response_pending = 0; 08170 08171 /* Convert core response reason to ISDN response status. */ 08172 status = 2;/* short_term_denial */ 08173 switch (reason) { 08174 case AST_CC_AGENT_RESPONSE_SUCCESS: 08175 status = 0;/* success */ 08176 break; 08177 case AST_CC_AGENT_RESPONSE_FAILURE_INVALID: 08178 status = 2;/* short_term_denial */ 08179 break; 08180 case AST_CC_AGENT_RESPONSE_FAILURE_TOO_MANY: 08181 status = 5;/* queue_full */ 08182 break; 08183 } 08184 08185 res = pri_cc_req_rsp(cc_pvt->pri->pri, cc_pvt->cc_id, status); 08186 if (!status) { 08187 /* CC core request was accepted. */ 08188 if (res) { 08189 failed_msg = failed_to_send; 08190 } else { 08191 failed_msg = NULL; 08192 } 08193 } else { 08194 /* CC core request was declined. */ 08195 if (res) { 08196 failed_msg = failed_to_send; 08197 } else { 08198 failed_msg = not_accepted; 08199 } 08200 } 08201 } else { 08202 failed_msg = NULL; 08203 } 08204 ast_mutex_unlock(&cc_pvt->pri->lock); 08205 if (failed_msg) { 08206 ast_cc_failed(agent->core_id, "%s agent: %s", sig_pri_cc_type_name, failed_msg); 08207 } 08208 }
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 8325 of file sig_pri.c.
08326 { 08327 /* libpri already knows when and how it needs to monitor Party A. */ 08328 return 0; 08329 }
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 8108 of file sig_pri.c.
08109 { 08110 /* libpri maintains it's own offer timer in the form of T_RETENTION. */ 08111 return 0; 08112 }
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 8227 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.
08228 { 08229 struct sig_pri_cc_agent_prv *cc_pvt; 08230 08231 cc_pvt = agent->private_data; 08232 ast_mutex_lock(&cc_pvt->pri->lock); 08233 pri_cc_status_req(cc_pvt->pri->pri, cc_pvt->cc_id); 08234 ast_mutex_unlock(&cc_pvt->pri->lock); 08235 return 0; 08236 }
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 8129 of file sig_pri.c.
08130 { 08131 /* libpri maintains it's own offer timer in the form of T_RETENTION. */ 08132 return 0; 08133 }
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 8262 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.
08263 { 08264 struct sig_pri_cc_agent_prv *cc_pvt; 08265 08266 cc_pvt = agent->private_data; 08267 ast_mutex_lock(&cc_pvt->pri->lock); 08268 pri_cc_stop_alerting(cc_pvt->pri->pri, cc_pvt->cc_id); 08269 ast_mutex_unlock(&cc_pvt->pri->lock); 08270 return 0; 08271 }
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 8607 of file sig_pri.c.
08608 { 08609 /* 08610 * libpri maintains it's own available timer as one of: 08611 * T_CCBS2/T_CCBS5/T_CCBS6/QSIG_CCBS_T2 08612 * T_CCNR2/T_CCNR5/T_CCNR6/QSIG_CCNR_T2 08613 */ 08614 return 0; 08615 }
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 8630 of file sig_pri.c.
References ao2_ref, ao2_unlink, and sig_pri_cc_monitors.
08631 { 08632 struct sig_pri_cc_monitor_instance *instance; 08633 08634 instance = monitor_pvt; 08635 if (!instance) { 08636 return; 08637 } 08638 ao2_unlink(sig_pri_cc_monitors, instance); 08639 ao2_ref(instance, -1); 08640 }
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 8463 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.
08464 { 08465 struct sig_pri_cc_monitor_instance *instance; 08466 int cc_mode; 08467 int res; 08468 08469 switch (monitor->service_offered) { 08470 case AST_CC_CCBS: 08471 cc_mode = 0;/* CCBS */ 08472 break; 08473 case AST_CC_CCNR: 08474 cc_mode = 1;/* CCNR */ 08475 break; 08476 default: 08477 /* CC service not supported by ISDN. */ 08478 return -1; 08479 } 08480 08481 instance = monitor->private_data; 08482 08483 /* libpri handles it's own available timer. */ 08484 ast_mutex_lock(&instance->pri->lock); 08485 res = pri_cc_req(instance->pri->pri, instance->cc_id, cc_mode); 08486 ast_mutex_unlock(&instance->pri->lock); 08487 08488 return res; 08489 }
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 8562 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.
08563 { 08564 struct sig_pri_cc_monitor_instance *instance; 08565 int cc_status; 08566 08567 switch (devstate) { 08568 case AST_DEVICE_UNKNOWN: 08569 case AST_DEVICE_NOT_INUSE: 08570 cc_status = 0;/* free */ 08571 break; 08572 case AST_DEVICE_BUSY: 08573 case AST_DEVICE_INUSE: 08574 cc_status = 1;/* busy */ 08575 break; 08576 default: 08577 /* Don't know how to interpret this device state into free/busy status. */ 08578 return 0; 08579 } 08580 instance = monitor->private_data; 08581 ast_mutex_lock(&instance->pri->lock); 08582 pri_cc_status_req_rsp(instance->pri->pri, instance->cc_id, cc_status); 08583 ast_mutex_unlock(&instance->pri->lock); 08584 08585 return 0; 08586 }
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 8506 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.
08507 { 08508 struct sig_pri_cc_monitor_instance *instance; 08509 08510 instance = monitor->private_data; 08511 ast_mutex_lock(&instance->pri->lock); 08512 pri_cc_status(instance->pri->pri, instance->cc_id, 1/* busy */); 08513 ast_mutex_unlock(&instance->pri->lock); 08514 08515 return 0; 08516 }
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 8532 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.
08533 { 08534 struct sig_pri_cc_monitor_instance *instance; 08535 08536 instance = monitor->private_data; 08537 ast_mutex_lock(&instance->pri->lock); 08538 pri_cc_status(instance->pri->pri, instance->cc_id, 0/* free */); 08539 ast_mutex_unlock(&instance->pri->lock); 08540 08541 return 0; 08542 }
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 7816 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().
07817 { 07818 pri_grab(p, p->pri); 07819 sig_pri_set_alarm(p, !noalarm); 07820 if (!noalarm) { 07821 if (pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0) { 07822 /* T309 is not enabled : destroy calls when alarm occurs */ 07823 if (p->call) { 07824 pri_destroycall(p->pri->pri, p->call); 07825 p->call = NULL; 07826 } 07827 if (p->owner) 07828 p->owner->_softhangup |= AST_SOFTHANGUP_DEV; 07829 } 07830 } 07831 sig_pri_span_devstate_changed(p->pri); 07832 pri_rel(p->pri); 07833 }
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 7875 of file sig_pri.c.
References ast_free.
Referenced by destroy_dahdi_pvt().
07876 { 07877 ast_free(doomed); 07878 }
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 7847 of file sig_pri.c.
References ast_calloc, and sig_pri_chan::pri.
07848 { 07849 struct sig_pri_chan *p; 07850 07851 p = ast_calloc(1, sizeof(*p)); 07852 if (!p) 07853 return p; 07854 07855 p->logicalspan = logicalspan; 07856 p->prioffset = channo; 07857 p->mastertrunkgroup = trunkgroup; 07858 07859 p->calls = callback; 07860 p->chan_pvt = pvt_data; 07861 07862 p->pri = pri; 07863 07864 return p; 07865 }
void sig_pri_cli_show_channels | ( | int | fd, | |
struct sig_pri_span * | pri | |||
) |
Definition at line 7888 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().
07889 { 07890 char line[256]; 07891 int idx; 07892 struct sig_pri_chan *pvt; 07893 07894 ast_mutex_lock(&pri->lock); 07895 for (idx = 0; idx < pri->numchans; ++idx) { 07896 if (!pri->pvts[idx]) { 07897 continue; 07898 } 07899 pvt = pri->pvts[idx]; 07900 sig_pri_lock_private(pvt); 07901 sig_pri_lock_owner(pri, idx); 07902 if (pvt->no_b_channel && sig_pri_is_chan_available(pvt)) { 07903 /* Don't show held/call-waiting channels if they are not in use. */ 07904 sig_pri_unlock_private(pvt); 07905 continue; 07906 } 07907 07908 snprintf(line, sizeof(line), SIG_PRI_SC_LINE, 07909 pri->span, 07910 pvt->channel, 07911 pvt->no_b_channel ? "No" : "Yes",/* Has media */ 07912 sig_pri_is_chan_available(pvt) ? "Yes" : "No", 07913 sig_pri_call_level2str(pvt->call_level), 07914 pvt->call ? "Yes" : "No", 07915 pvt->owner ? pvt->owner->name : ""); 07916 07917 if (pvt->owner) { 07918 ast_channel_unlock(pvt->owner); 07919 } 07920 sig_pri_unlock_private(pvt); 07921 07922 ast_mutex_unlock(&pri->lock); 07923 ast_cli(fd, "%s\n", line); 07924 ast_mutex_lock(&pri->lock); 07925 } 07926 ast_mutex_unlock(&pri->lock); 07927 }
void sig_pri_cli_show_channels_header | ( | int | fd | ) |
Definition at line 7882 of file sig_pri.c.
References ast_cli(), and SIG_PRI_SC_HEADER.
Referenced by handle_pri_show_channels().
07883 { 07884 ast_cli(fd, SIG_PRI_SC_HEADER, "PRI", "", "B", "Chan", "Call", "PRI", "Channel"); 07885 ast_cli(fd, SIG_PRI_SC_HEADER, "Span", "Chan", "Chan", "Idle", "Level", "Call", "Name"); 07886 }
void sig_pri_cli_show_span | ( | int | fd, | |
int * | dchannels, | |||
struct sig_pri_span * | pri | |||
) |
Definition at line 7960 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().
07961 { 07962 int x; 07963 char status[256]; 07964 07965 for (x = 0; x < SIG_PRI_NUM_DCHANS; x++) { 07966 if (pri->dchans[x]) { 07967 #ifdef PRI_DUMP_INFO_STR 07968 char *info_str = NULL; 07969 #endif 07970 ast_cli(fd, "%s D-channel: %d\n", pri_order(x), dchannels[x]); 07971 build_status(status, sizeof(status), pri->dchanavail[x], pri->dchans[x] == pri->pri); 07972 ast_cli(fd, "Status: %s\n", status); 07973 ast_mutex_lock(&pri->lock); 07974 #ifdef PRI_DUMP_INFO_STR 07975 info_str = pri_dump_info_str(pri->pri); 07976 if (info_str) { 07977 ast_cli(fd, "%s", info_str); 07978 free(info_str); 07979 } 07980 #else 07981 pri_dump_info(pri->pri); 07982 #endif 07983 ast_mutex_unlock(&pri->lock); 07984 ast_cli(fd, "Overlap Recv: %s\n\n", (pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)?"Yes":"No"); 07985 ast_cli(fd, "\n"); 07986 } 07987 } 07988 }
void sig_pri_cli_show_spans | ( | int | fd, | |
int | span, | |||
struct sig_pri_span * | pri | |||
) |
Definition at line 7948 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().
07949 { 07950 char status[256]; 07951 int x; 07952 for (x = 0; x < SIG_PRI_NUM_DCHANS; x++) { 07953 if (pri->dchans[x]) { 07954 build_status(status, sizeof(status), pri->dchanavail[x], pri->dchans[x] == pri->pri); 07955 ast_cli(fd, "PRI span %d/%d: %s\n", span, x, status); 07956 } 07957 } 07958 }
void sig_pri_dial_complete | ( | struct sig_pri_chan * | pvt, | |
struct ast_channel * | ast | |||
) |
DTMF dial string complete.
pvt | sig_pri private channel structure. | |
ast | Asterisk channel |
Definition at line 7428 of file sig_pri.c.
References AST_CONTROL_ANSWER, AST_FRAME_CONTROL, ast_queue_frame(), sig_pri_chan::call_level, sig_pri_chan::calls, sig_pri_chan::chan_pvt, f, sig_pri_callback::queue_control, SIG_PRI_CALL_LEVEL_CONNECT, SIG_PRI_CALL_LEVEL_DEFER_DIAL, sig_pri_open_media(), sig_pri_set_dialing(), and sig_pri_set_echocanceller().
Referenced by dahdi_handle_event().
07429 { 07430 /* If we just completed 'w' deferred dialing digits, we need to answer now. */ 07431 if (pvt->call_level == SIG_PRI_CALL_LEVEL_DEFER_DIAL) { 07432 pvt->call_level = SIG_PRI_CALL_LEVEL_CONNECT; 07433 07434 sig_pri_open_media(pvt); 07435 { 07436 struct ast_frame f = {AST_FRAME_CONTROL, }; 07437 07438 if (pvt->calls->queue_control) { 07439 pvt->calls->queue_control(pvt->chan_pvt, AST_CONTROL_ANSWER); 07440 } 07441 07442 f.subclass.integer = AST_CONTROL_ANSWER; 07443 ast_queue_frame(ast, &f); 07444 } 07445 sig_pri_set_dialing(pvt, 0); 07446 /* Enable echo cancellation if it's not on already */ 07447 sig_pri_set_echocanceller(pvt, 1); 07448 } 07449 }
int sig_pri_digit_begin | ( | struct sig_pri_chan * | pvt, | |
struct ast_channel * | ast, | |||
char | digit | |||
) |
Definition at line 7382 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().
07383 { 07384 if (ast->_state == AST_STATE_DIALING) { 07385 if (pvt->call_level < SIG_PRI_CALL_LEVEL_OVERLAP) { 07386 unsigned int len; 07387 07388 len = strlen(pvt->dialdest); 07389 if (len < sizeof(pvt->dialdest) - 1) { 07390 ast_debug(1, "Queueing digit '%c' since setup_ack not yet received\n", 07391 digit); 07392 pvt->dialdest[len++] = digit; 07393 pvt->dialdest[len] = '\0'; 07394 } else { 07395 ast_log(LOG_WARNING, 07396 "Span %d: Deferred digit buffer overflow for digit '%c'.\n", 07397 pvt->pri->span, digit); 07398 } 07399 return 0; 07400 } 07401 if (pvt->call_level < SIG_PRI_CALL_LEVEL_PROCEEDING) { 07402 pri_grab(pvt, pvt->pri); 07403 pri_information(pvt->pri->pri, pvt->call, digit); 07404 pri_rel(pvt->pri); 07405 return 0; 07406 } 07407 if (pvt->call_level < SIG_PRI_CALL_LEVEL_CONNECT) { 07408 ast_log(LOG_WARNING, 07409 "Span %d: Digit '%c' may be ignored by peer. (Call level:%d(%s))\n", 07410 pvt->pri->span, digit, pvt->call_level, 07411 sig_pri_call_level2str(pvt->call_level)); 07412 } 07413 } 07414 return 1; 07415 }
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 6478 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().
06479 { 06480 char *dial; 06481 char *number; 06482 char *subaddr; 06483 AST_DECLARE_APP_ARGS(args, 06484 AST_APP_ARG(group); /* channel/group token */ 06485 AST_APP_ARG(ext); /* extension token */ 06486 //AST_APP_ARG(opts); /* options token */ 06487 AST_APP_ARG(other); /* Any remining unused arguments */ 06488 ); 06489 06490 /* Get private copy of dial string and break it up. */ 06491 dial = ast_strdupa(rdest); 06492 AST_NONSTANDARD_APP_ARGS(args, dial, '/'); 06493 06494 number = args.ext; 06495 if (!number) { 06496 number = ""; 06497 } 06498 06499 /* Find and extract dialed_subaddress */ 06500 subaddr = strchr(number, ':'); 06501 if (subaddr) { 06502 *subaddr++ = '\0'; 06503 06504 /* Skip subaddress type prefix. */ 06505 switch (*subaddr) { 06506 case 'U': 06507 case 'u': 06508 case 'N': 06509 case 'n': 06510 ++subaddr; 06511 break; 06512 default: 06513 break; 06514 } 06515 } 06516 06517 /* Skip type-of-number/dial-plan prefix characters. */ 06518 if (strlen(number) < p->stripmsd) { 06519 number = ""; 06520 } else { 06521 char *deferred; 06522 06523 number += p->stripmsd; 06524 deferred = strchr(number, 'w'); 06525 if (deferred) { 06526 /* Remove any 'w' deferred digits. */ 06527 *deferred = '\0'; 06528 } 06529 while (isalpha(*number)) { 06530 ++number; 06531 } 06532 } 06533 06534 /* Fill buffer with extracted number and subaddress. */ 06535 if (ast_strlen_zero(subaddr)) { 06536 /* Put in called number only since there is no subaddress. */ 06537 snprintf(called, called_buff_size, "%s", number); 06538 } else { 06539 /* Put in called number and subaddress. */ 06540 snprintf(called, called_buff_size, "%s:%s", number, subaddr); 06541 } 06542 }
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 6387 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::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_set_outgoing(), 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().
06388 { 06389 ast_debug(1, "%s %d\n", __FUNCTION__, p->channel); 06390 if (!ast->tech_pvt) { 06391 ast_log(LOG_WARNING, "Asked to hangup channel not connected\n"); 06392 return 0; 06393 } 06394 06395 sig_pri_set_outgoing(p, 0); 06396 sig_pri_set_digital(p, 0); /* push up to parent for EC*/ 06397 #if defined(HAVE_PRI_CALL_WAITING) 06398 if (p->is_call_waiting) { 06399 p->is_call_waiting = 0; 06400 ast_atomic_fetchadd_int(&p->pri->num_call_waiting_calls, -1); 06401 } 06402 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 06403 p->call_level = SIG_PRI_CALL_LEVEL_IDLE; 06404 p->progress = 0; 06405 p->cid_num[0] = '\0'; 06406 p->cid_subaddr[0] = '\0'; 06407 p->cid_name[0] = '\0'; 06408 p->user_tag[0] = '\0'; 06409 p->exten[0] = '\0'; 06410 sig_pri_set_dialing(p, 0); 06411 06412 /* Make sure we really have a call */ 06413 pri_grab(p, p->pri); 06414 if (p->call) { 06415 #if defined(SUPPORT_USERUSER) 06416 const char *useruser = pbx_builtin_getvar_helper(ast, "USERUSERINFO"); 06417 06418 if (!ast_strlen_zero(useruser)) { 06419 pri_call_set_useruser(p->call, useruser); 06420 } 06421 #endif /* defined(SUPPORT_USERUSER) */ 06422 06423 #if defined(HAVE_PRI_AOC_EVENTS) 06424 if (p->holding_aoce) { 06425 pri_aoc_e_send(p->pri->pri, p->call, &p->aoc_e); 06426 } 06427 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 06428 06429 if (p->alreadyhungup) { 06430 ast_debug(1, "Already hungup... Calling hangup once, and clearing call\n"); 06431 06432 pri_hangup(p->pri->pri, p->call, -1); 06433 p->call = NULL; 06434 } else { 06435 const char *cause = pbx_builtin_getvar_helper(ast,"PRI_CAUSE"); 06436 int icause = ast->hangupcause ? ast->hangupcause : -1; 06437 06438 p->alreadyhungup = 1; 06439 if (!ast_strlen_zero(cause)) { 06440 if (atoi(cause)) { 06441 icause = atoi(cause); 06442 } 06443 } 06444 ast_debug(1, 06445 "Not yet hungup... Calling hangup with cause %d, and clearing call\n", 06446 icause); 06447 06448 pri_hangup(p->pri->pri, p->call, icause); 06449 } 06450 } 06451 #if defined(HAVE_PRI_AOC_EVENTS) 06452 p->aoc_s_request_invoke_id_valid = 0; 06453 p->holding_aoce = 0; 06454 p->waiting_for_aoce = 0; 06455 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 06456 06457 p->allocated = 0; 06458 p->owner = NULL; 06459 06460 sig_pri_span_devstate_changed(p->pri); 06461 pri_rel(p->pri); 06462 return 0; 06463 }
int sig_pri_indicate | ( | struct sig_pri_chan * | p, | |
struct ast_channel * | chan, | |||
int | condition, | |||
const void * | data, | |||
size_t | datalen | |||
) |
Definition at line 7010 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().
07011 { 07012 int res = -1; 07013 07014 switch (condition) { 07015 case AST_CONTROL_BUSY: 07016 if (p->priindication_oob || p->no_b_channel) { 07017 chan->hangupcause = AST_CAUSE_USER_BUSY; 07018 chan->_softhangup |= AST_SOFTHANGUP_DEV; 07019 res = 0; 07020 break; 07021 } 07022 res = sig_pri_play_tone(p, SIG_PRI_TONE_BUSY); 07023 if (p->call_level < SIG_PRI_CALL_LEVEL_ALERTING && !p->outgoing) { 07024 chan->hangupcause = AST_CAUSE_USER_BUSY; 07025 p->progress = 1;/* No need to send plain PROGRESS after this. */ 07026 if (p->pri && p->pri->pri) { 07027 pri_grab(p, p->pri); 07028 #ifdef HAVE_PRI_PROG_W_CAUSE 07029 pri_progress_with_cause(p->pri->pri, p->call, PVT_TO_CHANNEL(p), 1, chan->hangupcause); 07030 #else 07031 pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1); 07032 #endif 07033 pri_rel(p->pri); 07034 } 07035 } 07036 break; 07037 case AST_CONTROL_RINGING: 07038 if (p->call_level < SIG_PRI_CALL_LEVEL_ALERTING && !p->outgoing) { 07039 p->call_level = SIG_PRI_CALL_LEVEL_ALERTING; 07040 if (p->pri && p->pri->pri) { 07041 pri_grab(p, p->pri); 07042 pri_acknowledge(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 07043 p->no_b_channel || p->digital ? 0 : 1); 07044 pri_rel(p->pri); 07045 } 07046 } 07047 res = sig_pri_play_tone(p, SIG_PRI_TONE_RINGTONE); 07048 if (chan->_state != AST_STATE_UP) { 07049 if (chan->_state != AST_STATE_RING) 07050 ast_setstate(chan, AST_STATE_RINGING); 07051 } 07052 break; 07053 case AST_CONTROL_PROCEEDING: 07054 ast_debug(1,"Received AST_CONTROL_PROCEEDING on %s\n",chan->name); 07055 if (p->call_level < SIG_PRI_CALL_LEVEL_PROCEEDING && !p->outgoing) { 07056 p->call_level = SIG_PRI_CALL_LEVEL_PROCEEDING; 07057 if (p->pri && p->pri->pri) { 07058 pri_grab(p, p->pri); 07059 pri_proceeding(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 07060 p->no_b_channel || p->digital ? 0 : 1); 07061 if (!p->no_b_channel && !p->digital) { 07062 sig_pri_set_dialing(p, 0); 07063 } 07064 pri_rel(p->pri); 07065 } 07066 } 07067 /* don't continue in ast_indicate */ 07068 res = 0; 07069 break; 07070 case AST_CONTROL_PROGRESS: 07071 ast_debug(1,"Received AST_CONTROL_PROGRESS on %s\n",chan->name); 07072 sig_pri_set_digital(p, 0); /* Digital-only calls isn't allowing any inband progress messages */ 07073 if (!p->progress && p->call_level < SIG_PRI_CALL_LEVEL_ALERTING && !p->outgoing 07074 && !p->no_b_channel) { 07075 p->progress = 1;/* No need to send plain PROGRESS again. */ 07076 if (p->pri && p->pri->pri) { 07077 pri_grab(p, p->pri); 07078 #ifdef HAVE_PRI_PROG_W_CAUSE 07079 pri_progress_with_cause(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1, -1); /* no cause at all */ 07080 #else 07081 pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1); 07082 #endif 07083 pri_rel(p->pri); 07084 } 07085 } 07086 /* don't continue in ast_indicate */ 07087 res = 0; 07088 break; 07089 case AST_CONTROL_INCOMPLETE: 07090 /* If we are connected or if we support overlap dialing, wait for additional digits */ 07091 if (p->call_level == SIG_PRI_CALL_LEVEL_CONNECT || (p->pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)) { 07092 res = 0; 07093 break; 07094 } 07095 /* Otherwise, treat as congestion */ 07096 chan->hangupcause = AST_CAUSE_INVALID_NUMBER_FORMAT; 07097 /* Falls through */ 07098 case AST_CONTROL_CONGESTION: 07099 if (p->priindication_oob || p->no_b_channel) { 07100 /* There are many cause codes that generate an AST_CONTROL_CONGESTION. */ 07101 switch (chan->hangupcause) { 07102 case AST_CAUSE_USER_BUSY: 07103 case AST_CAUSE_NORMAL_CLEARING: 07104 case 0:/* Cause has not been set. */ 07105 /* Supply a more appropriate cause. */ 07106 chan->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 07107 break; 07108 default: 07109 break; 07110 } 07111 chan->_softhangup |= AST_SOFTHANGUP_DEV; 07112 res = 0; 07113 break; 07114 } 07115 res = sig_pri_play_tone(p, SIG_PRI_TONE_CONGESTION); 07116 if (p->call_level < SIG_PRI_CALL_LEVEL_ALERTING && !p->outgoing) { 07117 /* There are many cause codes that generate an AST_CONTROL_CONGESTION. */ 07118 switch (chan->hangupcause) { 07119 case AST_CAUSE_USER_BUSY: 07120 case AST_CAUSE_NORMAL_CLEARING: 07121 case 0:/* Cause has not been set. */ 07122 /* Supply a more appropriate cause. */ 07123 chan->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 07124 break; 07125 default: 07126 break; 07127 } 07128 p->progress = 1;/* No need to send plain PROGRESS after this. */ 07129 if (p->pri && p->pri->pri) { 07130 pri_grab(p, p->pri); 07131 #ifdef HAVE_PRI_PROG_W_CAUSE 07132 pri_progress_with_cause(p->pri->pri, p->call, PVT_TO_CHANNEL(p), 1, chan->hangupcause); 07133 #else 07134 pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1); 07135 #endif 07136 pri_rel(p->pri); 07137 } 07138 } 07139 break; 07140 case AST_CONTROL_HOLD: 07141 if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) { 07142 pri_grab(p, p->pri); 07143 res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_HOLD); 07144 pri_rel(p->pri); 07145 } else 07146 ast_moh_start(chan, data, p->mohinterpret); 07147 break; 07148 case AST_CONTROL_UNHOLD: 07149 if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) { 07150 pri_grab(p, p->pri); 07151 res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_RETRIEVAL); 07152 pri_rel(p->pri); 07153 } else 07154 ast_moh_stop(chan); 07155 break; 07156 case AST_CONTROL_SRCUPDATE: 07157 res = 0; 07158 break; 07159 case -1: 07160 res = sig_pri_play_tone(p, -1); 07161 break; 07162 case AST_CONTROL_CONNECTED_LINE: 07163 ast_debug(1, "Received AST_CONTROL_CONNECTED_LINE on %s\n", chan->name); 07164 if (p->pri) { 07165 struct pri_party_connected_line connected; 07166 07167 pri_grab(p, p->pri); 07168 memset(&connected, 0, sizeof(connected)); 07169 sig_pri_party_id_from_ast(&connected.id, &chan->connected.id); 07170 07171 pri_connected_line_update(p->pri->pri, p->call, &connected); 07172 pri_rel(p->pri); 07173 } 07174 break; 07175 case AST_CONTROL_REDIRECTING: 07176 ast_debug(1, "Received AST_CONTROL_REDIRECTING on %s\n", chan->name); 07177 if (p->pri) { 07178 pri_grab(p, p->pri); 07179 sig_pri_redirecting_update(p, chan); 07180 pri_rel(p->pri); 07181 } 07182 break; 07183 case AST_CONTROL_AOC: 07184 #if defined(HAVE_PRI_AOC_EVENTS) 07185 { 07186 struct ast_aoc_decoded *decoded 07187 = ast_aoc_decode((struct ast_aoc_encoded *) data, datalen, chan); 07188 ast_debug(1, "Received AST_CONTROL_AOC on %s\n", chan->name); 07189 if (decoded && p->pri) { 07190 pri_grab(p, p->pri); 07191 switch (ast_aoc_get_msg_type(decoded)) { 07192 case AST_AOC_S: 07193 if (p->pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_S) { 07194 sig_pri_aoc_s_from_ast(p, decoded); 07195 } 07196 break; 07197 case AST_AOC_D: 07198 if (p->pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_D) { 07199 sig_pri_aoc_d_from_ast(p, decoded); 07200 } 07201 break; 07202 case AST_AOC_E: 07203 if (p->pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_E) { 07204 sig_pri_aoc_e_from_ast(p, decoded); 07205 } 07206 /* if hangup was delayed for this AOC-E msg, waiting_for_aoc 07207 * will be set. A hangup is already occuring via a timeout during 07208 * this delay. Instead of waiting for that timeout to occur, go ahead 07209 * and initiate the softhangup since the delay is no longer necessary */ 07210 if (p->waiting_for_aoce) { 07211 p->waiting_for_aoce = 0; 07212 ast_log(LOG_DEBUG, 07213 "Received final AOC-E msg, continue with hangup on %s\n", 07214 chan->name); 07215 ast_softhangup_nolock(chan, AST_SOFTHANGUP_DEV); 07216 } 07217 break; 07218 case AST_AOC_REQUEST: 07219 /* We do not pass through AOC requests, So unless this 07220 * is an AOC termination request it will be ignored */ 07221 if (ast_aoc_get_termination_request(decoded)) { 07222 pri_hangup(p->pri->pri, p->call, -1); 07223 } 07224 break; 07225 default: 07226 break; 07227 } 07228 pri_rel(p->pri); 07229 } 07230 ast_aoc_destroy_decoded(decoded); 07231 } 07232 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 07233 break; 07234 } 07235 07236 return res; 07237 }
void sig_pri_init_pri | ( | struct sig_pri_span * | pri | ) |
Definition at line 6374 of file sig_pri.c.
References ast_mutex_init, AST_PTHREADT_NULL, and SIG_PRI_NUM_DCHANS.
Referenced by load_module().
06375 { 06376 int i; 06377 06378 memset(pri, 0, sizeof(*pri)); 06379 06380 ast_mutex_init(&pri->lock); 06381 06382 pri->master = AST_PTHREADT_NULL; 06383 for (i = 0; i < SIG_PRI_NUM_DCHANS; i++) 06384 pri->fds[i] = -1; 06385 }
int sig_pri_is_alarm_ignored | ( | struct sig_pri_span * | pri | ) |
Determine if layer 1 alarms are ignored.
p | Channel private pointer. |
Definition at line 7842 of file sig_pri.c.
References sig_pri_span::layer1_ignored.
Referenced by handle_alarms(), handle_clear_alarms(), my_handle_dchan_exception(), and sig_pri_set_alarm().
07843 { 07844 return pri->layer1_ignored; 07845 }
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 1159 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().
01160 { 01161 return !sig_pri_is_chan_in_use(pvt) 01162 #if defined(HAVE_PRI_SERVICE_MESSAGES) 01163 /* And not out-of-service */ 01164 && !pvt->service_status 01165 #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */ 01166 ; 01167 }
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 8652 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().
08653 { 08654 #if defined(HAVE_PRI_CCSS) 08655 sig_pri_cc_type_name = cc_type_name; 08656 sig_pri_cc_monitors = ao2_container_alloc(37, sig_pri_cc_monitor_instance_hash_fn, 08657 sig_pri_cc_monitor_instance_cmp_fn); 08658 if (!sig_pri_cc_monitors) { 08659 return -1; 08660 } 08661 #endif /* defined(HAVE_PRI_CCSS) */ 08662 return 0; 08663 }
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 1012 of file sig_pri.c.
References ast_log(), AST_STATE_RESERVED, sig_pri_chan::channel, sig_pri_chan::exten, LOG_DEBUG, sig_pri_new_ast_channel(), and sig_pri_set_outgoing().
Referenced by dahdi_request(), and pri_dchannel().
01013 { 01014 struct ast_channel *ast; 01015 01016 ast_log(LOG_DEBUG, "%s %d\n", __FUNCTION__, p->channel); 01017 01018 sig_pri_set_outgoing(p, 1); 01019 ast = sig_pri_new_ast_channel(p, AST_STATE_RESERVED, law, transfercapability, p->exten, requestor); 01020 if (!ast) { 01021 sig_pri_set_outgoing(p, 0); 01022 } 01023 return ast; 01024 }
void sig_pri_set_alarm | ( | struct sig_pri_chan * | p, | |
int | in_alarm | |||
) |
Definition at line 187 of file sig_pri.c.
References sig_pri_chan::calls, sig_pri_chan::chan_pvt, sig_pri_chan::inalarm, sig_pri_chan::pri, sig_pri_chan::resetting, sig_pri_callback::set_alarm, sig_pri_is_alarm_ignored(), and SIG_PRI_RESET_IDLE.
Referenced by sig_pri_chan_alarm_notify().
00188 { 00189 if (sig_pri_is_alarm_ignored(p->pri)) { 00190 /* Always set not in alarm */ 00191 in_alarm = 0; 00192 } 00193 00194 /* 00195 * Clear the channel restart state when the channel alarm 00196 * changes to prevent the state from getting stuck when the link 00197 * goes down. 00198 */ 00199 p->resetting = SIG_PRI_RESET_IDLE; 00200 00201 p->inalarm = in_alarm; 00202 if (p->calls->set_alarm) { 00203 p->calls->set_alarm(p->chan_pvt, in_alarm); 00204 } 00205 }
int sig_pri_start_pri | ( | struct sig_pri_span * | pri | ) |
Definition at line 7625 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().
07626 { 07627 int x; 07628 int i; 07629 #if defined(HAVE_PRI_MWI) 07630 char *saveptr; 07631 char *mbox_number; 07632 char *mbox_context; 07633 struct ast_str *mwi_description = ast_str_alloca(64); 07634 #endif /* defined(HAVE_PRI_MWI) */ 07635 07636 #if defined(HAVE_PRI_MWI) 07637 /* Prepare the mbox[] for use. */ 07638 for (i = 0; i < ARRAY_LEN(pri->mbox); ++i) { 07639 if (pri->mbox[i].sub) { 07640 pri->mbox[i].sub = ast_event_unsubscribe(pri->mbox[i].sub); 07641 } 07642 } 07643 #endif /* defined(HAVE_PRI_MWI) */ 07644 07645 ast_mutex_init(&pri->lock); 07646 sig_pri_sort_pri_chans(pri); 07647 07648 #if defined(HAVE_PRI_MWI) 07649 /* 07650 * Split the mwi_mailboxes configuration string into the mbox[]: 07651 * mailbox_number[@context]{,mailbox_number[@context]} 07652 */ 07653 i = 0; 07654 saveptr = pri->mwi_mailboxes; 07655 while (i < ARRAY_LEN(pri->mbox)) { 07656 mbox_number = strsep(&saveptr, ","); 07657 if (!mbox_number) { 07658 break; 07659 } 07660 /* Split the mailbox_number and context */ 07661 mbox_context = strchr(mbox_number, '@'); 07662 if (mbox_context) { 07663 *mbox_context++ = '\0'; 07664 mbox_context = ast_strip(mbox_context); 07665 } 07666 mbox_number = ast_strip(mbox_number); 07667 if (ast_strlen_zero(mbox_number)) { 07668 /* There is no mailbox number. Skip it. */ 07669 continue; 07670 } 07671 if (ast_strlen_zero(mbox_context)) { 07672 /* There was no context so use the default. */ 07673 mbox_context = "default"; 07674 } 07675 07676 /* Fill the mbox[] element. */ 07677 ast_str_set(&mwi_description, -1, "%s span %d[%d] MWI mailbox %s@%s", 07678 sig_pri_cc_type_name, pri->span, i, mbox_number, mbox_context); 07679 pri->mbox[i].sub = ast_event_subscribe(AST_EVENT_MWI, sig_pri_mwi_event_cb, 07680 ast_str_buffer(mwi_description), pri, 07681 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mbox_number, 07682 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, mbox_context, 07683 AST_EVENT_IE_END); 07684 if (!pri->mbox[i].sub) { 07685 ast_log(LOG_ERROR, "%s span %d could not subscribe to MWI events for %s@%s.", 07686 sig_pri_cc_type_name, pri->span, mbox_number, mbox_context); 07687 continue; 07688 } 07689 pri->mbox[i].number = mbox_number; 07690 pri->mbox[i].context = mbox_context; 07691 ++i; 07692 } 07693 #endif /* defined(HAVE_PRI_MWI) */ 07694 07695 for (i = 0; i < SIG_PRI_NUM_DCHANS; i++) { 07696 if (pri->fds[i] == -1) { 07697 break; 07698 } 07699 07700 switch (pri->sig) { 07701 case SIG_BRI: 07702 pri->dchans[i] = pri_new_bri(pri->fds[i], 1, pri->nodetype, pri->switchtype); 07703 break; 07704 case SIG_BRI_PTMP: 07705 pri->dchans[i] = pri_new_bri(pri->fds[i], 0, pri->nodetype, pri->switchtype); 07706 break; 07707 default: 07708 pri->dchans[i] = pri_new(pri->fds[i], pri->nodetype, pri->switchtype); 07709 #if defined(HAVE_PRI_SERVICE_MESSAGES) 07710 if (pri->enable_service_message_support) { 07711 pri_set_service_message_support(pri->dchans[i], 1); 07712 } 07713 #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */ 07714 break; 07715 } 07716 07717 pri_set_overlapdial(pri->dchans[i], (pri->overlapdial & DAHDI_OVERLAPDIAL_OUTGOING) ? 1 : 0); 07718 #ifdef HAVE_PRI_PROG_W_CAUSE 07719 pri_set_chan_mapping_logical(pri->dchans[i], pri->qsigchannelmapping == DAHDI_CHAN_MAPPING_LOGICAL); 07720 #endif 07721 #ifdef HAVE_PRI_INBANDDISCONNECT 07722 pri_set_inbanddisconnect(pri->dchans[i], pri->inbanddisconnect); 07723 #endif 07724 /* Enslave to master if appropriate */ 07725 if (i) 07726 pri_enslave(pri->dchans[0], pri->dchans[i]); 07727 if (!pri->dchans[i]) { 07728 if (pri->fds[i] > 0) 07729 close(pri->fds[i]); 07730 pri->fds[i] = -1; 07731 ast_log(LOG_ERROR, "Unable to create PRI structure\n"); 07732 return -1; 07733 } 07734 pri_set_debug(pri->dchans[i], SIG_PRI_DEBUG_DEFAULT); 07735 pri_set_nsf(pri->dchans[i], pri->nsf); 07736 #ifdef PRI_GETSET_TIMERS 07737 for (x = 0; x < PRI_MAX_TIMERS; x++) { 07738 if (pri->pritimers[x] != 0) 07739 pri_set_timer(pri->dchans[i], x, pri->pritimers[x]); 07740 } 07741 #endif 07742 } 07743 07744 /* Assume primary is the one we use */ 07745 pri->pri = pri->dchans[0]; 07746 07747 #if defined(HAVE_PRI_CALL_HOLD) 07748 pri_hold_enable(pri->pri, 1); 07749 #endif /* defined(HAVE_PRI_CALL_HOLD) */ 07750 #if defined(HAVE_PRI_CALL_REROUTING) 07751 pri_reroute_enable(pri->pri, 1); 07752 #endif /* defined(HAVE_PRI_CALL_REROUTING) */ 07753 #if defined(HAVE_PRI_HANGUP_FIX) 07754 pri_hangup_fix_enable(pri->pri, 1); 07755 #endif /* defined(HAVE_PRI_HANGUP_FIX) */ 07756 #if defined(HAVE_PRI_CCSS) 07757 pri_cc_enable(pri->pri, 1); 07758 pri_cc_recall_mode(pri->pri, pri->cc_ptmp_recall_mode); 07759 pri_cc_retain_signaling_req(pri->pri, pri->cc_qsig_signaling_link_req); 07760 pri_cc_retain_signaling_rsp(pri->pri, pri->cc_qsig_signaling_link_rsp); 07761 #endif /* defined(HAVE_PRI_CCSS) */ 07762 #if defined(HAVE_PRI_TRANSFER) 07763 pri_transfer_enable(pri->pri, 1); 07764 #endif /* defined(HAVE_PRI_TRANSFER) */ 07765 #if defined(HAVE_PRI_AOC_EVENTS) 07766 pri_aoc_events_enable(pri->pri, 1); 07767 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 07768 #if defined(HAVE_PRI_CALL_WAITING) 07769 pri_connect_ack_enable(pri->pri, 1); 07770 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 07771 #if defined(HAVE_PRI_MCID) 07772 pri_mcid_enable(pri->pri, 1); 07773 #endif /* defined(HAVE_PRI_MCID) */ 07774 #if defined(HAVE_PRI_L2_PERSISTENCE) 07775 pri_persistent_layer2_option(pri->pri, pri->l2_persistence); 07776 #endif /* defined(HAVE_PRI_L2_PERSISTENCE) */ 07777 07778 pri->resetpos = -1; 07779 if (ast_pthread_create_background(&pri->master, NULL, pri_dchannel, pri)) { 07780 for (i = 0; i < SIG_PRI_NUM_DCHANS; i++) { 07781 if (!pri->dchans[i]) 07782 break; 07783 if (pri->fds[i] > 0) 07784 close(pri->fds[i]); 07785 pri->fds[i] = -1; 07786 } 07787 ast_log(LOG_ERROR, "Unable to spawn D-channel: %s\n", strerror(errno)); 07788 return -1; 07789 } 07790 07791 #if defined(HAVE_PRI_MWI) 07792 /* 07793 * Send the initial MWI indications from the event cache for this span. 07794 * 07795 * If we were loaded after app_voicemail the event would already be in 07796 * the cache. If we were loaded before app_voicemail the event would not 07797 * be in the cache yet and app_voicemail will send the event when it 07798 * gets loaded. 07799 */ 07800 sig_pri_mwi_cache_update(pri); 07801 #endif /* defined(HAVE_PRI_MWI) */ 07802 07803 return 0; 07804 }
void sig_pri_stop_pri | ( | struct sig_pri_span * | pri | ) |
Stop PRI span.
pri | PRI span control structure. |
Definition at line 7560 of file sig_pri.c.
References ARRAY_LEN, ast_event_unsubscribe(), sig_pri_span::mbox, and sig_pri_mbox::sub.
Referenced by __unload_module().
07561 { 07562 #if defined(HAVE_PRI_MWI) 07563 int idx; 07564 #endif /* defined(HAVE_PRI_MWI) */ 07565 07566 #if defined(HAVE_PRI_MWI) 07567 for (idx = 0; idx < ARRAY_LEN(pri->mbox); ++idx) { 07568 if (pri->mbox[idx].sub) { 07569 pri->mbox[idx].sub = ast_event_unsubscribe(pri->mbox[idx].sub); 07570 } 07571 } 07572 #endif /* defined(HAVE_PRI_MWI) */ 07573 }
void sig_pri_unload | ( | void | ) |
Unload the sig_pri submodule.
Definition at line 8671 of file sig_pri.c.
References ao2_ref, and sig_pri_cc_monitors.
Referenced by __unload_module().
08672 { 08673 #if defined(HAVE_PRI_CCSS) 08674 if (sig_pri_cc_monitors) { 08675 ao2_ref(sig_pri_cc_monitors, -1); 08676 sig_pri_cc_monitors = NULL; 08677 } 08678 #endif /* defined(HAVE_PRI_CCSS) */ 08679 }
const char dahdi_db[] = "dahdi/registry" [static] |