#include "asterisk/channel.h"
#include "asterisk/frame.h"
#include "asterisk/event.h"
#include "asterisk/ccss.h"
#include <libpri.h>
#include <dahdi/user.h>
Go to the source code of this file.
Data Structures | |
struct | sig_pri_callback |
struct | sig_pri_chan |
struct | sig_pri_span |
Defines | |
#define | DAHDI_CHAN_MAPPING_LOGICAL 1 |
#define | DAHDI_CHAN_MAPPING_PHYSICAL 0 |
#define | DAHDI_OVERLAPDIAL_BOTH (DAHDI_OVERLAPDIAL_INCOMING|DAHDI_OVERLAPDIAL_OUTGOING) |
#define | DAHDI_OVERLAPDIAL_INCOMING 2 |
#define | DAHDI_OVERLAPDIAL_NONE 0 |
#define | DAHDI_OVERLAPDIAL_OUTGOING 1 |
#define | SIG_BRI (0x2000000 | DAHDI_SIG_CLEAR) |
#define | SIG_BRI_PTMP (0X4000000 | DAHDI_SIG_CLEAR) |
#define | SIG_PRI DAHDI_SIG_CLEAR |
#define | SIG_PRI_AOC_GRANT_D (1 << 1) |
#define | SIG_PRI_AOC_GRANT_E (1 << 2) |
#define | SIG_PRI_AOC_GRANT_S (1 << 0) |
#define | SIG_PRI_DEBUG_DEFAULT 0 |
#define | SIG_PRI_DEBUG_INTENSE |
#define | SIG_PRI_DEBUG_NORMAL (PRI_DEBUG_APDU | PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q931_STATE | PRI_DEBUG_Q921_STATE) |
#define | SIG_PRI_MAX_CHANNELS 672 |
#define | SIG_PRI_NUM_DCHANS 4 |
#define | SRVST_BOTH (SRVST_NEAREND | SRVST_FAREND) |
SRVST_BOTH is used to indicate that both sides of the channel are out-of-service. | |
#define | SRVST_DBKEY "service-state" |
Persistent Service State. | |
#define | SRVST_FAREND (1 << 1) |
SRVST_FAREND is used to indicate that the far end was taken out-of-service. | |
#define | SRVST_INITIALIZED 0 |
SRVST_INITIALIZED is used to indicate a channel being out-of-service The SRVST_INITIALIZED is mostly used maintain backwards compatibility but also may mean that the channel has not yet received a RESTART message. If a channel is out-of-service with this reason a RESTART message will result in the channel being put into service. | |
#define | SRVST_NEAREND (1 << 0) |
SRVST_NEAREND is used to indicate that the near end was put out-of-service. | |
#define | SRVST_TYPE_OOS "O" |
The out-of-service SERVICE state. | |
Enumerations | |
enum | sig_pri_call_level { SIG_PRI_CALL_LEVEL_IDLE, SIG_PRI_CALL_LEVEL_SETUP, SIG_PRI_CALL_LEVEL_OVERLAP, SIG_PRI_CALL_LEVEL_PROCEEDING, SIG_PRI_CALL_LEVEL_ALERTING, SIG_PRI_CALL_LEVEL_CONNECT } |
enum | sig_pri_law { SIG_PRI_DEFLAW = 0, SIG_PRI_ULAW, SIG_PRI_ALAW } |
enum | sig_pri_tone { SIG_PRI_TONE_RINGTONE = 0, SIG_PRI_TONE_STUTTER, SIG_PRI_TONE_CONGESTION, SIG_PRI_TONE_DIALTONE, SIG_PRI_TONE_DIALRECALL, SIG_PRI_TONE_INFO, SIG_PRI_TONE_BUSY } |
Functions | |
void | pri_event_alarm (struct sig_pri_span *pri, int index, int before_start_pri) |
void | pri_event_noalarm (struct sig_pri_span *pri, int index, int before_start_pri) |
int | pri_is_up (struct sig_pri_span *pri) |
int | pri_maintenance_bservice (struct pri *pri, struct sig_pri_chan *p, int changestatus) |
int | pri_send_callrerouting_facility_exec (struct sig_pri_chan *p, enum ast_channel_state chanstate, const char *destination, const char *original, const char *reason) |
int | pri_send_keypad_facility_exec (struct sig_pri_chan *p, const char *digits) |
int | sig_pri_answer (struct sig_pri_chan *p, struct ast_channel *ast) |
int | sig_pri_available (struct sig_pri_chan **pvt, int is_specific_channel) |
int | sig_pri_call (struct sig_pri_chan *p, struct ast_channel *ast, char *rdest, int timeout, int layer1) |
int | sig_pri_cc_agent_callee_available (struct ast_cc_agent *agent) |
void | sig_pri_cc_agent_destructor (struct ast_cc_agent *agent) |
int | sig_pri_cc_agent_init (struct ast_cc_agent *agent, struct sig_pri_chan *pvt_chan) |
int | sig_pri_cc_agent_party_b_free (struct ast_cc_agent *agent) |
void | sig_pri_cc_agent_req_rsp (struct ast_cc_agent *agent, enum ast_cc_agent_response_reason reason) |
int | sig_pri_cc_agent_start_monitoring (struct ast_cc_agent *agent) |
int | sig_pri_cc_agent_start_offer_timer (struct ast_cc_agent *agent) |
int | sig_pri_cc_agent_status_req (struct ast_cc_agent *agent) |
int | sig_pri_cc_agent_stop_offer_timer (struct ast_cc_agent *agent) |
int | sig_pri_cc_agent_stop_ringing (struct ast_cc_agent *agent) |
int | sig_pri_cc_monitor_cancel_available_timer (struct ast_cc_monitor *monitor, int *sched_id) |
void | sig_pri_cc_monitor_destructor (void *monitor_pvt) |
int | sig_pri_cc_monitor_req_cc (struct ast_cc_monitor *monitor, int *available_timer_id) |
int | sig_pri_cc_monitor_status_rsp (struct ast_cc_monitor *monitor, enum ast_device_state devstate) |
int | sig_pri_cc_monitor_suspend (struct ast_cc_monitor *monitor) |
int | sig_pri_cc_monitor_unsuspend (struct ast_cc_monitor *monitor) |
void | sig_pri_chan_alarm_notify (struct sig_pri_chan *p, int noalarm) |
void | sig_pri_chan_delete (struct sig_pri_chan *doomed) |
Delete the sig_pri private channel structure. | |
sig_pri_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_span (int fd, int *dchannels, struct sig_pri_span *pri) |
void | sig_pri_cli_show_spans (int fd, int span, struct sig_pri_span *pri) |
int | sig_pri_digit_begin (struct sig_pri_chan *pvt, struct ast_channel *ast, char digit) |
void | sig_pri_extract_called_num_subaddr (struct sig_pri_chan *p, const char *rdest, char *called, size_t called_buff_size) |
Extract the called number and subaddress from the dial string. | |
void | sig_pri_fixup (struct ast_channel *oldchan, struct ast_channel *newchan, struct sig_pri_chan *pchan) |
int | sig_pri_hangup (struct sig_pri_chan *p, struct ast_channel *ast) |
int | sig_pri_indicate (struct sig_pri_chan *p, struct ast_channel *chan, int condition, const void *data, size_t datalen) |
void | sig_pri_init_pri (struct sig_pri_span *pri) |
int | sig_pri_load (const char *cc_type_name) |
Load the sig_pri submodule. | |
ast_channel * | sig_pri_request (struct sig_pri_chan *p, enum sig_pri_law law, const struct ast_channel *requestor, int transfercapability) |
int | sig_pri_start_pri (struct sig_pri_span *pri) |
void | sig_pri_stop_pri (struct sig_pri_span *pri) |
Stop PRI span. | |
void | sig_pri_unload (void) |
Unload the sig_pri submodule. | |
Variables | |
static const char | dahdi_db [] = "dahdi/registry" |
The AstDB family. |
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 162 of file sig_pri.h.
Referenced by dahdi_handle_event(), dahdi_read(), pri_ss_thread(), and sig_pri_cli_show_span().
#define DAHDI_OVERLAPDIAL_OUTGOING 1 |
#define SIG_PRI_AOC_GRANT_D (1 << 1) |
Definition at line 67 of file sig_pri.h.
Referenced by sig_pri_handle_subcmds(), and sig_pri_indicate().
#define SIG_PRI_AOC_GRANT_E (1 << 2) |
Definition at line 68 of file sig_pri.h.
Referenced by sig_pri_handle_subcmds(), and sig_pri_indicate().
#define SIG_PRI_AOC_GRANT_S (1 << 0) |
Definition at line 66 of file sig_pri.h.
Referenced by sig_pri_handle_subcmds(), and sig_pri_indicate().
#define SIG_PRI_DEBUG_DEFAULT 0 |
#define SIG_PRI_DEBUG_INTENSE |
Value:
(PRI_DEBUG_APDU | PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q931_STATE | PRI_DEBUG_Q921_STATE \ | PRI_DEBUG_Q921_RAW | PRI_DEBUG_Q921_DUMP)
Definition at line 53 of file sig_pri.h.
Referenced by handle_pri_debug().
#define SIG_PRI_DEBUG_NORMAL (PRI_DEBUG_APDU | PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q931_STATE | PRI_DEBUG_Q921_STATE) |
PRI debug message flags when normal PRI debugging is turned on at the command line.
Definition at line 49 of file sig_pri.h.
Referenced by handle_pri_debug().
#define SIG_PRI_MAX_CHANNELS 672 |
#define SIG_PRI_NUM_DCHANS 4 |
No more than 4 d-channels
Definition at line 148 of file sig_pri.h.
Referenced by pri_active_dchan_index(), pri_find_dchan(), pri_is_up(), sig_pri_init_pri(), and sig_pri_start_pri().
#define SRVST_BOTH (SRVST_NEAREND | SRVST_FAREND) |
#define SRVST_DBKEY "service-state" |
Persistent Service State.
Definition at line 167 of file sig_pri.h.
Referenced by destroy_all_channels().
#define SRVST_FAREND (1 << 1) |
SRVST_FAREND is used to indicate that the far end was taken out-of-service.
Definition at line 179 of file sig_pri.h.
Referenced by pri_check_restart().
#define SRVST_INITIALIZED 0 |
SRVST_INITIALIZED is used to indicate a channel being out-of-service The SRVST_INITIALIZED is mostly used maintain backwards compatibility but also may mean that the channel has not yet received a RESTART message. If a channel is out-of-service with this reason a RESTART message will result in the channel being put into service.
#define SRVST_NEAREND (1 << 0) |
SRVST_NEAREND is used to indicate that the near end was put out-of-service.
Definition at line 177 of file sig_pri.h.
Referenced by pri_check_restart().
#define SRVST_TYPE_OOS "O" |
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 1688 of file sig_pri.c.
References DCHAN_NOTINALARM, DCHAN_UP, sig_pri_span::dchanavail, and pri_find_dchan().
Referenced by my_handle_dchan_exception(), and prepare_pri().
01689 { 01690 pri->dchanavail[index] &= ~(DCHAN_NOTINALARM | DCHAN_UP); 01691 if (!before_start_pri) 01692 pri_find_dchan(pri); 01693 }
void pri_event_noalarm | ( | struct sig_pri_span * | pri, | |
int | index, | |||
int | before_start_pri | |||
) |
Definition at line 1695 of file sig_pri.c.
References DCHAN_NOTINALARM, sig_pri_span::dchanavail, and sig_pri_span::dchans.
Referenced by my_handle_dchan_exception(), and prepare_pri().
01696 { 01697 pri->dchanavail[index] |= DCHAN_NOTINALARM; 01698 if (!before_start_pri) 01699 pri_restart(pri->dchans[index]); 01700 }
int pri_is_up | ( | struct sig_pri_span * | pri | ) |
Definition at line 930 of file sig_pri.c.
References DCHAN_AVAILABLE, sig_pri_span::dchanavail, and SIG_PRI_NUM_DCHANS.
Referenced by pri_dchannel().
00931 { 00932 int x; 00933 for (x = 0; x < SIG_PRI_NUM_DCHANS; x++) { 00934 if (pri->dchanavail[x] == DCHAN_AVAILABLE) 00935 return 1; 00936 } 00937 return 0; 00938 }
int pri_maintenance_bservice | ( | struct pri * | pri, | |
struct sig_pri_chan * | p, | |||
int | changestatus | |||
) |
Definition at line 7463 of file sig_pri.c.
References sig_pri_chan::channel, PRI_SPAN, and PVT_TO_CHANNEL().
07464 { 07465 int channel = PVT_TO_CHANNEL(p); 07466 int span = PRI_SPAN(channel); 07467 07468 return pri_maintenance_service(pri, span, channel, changestatus); 07469 }
int pri_send_callrerouting_facility_exec | ( | struct sig_pri_chan * | p, | |
enum ast_channel_state | chanstate, | |||
const char * | destination, | |||
const char * | original, | |||
const char * | reason | |||
) |
Definition at line 7438 of file sig_pri.c.
References ast_log(), sig_pri_chan::call, LOG_DEBUG, sig_pri_span::pri, sig_pri_chan::pri, pri_grab(), pri_rel(), sig_pri_lock_private(), sig_pri_unlock_private(), and sig_pri_span::span.
Referenced by dahdi_send_callrerouting_facility_exec().
07439 { 07440 int res = -1; 07441 07442 sig_pri_lock_private(p); 07443 07444 if (!p->pri || !p->call) { 07445 ast_log(LOG_DEBUG, "Unable to find pri or call on channel!\n"); 07446 sig_pri_unlock_private(p); 07447 return -1; 07448 } 07449 07450 if (!pri_grab(p, p->pri)) { 07451 res = pri_callrerouting_facility(p->pri->pri, p->call, destination, original, reason); 07452 pri_rel(p->pri); 07453 } else { 07454 ast_log(LOG_DEBUG, "Unable to grab pri to send callrerouting facility on span %d!\n", p->pri->span); 07455 } 07456 07457 sig_pri_unlock_private(p); 07458 07459 return res; 07460 }
int pri_send_keypad_facility_exec | ( | struct sig_pri_chan * | p, | |
const char * | digits | |||
) |
Definition at line 7414 of file sig_pri.c.
References ast_debug, sig_pri_chan::call, sig_pri_span::pri, sig_pri_chan::pri, pri_grab(), pri_rel(), sig_pri_lock_private(), and sig_pri_unlock_private().
Referenced by dahdi_send_keypad_facility_exec().
07415 { 07416 sig_pri_lock_private(p); 07417 07418 if (!p->pri || !p->call) { 07419 ast_debug(1, "Unable to find pri or call on channel!\n"); 07420 sig_pri_unlock_private(p); 07421 return -1; 07422 } 07423 07424 if (!pri_grab(p, p->pri)) { 07425 pri_keypad_facility(p->pri->pri, p->call, digits); 07426 pri_rel(p->pri); 07427 } else { 07428 ast_debug(1, "Unable to grab pri to send keypad facility!\n"); 07429 sig_pri_unlock_private(p); 07430 return -1; 07431 } 07432 07433 sig_pri_unlock_private(p); 07434 07435 return 0; 07436 }
int sig_pri_answer | ( | struct sig_pri_chan * | p, | |
struct ast_channel * | ast | |||
) |
Definition at line 6763 of file sig_pri.c.
References ast_setstate(), AST_STATE_UP, sig_pri_chan::call, sig_pri_chan::call_level, sig_pri_chan::digital, sig_pri_span::pri, sig_pri_chan::pri, pri_grab(), pri_rel(), SIG_PRI_CALL_LEVEL_CONNECT, sig_pri_open_media(), and sig_pri_set_dialing().
Referenced by dahdi_answer().
06764 { 06765 int res = 0; 06766 /* Send a pri acknowledge */ 06767 if (!pri_grab(p, p->pri)) { 06768 #if defined(HAVE_PRI_AOC_EVENTS) 06769 if (p->aoc_s_request_invoke_id_valid) { 06770 /* if AOC-S was requested and the invoke id is still present on answer. That means 06771 * no AOC-S rate list was provided, so send a NULL response which will indicate that 06772 * AOC-S is not available */ 06773 pri_aoc_s_request_response_send(p->pri->pri, p->call, 06774 p->aoc_s_request_invoke_id, NULL); 06775 p->aoc_s_request_invoke_id_valid = 0; 06776 } 06777 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 06778 if (p->call_level < SIG_PRI_CALL_LEVEL_CONNECT) { 06779 p->call_level = SIG_PRI_CALL_LEVEL_CONNECT; 06780 } 06781 sig_pri_set_dialing(p, 0); 06782 sig_pri_open_media(p); 06783 res = pri_answer(p->pri->pri, p->call, 0, !p->digital); 06784 pri_rel(p->pri); 06785 } else { 06786 res = -1; 06787 } 06788 ast_setstate(ast, AST_STATE_UP); 06789 return res; 06790 }
int sig_pri_available | ( | struct sig_pri_chan ** | pvt, | |
int | is_specific_channel | |||
) |
Definition at line 6867 of file sig_pri.c.
References sig_pri_chan::pri, and sig_pri_available_check().
Referenced by available().
06868 { 06869 struct sig_pri_chan *p = *pvt; 06870 06871 if (!p->pri) { 06872 /* Something is wrong here. A PRI channel without the pri pointer? */ 06873 return 0; 06874 } 06875 06876 if ( 06877 #if defined(HAVE_PRI_CALL_WAITING) 06878 /* 06879 * Only do call waiting calls if we have any 06880 * call waiting call outstanding. We do not 06881 * want new calls to steal a B channel 06882 * freed for an earlier call waiting call. 06883 */ 06884 !p->pri->num_call_waiting_calls && 06885 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 06886 sig_pri_available_check(p)) { 06887 return 1; 06888 } 06889 06890 #if defined(HAVE_PRI_CALL_WAITING) 06891 if (!is_specific_channel) { 06892 struct sig_pri_chan *cw; 06893 06894 cw = sig_pri_cw_available(p->pri); 06895 if (cw) { 06896 /* We have a call waiting interface to use instead. */ 06897 *pvt = cw; 06898 return 1; 06899 } 06900 } 06901 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 06902 return 0; 06903 }
int sig_pri_call | ( | struct sig_pri_chan * | p, | |
struct ast_channel * | ast, | |||
char * | rdest, | |||
int | timeout, | |||
int | layer1 | |||
) |
Definition at line 6091 of file sig_pri.c.
References ast_channel::_state, ao2_ref, sig_pri_span::append_msn_to_user_tag, args, AST_APP_ARG, ast_app_parse_options(), ast_assert, ast_cc_get_monitor_by_recall_core_id(), ast_cc_is_recall(), ast_channel_get_device_name(), AST_CHANNEL_NAME, ast_copy_string(), AST_DECLARE_APP_ARGS, ast_free, ast_log(), AST_NONSTANDARD_APP_ARGS, ast_party_subaddress_init(), ast_setstate(), AST_STATE_DIALING, AST_STATE_DOWN, AST_STATE_RESERVED, ast_strdup, ast_strlen_zero(), ast_test_flag, ast_transfercapability2str(), ast_verb, sig_pri_chan::call, sig_pri_chan::call_level, ast_channel::caller, sig_pri_chan::channel, ast_channel::connected, sig_pri_chan::dialdest, sig_pri_span::dialplan, dialplan2str(), sig_pri_chan::digital, ext, sig_pri_span::facilityenable, sig_pri_chan::hidecallerid, sig_pri_chan::hidecalleridname, ast_party_caller::id, ast_party_connected_line::id, sig_pri_span::initial_user_tag, sig_pri_span::internationalprefix, IS_DIGITAL, sig_pri_span::localdialplan, LOG_DEBUG, LOG_ERROR, LOG_WARNING, monitor, ast_channel::name, ast_party_id::name, sig_pri_span::nationalprefix, sig_pri_span::nodetype, ast_party_id::number, ast_party_subaddress::odd_even_indicator, OPT_AOC_REQUEST, OPT_ARG_AOC_REQUEST, OPT_ARG_ARRAY_SIZE, OPT_ARG_KEYPAD, OPT_KEYPAD, OPT_REVERSE_CHARGE, sig_pri_chan::outgoing, sig_pri_chan::owner, pbx_builtin_getvar_helper(), ast_party_number::presentation, sig_pri_span::pri, sig_pri_chan::pri, pri_grab(), pri_rel(), PRI_TRANS_CAP_DIGITAL, sig_pri_chan::priexclusive, PVT_TO_CHANNEL(), S_COR, SIG_PRI_CALL_LEVEL_SETUP, sig_pri_call_opts, sig_pri_party_subaddress_from_ast(), sig_pri_redirecting_update(), sig_pri_set_dialing(), sig_pri_set_digital(), ast_party_subaddress::str, ast_party_number::str, ast_party_name::str, sig_pri_chan::stripmsd, ast_party_id::subaddress, ast_party_id::tag, ast_channel::transfercapability, ast_party_subaddress::type, sig_pri_chan::use_callingpres, sig_pri_chan::user_tag, ast_party_subaddress::valid, ast_party_number::valid, and ast_party_name::valid.
Referenced by dahdi_call().
06092 { 06093 char dest[256]; /* must be same length as p->dialdest */ 06094 struct ast_party_subaddress dialed_subaddress; /* Called subaddress */ 06095 struct pri_sr *sr; 06096 char *c, *l, *n, *s; 06097 #ifdef SUPPORT_USERUSER 06098 const char *useruser; 06099 #endif 06100 int core_id; 06101 int pridialplan; 06102 int dp_strip; 06103 int prilocaldialplan; 06104 int ldp_strip; 06105 int exclusive; 06106 #if defined(HAVE_PRI_SETUP_KEYPAD) 06107 const char *keypad; 06108 #endif /* defined(HAVE_PRI_SETUP_KEYPAD) */ 06109 AST_DECLARE_APP_ARGS(args, 06110 AST_APP_ARG(group); /* channel/group token */ 06111 AST_APP_ARG(ext); /* extension token */ 06112 AST_APP_ARG(opts); /* options token */ 06113 AST_APP_ARG(other); /* Any remining unused arguments */ 06114 ); 06115 struct ast_flags opts; 06116 char *opt_args[OPT_ARG_ARRAY_SIZE]; 06117 06118 ast_log(LOG_DEBUG, "CALLER NAME: %s NUM: %s\n", 06119 S_COR(ast->connected.id.name.valid, ast->connected.id.name.str, ""), 06120 S_COR(ast->connected.id.number.valid, ast->connected.id.number.str, "")); 06121 06122 if (!p->pri) { 06123 ast_log(LOG_ERROR, "Could not find pri on channel %d\n", p->channel); 06124 return -1; 06125 } 06126 06127 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { 06128 ast_log(LOG_WARNING, "sig_pri_call called on %s, neither down nor reserved\n", ast->name); 06129 return -1; 06130 } 06131 06132 p->dialdest[0] = '\0'; 06133 p->outgoing = 1; 06134 06135 ast_copy_string(dest, rdest, sizeof(dest)); 06136 AST_NONSTANDARD_APP_ARGS(args, dest, '/'); 06137 if (ast_app_parse_options(sig_pri_call_opts, &opts, opt_args, args.opts)) { 06138 /* General invalid option syntax. */ 06139 return -1; 06140 } 06141 06142 c = args.ext; 06143 if (!c) { 06144 c = ""; 06145 } 06146 06147 /* setup dialed_subaddress if found */ 06148 ast_party_subaddress_init(&dialed_subaddress); 06149 s = strchr(c, ':'); 06150 if (s) { 06151 *s = '\0'; 06152 s++; 06153 /* prefix */ 06154 /* 'n' = NSAP */ 06155 /* 'U' = odd, 'u'= even */ 06156 /* Default = NSAP */ 06157 switch (*s) { 06158 case 'U': 06159 dialed_subaddress.odd_even_indicator = 1; 06160 /* fall through */ 06161 case 'u': 06162 s++; 06163 dialed_subaddress.type = 2; 06164 break; 06165 case 'N': 06166 case 'n': 06167 s++; 06168 /* default already covered with ast_party_subaddress_init */ 06169 break; 06170 } 06171 dialed_subaddress.str = s; 06172 dialed_subaddress.valid = 1; 06173 s = NULL; 06174 } 06175 06176 l = NULL; 06177 n = NULL; 06178 if (!p->hidecallerid) { 06179 if (ast->connected.id.number.valid) { 06180 /* If we get to the end of this loop without breaking, there's no 06181 * calleridnum. This is done instead of testing for "unknown" or 06182 * the thousands of other ways that the calleridnum could be 06183 * invalid. */ 06184 for (l = ast->connected.id.number.str; l && *l; l++) { 06185 if (strchr("0123456789", *l)) { 06186 l = ast->connected.id.number.str; 06187 break; 06188 } 06189 } 06190 } else { 06191 l = NULL; 06192 } 06193 if (!p->hidecalleridname) { 06194 n = ast->connected.id.name.valid ? ast->connected.id.name.str : NULL; 06195 } 06196 } 06197 06198 if (strlen(c) < p->stripmsd) { 06199 ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd); 06200 return -1; 06201 } 06202 if (pri_grab(p, p->pri)) { 06203 ast_log(LOG_WARNING, "Failed to grab PRI!\n"); 06204 return -1; 06205 } 06206 if (!(p->call = pri_new_call(p->pri->pri))) { 06207 ast_log(LOG_WARNING, "Unable to create call on channel %d\n", p->channel); 06208 pri_rel(p->pri); 06209 return -1; 06210 } 06211 if (!(sr = pri_sr_new())) { 06212 ast_log(LOG_WARNING, "Failed to allocate setup request channel %d\n", p->channel); 06213 pri_destroycall(p->pri->pri, p->call); 06214 p->call = NULL; 06215 pri_rel(p->pri); 06216 return -1; 06217 } 06218 06219 sig_pri_set_digital(p, IS_DIGITAL(ast->transfercapability)); /* push up to parent for EC */ 06220 06221 #if defined(HAVE_PRI_CALL_WAITING) 06222 if (p->is_call_waiting) { 06223 /* 06224 * Indicate that this is a call waiting call. 06225 * i.e., Normal call but with no B channel. 06226 */ 06227 pri_sr_set_channel(sr, 0, 0, 1); 06228 } else 06229 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 06230 { 06231 /* Should the picked channel be used exclusively? */ 06232 if (p->priexclusive || p->pri->nodetype == PRI_NETWORK) { 06233 exclusive = 1; 06234 } else { 06235 exclusive = 0; 06236 } 06237 pri_sr_set_channel(sr, PVT_TO_CHANNEL(p), exclusive, 1); 06238 } 06239 06240 pri_sr_set_bearer(sr, p->digital ? PRI_TRANS_CAP_DIGITAL : ast->transfercapability, 06241 (p->digital ? -1 : layer1)); 06242 06243 if (p->pri->facilityenable) 06244 pri_facility_enable(p->pri->pri); 06245 06246 ast_verb(3, "Requested transfer capability: 0x%.2x - %s\n", ast->transfercapability, ast_transfercapability2str(ast->transfercapability)); 06247 dp_strip = 0; 06248 pridialplan = p->pri->dialplan - 1; 06249 if (pridialplan == -2 || pridialplan == -3) { /* compute dynamically */ 06250 if (strncmp(c + p->stripmsd, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) { 06251 if (pridialplan == -2) { 06252 dp_strip = strlen(p->pri->internationalprefix); 06253 } 06254 pridialplan = PRI_INTERNATIONAL_ISDN; 06255 } else if (strncmp(c + p->stripmsd, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) { 06256 if (pridialplan == -2) { 06257 dp_strip = strlen(p->pri->nationalprefix); 06258 } 06259 pridialplan = PRI_NATIONAL_ISDN; 06260 } else { 06261 pridialplan = PRI_LOCAL_ISDN; 06262 } 06263 } 06264 while (c[p->stripmsd] > '9' && c[p->stripmsd] != '*' && c[p->stripmsd] != '#') { 06265 switch (c[p->stripmsd]) { 06266 case 'U': 06267 pridialplan = (PRI_TON_UNKNOWN << 4) | (pridialplan & 0xf); 06268 break; 06269 case 'I': 06270 pridialplan = (PRI_TON_INTERNATIONAL << 4) | (pridialplan & 0xf); 06271 break; 06272 case 'N': 06273 pridialplan = (PRI_TON_NATIONAL << 4) | (pridialplan & 0xf); 06274 break; 06275 case 'L': 06276 pridialplan = (PRI_TON_NET_SPECIFIC << 4) | (pridialplan & 0xf); 06277 break; 06278 case 'S': 06279 pridialplan = (PRI_TON_SUBSCRIBER << 4) | (pridialplan & 0xf); 06280 break; 06281 case 'V': 06282 pridialplan = (PRI_TON_ABBREVIATED << 4) | (pridialplan & 0xf); 06283 break; 06284 case 'R': 06285 pridialplan = (PRI_TON_RESERVED << 4) | (pridialplan & 0xf); 06286 break; 06287 case 'u': 06288 pridialplan = PRI_NPI_UNKNOWN | (pridialplan & 0xf0); 06289 break; 06290 case 'e': 06291 pridialplan = PRI_NPI_E163_E164 | (pridialplan & 0xf0); 06292 break; 06293 case 'x': 06294 pridialplan = PRI_NPI_X121 | (pridialplan & 0xf0); 06295 break; 06296 case 'f': 06297 pridialplan = PRI_NPI_F69 | (pridialplan & 0xf0); 06298 break; 06299 case 'n': 06300 pridialplan = PRI_NPI_NATIONAL | (pridialplan & 0xf0); 06301 break; 06302 case 'p': 06303 pridialplan = PRI_NPI_PRIVATE | (pridialplan & 0xf0); 06304 break; 06305 case 'r': 06306 pridialplan = PRI_NPI_RESERVED | (pridialplan & 0xf0); 06307 break; 06308 default: 06309 if (isalpha(c[p->stripmsd])) { 06310 ast_log(LOG_WARNING, "Unrecognized pridialplan %s modifier: %c\n", 06311 c[p->stripmsd] > 'Z' ? "NPI" : "TON", c[p->stripmsd]); 06312 } 06313 break; 06314 } 06315 c++; 06316 } 06317 #if defined(HAVE_PRI_SETUP_KEYPAD) 06318 if (ast_test_flag(&opts, OPT_KEYPAD) 06319 && !ast_strlen_zero(opt_args[OPT_ARG_KEYPAD])) { 06320 /* We have a keypad facility digits option with digits. */ 06321 keypad = opt_args[OPT_ARG_KEYPAD]; 06322 pri_sr_set_keypad_digits(sr, keypad); 06323 } else { 06324 keypad = NULL; 06325 } 06326 if (!keypad || !ast_strlen_zero(c + p->stripmsd + dp_strip)) 06327 #endif /* defined(HAVE_PRI_SETUP_KEYPAD) */ 06328 { 06329 pri_sr_set_called(sr, c + p->stripmsd + dp_strip, pridialplan, s ? 1 : 0); 06330 } 06331 06332 #if defined(HAVE_PRI_SUBADDR) 06333 if (dialed_subaddress.valid) { 06334 struct pri_party_subaddress subaddress; 06335 06336 memset(&subaddress, 0, sizeof(subaddress)); 06337 sig_pri_party_subaddress_from_ast(&subaddress, &dialed_subaddress); 06338 pri_sr_set_called_subaddress(sr, &subaddress); 06339 } 06340 #endif /* defined(HAVE_PRI_SUBADDR) */ 06341 #if defined(HAVE_PRI_REVERSE_CHARGE) 06342 if (ast_test_flag(&opts, OPT_REVERSE_CHARGE)) { 06343 pri_sr_set_reversecharge(sr, PRI_REVERSECHARGE_REQUESTED); 06344 } 06345 #endif /* defined(HAVE_PRI_REVERSE_CHARGE) */ 06346 #if defined(HAVE_PRI_AOC_EVENTS) 06347 if (ast_test_flag(&opts, OPT_AOC_REQUEST) 06348 && !ast_strlen_zero(opt_args[OPT_ARG_AOC_REQUEST])) { 06349 if (strchr(opt_args[OPT_ARG_AOC_REQUEST], 's')) { 06350 pri_sr_set_aoc_charging_request(sr, PRI_AOC_REQUEST_S); 06351 } 06352 if (strchr(opt_args[OPT_ARG_AOC_REQUEST], 'd')) { 06353 pri_sr_set_aoc_charging_request(sr, PRI_AOC_REQUEST_D); 06354 } 06355 if (strchr(opt_args[OPT_ARG_AOC_REQUEST], 'e')) { 06356 pri_sr_set_aoc_charging_request(sr, PRI_AOC_REQUEST_E); 06357 } 06358 } 06359 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 06360 06361 /* Setup the user tag for party id's from this device for this call. */ 06362 if (p->pri->append_msn_to_user_tag) { 06363 snprintf(p->user_tag, sizeof(p->user_tag), "%s_%s", p->pri->initial_user_tag, 06364 p->pri->nodetype == PRI_NETWORK 06365 ? c + p->stripmsd + dp_strip 06366 : S_COR(ast->connected.id.number.valid, 06367 ast->connected.id.number.str, "")); 06368 } else { 06369 ast_copy_string(p->user_tag, p->pri->initial_user_tag, sizeof(p->user_tag)); 06370 } 06371 06372 /* 06373 * Replace the caller id tag from the channel creation 06374 * with the actual tag value. 06375 */ 06376 ast_free(ast->caller.id.tag); 06377 ast->caller.id.tag = ast_strdup(p->user_tag); 06378 06379 ldp_strip = 0; 06380 prilocaldialplan = p->pri->localdialplan - 1; 06381 if ((l != NULL) && (prilocaldialplan == -2 || prilocaldialplan == -3)) { /* compute dynamically */ 06382 if (strncmp(l, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) { 06383 if (prilocaldialplan == -2) { 06384 ldp_strip = strlen(p->pri->internationalprefix); 06385 } 06386 prilocaldialplan = PRI_INTERNATIONAL_ISDN; 06387 } else if (strncmp(l, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) { 06388 if (prilocaldialplan == -2) { 06389 ldp_strip = strlen(p->pri->nationalprefix); 06390 } 06391 prilocaldialplan = PRI_NATIONAL_ISDN; 06392 } else { 06393 prilocaldialplan = PRI_LOCAL_ISDN; 06394 } 06395 } 06396 if (l != NULL) { 06397 while (*l > '9' && *l != '*' && *l != '#') { 06398 switch (*l) { 06399 case 'U': 06400 prilocaldialplan = (PRI_TON_UNKNOWN << 4) | (prilocaldialplan & 0xf); 06401 break; 06402 case 'I': 06403 prilocaldialplan = (PRI_TON_INTERNATIONAL << 4) | (prilocaldialplan & 0xf); 06404 break; 06405 case 'N': 06406 prilocaldialplan = (PRI_TON_NATIONAL << 4) | (prilocaldialplan & 0xf); 06407 break; 06408 case 'L': 06409 prilocaldialplan = (PRI_TON_NET_SPECIFIC << 4) | (prilocaldialplan & 0xf); 06410 break; 06411 case 'S': 06412 prilocaldialplan = (PRI_TON_SUBSCRIBER << 4) | (prilocaldialplan & 0xf); 06413 break; 06414 case 'V': 06415 prilocaldialplan = (PRI_TON_ABBREVIATED << 4) | (prilocaldialplan & 0xf); 06416 break; 06417 case 'R': 06418 prilocaldialplan = (PRI_TON_RESERVED << 4) | (prilocaldialplan & 0xf); 06419 break; 06420 case 'u': 06421 prilocaldialplan = PRI_NPI_UNKNOWN | (prilocaldialplan & 0xf0); 06422 break; 06423 case 'e': 06424 prilocaldialplan = PRI_NPI_E163_E164 | (prilocaldialplan & 0xf0); 06425 break; 06426 case 'x': 06427 prilocaldialplan = PRI_NPI_X121 | (prilocaldialplan & 0xf0); 06428 break; 06429 case 'f': 06430 prilocaldialplan = PRI_NPI_F69 | (prilocaldialplan & 0xf0); 06431 break; 06432 case 'n': 06433 prilocaldialplan = PRI_NPI_NATIONAL | (prilocaldialplan & 0xf0); 06434 break; 06435 case 'p': 06436 prilocaldialplan = PRI_NPI_PRIVATE | (prilocaldialplan & 0xf0); 06437 break; 06438 case 'r': 06439 prilocaldialplan = PRI_NPI_RESERVED | (prilocaldialplan & 0xf0); 06440 break; 06441 default: 06442 if (isalpha(*l)) { 06443 ast_log(LOG_WARNING, 06444 "Unrecognized prilocaldialplan %s modifier: %c\n", 06445 *l > 'Z' ? "NPI" : "TON", *l); 06446 } 06447 break; 06448 } 06449 l++; 06450 } 06451 } 06452 pri_sr_set_caller(sr, l ? (l + ldp_strip) : NULL, n, prilocaldialplan, 06453 p->use_callingpres ? ast->connected.id.number.presentation : (l ? PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN : PRES_NUMBER_NOT_AVAILABLE)); 06454 06455 #if defined(HAVE_PRI_SUBADDR) 06456 if (ast->connected.id.subaddress.valid) { 06457 struct pri_party_subaddress subaddress; 06458 06459 memset(&subaddress, 0, sizeof(subaddress)); 06460 sig_pri_party_subaddress_from_ast(&subaddress, &ast->connected.id.subaddress); 06461 pri_sr_set_caller_subaddress(sr, &subaddress); 06462 } 06463 #endif /* defined(HAVE_PRI_SUBADDR) */ 06464 06465 sig_pri_redirecting_update(p, ast); 06466 06467 #ifdef SUPPORT_USERUSER 06468 /* User-user info */ 06469 useruser = pbx_builtin_getvar_helper(p->owner, "USERUSERINFO"); 06470 if (useruser) 06471 pri_sr_set_useruser(sr, useruser); 06472 #endif 06473 06474 #if defined(HAVE_PRI_CCSS) 06475 if (ast_cc_is_recall(ast, &core_id, sig_pri_cc_type_name)) { 06476 struct ast_cc_monitor *monitor; 06477 char device_name[AST_CHANNEL_NAME]; 06478 06479 /* This is a CC recall call. */ 06480 ast_channel_get_device_name(ast, device_name, sizeof(device_name)); 06481 monitor = ast_cc_get_monitor_by_recall_core_id(core_id, device_name); 06482 if (monitor) { 06483 struct sig_pri_cc_monitor_instance *instance; 06484 06485 instance = monitor->private_data; 06486 06487 /* If this fails then we have monitor instance ambiguity. */ 06488 ast_assert(p->pri == instance->pri); 06489 06490 if (pri_cc_call(p->pri->pri, instance->cc_id, p->call, sr)) { 06491 /* The CC recall call failed for some reason. */ 06492 ast_log(LOG_WARNING, "Unable to setup CC recall call to device %s\n", 06493 device_name); 06494 ao2_ref(monitor, -1); 06495 pri_destroycall(p->pri->pri, p->call); 06496 p->call = NULL; 06497 pri_rel(p->pri); 06498 pri_sr_free(sr); 06499 return -1; 06500 } 06501 ao2_ref(monitor, -1); 06502 } else { 06503 core_id = -1; 06504 } 06505 } else 06506 #endif /* defined(HAVE_PRI_CCSS) */ 06507 { 06508 core_id = -1; 06509 } 06510 if (core_id == -1 && pri_setup(p->pri->pri, p->call, sr)) { 06511 ast_log(LOG_WARNING, "Unable to setup call to %s (using %s)\n", 06512 c + p->stripmsd + dp_strip, dialplan2str(p->pri->dialplan)); 06513 pri_destroycall(p->pri->pri, p->call); 06514 p->call = NULL; 06515 pri_rel(p->pri); 06516 pri_sr_free(sr); 06517 return -1; 06518 } 06519 p->call_level = SIG_PRI_CALL_LEVEL_SETUP; 06520 pri_sr_free(sr); 06521 ast_setstate(ast, AST_STATE_DIALING); 06522 sig_pri_set_dialing(p, 1); 06523 pri_rel(p->pri); 06524 return 0; 06525 }
int sig_pri_cc_agent_callee_available | ( | struct ast_cc_agent * | agent | ) |
void sig_pri_cc_agent_destructor | ( | struct ast_cc_agent * | agent | ) |
int sig_pri_cc_agent_init | ( | struct ast_cc_agent * | agent, | |
struct sig_pri_chan * | pvt_chan | |||
) |
int sig_pri_cc_agent_party_b_free | ( | struct ast_cc_agent * | agent | ) |
void sig_pri_cc_agent_req_rsp | ( | struct ast_cc_agent * | agent, | |
enum ast_cc_agent_response_reason | reason | |||
) |
int sig_pri_cc_agent_start_monitoring | ( | struct ast_cc_agent * | agent | ) |
int sig_pri_cc_agent_start_offer_timer | ( | struct ast_cc_agent * | agent | ) |
int sig_pri_cc_agent_status_req | ( | struct ast_cc_agent * | agent | ) |
int sig_pri_cc_agent_stop_offer_timer | ( | struct ast_cc_agent * | agent | ) |
int sig_pri_cc_agent_stop_ringing | ( | struct ast_cc_agent * | agent | ) |
int sig_pri_cc_monitor_cancel_available_timer | ( | struct ast_cc_monitor * | monitor, | |
int * | sched_id | |||
) |
void sig_pri_cc_monitor_destructor | ( | void * | monitor_pvt | ) |
int sig_pri_cc_monitor_req_cc | ( | struct ast_cc_monitor * | monitor, | |
int * | available_timer_id | |||
) |
int sig_pri_cc_monitor_status_rsp | ( | struct ast_cc_monitor * | monitor, | |
enum ast_device_state | devstate | |||
) |
int sig_pri_cc_monitor_suspend | ( | struct ast_cc_monitor * | monitor | ) |
int sig_pri_cc_monitor_unsuspend | ( | struct ast_cc_monitor * | monitor | ) |
void sig_pri_chan_alarm_notify | ( | struct sig_pri_chan * | p, | |
int | noalarm | |||
) |
Definition at line 7296 of file sig_pri.c.
References ast_channel::_softhangup, ast_log(), AST_SOFTHANGUP_DEV, sig_pri_chan::call, LOG_WARNING, sig_pri_chan::owner, sig_pri_span::pri, sig_pri_chan::pri, pri_grab(), pri_rel(), and sig_pri_set_alarm().
Referenced by dahdi_handle_event(), and handle_init_event().
07297 { 07298 sig_pri_set_alarm(p, !noalarm); 07299 if (!noalarm) { 07300 if (!p->pri || !p->pri->pri || (pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0)) { 07301 /* T309 is not enabled : hangup calls when alarm occurs */ 07302 if (p->call) { 07303 if (p->pri && p->pri->pri) { 07304 if (!pri_grab(p, p->pri)) { 07305 pri_hangup(p->pri->pri, p->call, -1); 07306 pri_destroycall(p->pri->pri, p->call); 07307 p->call = NULL; 07308 pri_rel(p->pri); 07309 } else 07310 ast_log(LOG_WARNING, "Failed to grab PRI!\n"); 07311 } else 07312 ast_log(LOG_WARNING, "The PRI Call has not been destroyed\n"); 07313 } 07314 if (p->owner) 07315 p->owner->_softhangup |= AST_SOFTHANGUP_DEV; 07316 } 07317 } 07318 }
void sig_pri_chan_delete | ( | struct sig_pri_chan * | doomed | ) |
Delete the sig_pri private channel structure.
doomed | sig_pri private channel structure to delete. |
Definition at line 7348 of file sig_pri.c.
References ast_free.
Referenced by destroy_dahdi_pvt().
07349 { 07350 ast_free(doomed); 07351 }
struct sig_pri_chan* sig_pri_chan_new | ( | void * | pvt_data, | |
struct sig_pri_callback * | callback, | |||
struct sig_pri_span * | pri, | |||
int | logicalspan, | |||
int | channo, | |||
int | trunkgroup | |||
) |
Definition at line 7320 of file sig_pri.c.
References ast_calloc, and sig_pri_chan::pri.
07321 { 07322 struct sig_pri_chan *p; 07323 07324 p = ast_calloc(1, sizeof(*p)); 07325 if (!p) 07326 return p; 07327 07328 p->logicalspan = logicalspan; 07329 p->prioffset = channo; 07330 p->mastertrunkgroup = trunkgroup; 07331 07332 p->calls = callback; 07333 p->chan_pvt = pvt_data; 07334 07335 p->pri = pri; 07336 07337 return p; 07338 }
void sig_pri_cli_show_span | ( | int | fd, | |
int * | dchannels, | |||
struct sig_pri_span * | pri | |||
) |
Definition at line 7384 of file sig_pri.c.
References ast_cli(), ast_mutex_lock, ast_mutex_unlock, build_status(), DAHDI_OVERLAPDIAL_INCOMING, sig_pri_span::dchanavail, sig_pri_span::dchans, free, sig_pri_span::lock, sig_pri_span::overlapdial, sig_pri_span::pri, sig_pri_chan::pri, pri_order(), and status.
Referenced by handle_pri_show_span().
07385 { 07386 int x; 07387 char status[256]; 07388 07389 for (x = 0; x < SIG_PRI_NUM_DCHANS; x++) { 07390 if (pri->dchans[x]) { 07391 #ifdef PRI_DUMP_INFO_STR 07392 char *info_str = NULL; 07393 #endif 07394 ast_cli(fd, "%s D-channel: %d\n", pri_order(x), dchannels[x]); 07395 build_status(status, sizeof(status), pri->dchanavail[x], pri->dchans[x] == pri->pri); 07396 ast_cli(fd, "Status: %s\n", status); 07397 ast_mutex_lock(&pri->lock); 07398 #ifdef PRI_DUMP_INFO_STR 07399 info_str = pri_dump_info_str(pri->pri); 07400 if (info_str) { 07401 ast_cli(fd, "%s", info_str); 07402 free(info_str); 07403 } 07404 #else 07405 pri_dump_info(pri->pri); 07406 #endif 07407 ast_mutex_unlock(&pri->lock); 07408 ast_cli(fd, "Overlap Recv: %s\n\n", (pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)?"Yes":"No"); 07409 ast_cli(fd, "\n"); 07410 } 07411 } 07412 }
void sig_pri_cli_show_spans | ( | int | fd, | |
int | span, | |||
struct sig_pri_span * | pri | |||
) |
Definition at line 7372 of file sig_pri.c.
References ast_cli(), build_status(), sig_pri_span::dchanavail, sig_pri_span::dchans, sig_pri_span::pri, sig_pri_chan::pri, and status.
Referenced by handle_pri_show_spans().
07373 { 07374 char status[256]; 07375 int x; 07376 for (x = 0; x < SIG_PRI_NUM_DCHANS; x++) { 07377 if (pri->dchans[x]) { 07378 build_status(status, sizeof(status), pri->dchanavail[x], pri->dchans[x] == pri->pri); 07379 ast_cli(fd, "PRI span %d/%d: %s\n", span, x, status); 07380 } 07381 } 07382 }
int sig_pri_digit_begin | ( | struct sig_pri_chan * | pvt, | |
struct ast_channel * | ast, | |||
char | digit | |||
) |
Definition at line 6907 of file sig_pri.c.
References ast_channel::_state, ast_debug, ast_log(), AST_STATE_DIALING, sig_pri_chan::call, sig_pri_chan::call_level, sig_pri_chan::dialdest, LOG_WARNING, sig_pri_span::pri, sig_pri_chan::pri, pri_grab(), pri_rel(), SIG_PRI_CALL_LEVEL_CONNECT, SIG_PRI_CALL_LEVEL_OVERLAP, SIG_PRI_CALL_LEVEL_PROCEEDING, and sig_pri_span::span.
Referenced by dahdi_digit_begin().
06908 { 06909 if (ast->_state == AST_STATE_DIALING) { 06910 if (pvt->call_level < SIG_PRI_CALL_LEVEL_OVERLAP) { 06911 unsigned int len; 06912 06913 len = strlen(pvt->dialdest); 06914 if (len < sizeof(pvt->dialdest) - 1) { 06915 ast_debug(1, "Queueing digit '%c' since setup_ack not yet received\n", 06916 digit); 06917 pvt->dialdest[len++] = digit; 06918 pvt->dialdest[len] = '\0'; 06919 } else { 06920 ast_log(LOG_WARNING, 06921 "Span %d: Deferred digit buffer overflow for digit '%c'.\n", 06922 pvt->pri->span, digit); 06923 } 06924 return 0; 06925 } 06926 if (pvt->call_level < SIG_PRI_CALL_LEVEL_PROCEEDING) { 06927 if (!pri_grab(pvt, pvt->pri)) { 06928 pri_information(pvt->pri->pri, pvt->call, digit); 06929 pri_rel(pvt->pri); 06930 } else { 06931 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", pvt->pri->span); 06932 } 06933 return 0; 06934 } 06935 if (pvt->call_level < SIG_PRI_CALL_LEVEL_CONNECT) { 06936 ast_log(LOG_WARNING, 06937 "Span %d: Digit '%c' may be ignored by peer. (Call level:%d)\n", 06938 pvt->pri->span, digit, pvt->call_level); 06939 } 06940 } 06941 return 1; 06942 }
void sig_pri_extract_called_num_subaddr | ( | struct sig_pri_chan * | p, | |
const char * | rdest, | |||
char * | called, | |||
size_t | called_buff_size | |||
) |
Extract the called number and subaddress from the dial string.
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 6012 of file sig_pri.c.
References args, AST_APP_ARG, AST_DECLARE_APP_ARGS, AST_NONSTANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), ext, and sig_pri_chan::stripmsd.
Referenced by dahdi_request().
06013 { 06014 char *dial; 06015 char *number; 06016 char *subaddr; 06017 AST_DECLARE_APP_ARGS(args, 06018 AST_APP_ARG(group); /* channel/group token */ 06019 AST_APP_ARG(ext); /* extension token */ 06020 //AST_APP_ARG(opts); /* options token */ 06021 AST_APP_ARG(other); /* Any remining unused arguments */ 06022 ); 06023 06024 /* Get private copy of dial string and break it up. */ 06025 dial = ast_strdupa(rdest); 06026 AST_NONSTANDARD_APP_ARGS(args, dial, '/'); 06027 06028 number = args.ext; 06029 if (!number) { 06030 number = ""; 06031 } 06032 06033 /* Find and extract dialed_subaddress */ 06034 subaddr = strchr(number, ':'); 06035 if (subaddr) { 06036 *subaddr++ = '\0'; 06037 06038 /* Skip subaddress type prefix. */ 06039 switch (*subaddr) { 06040 case 'U': 06041 case 'u': 06042 case 'N': 06043 case 'n': 06044 ++subaddr; 06045 break; 06046 default: 06047 break; 06048 } 06049 } 06050 06051 /* Skip type-of-number/dial-plan prefix characters. */ 06052 if (strlen(number) < p->stripmsd) { 06053 number = ""; 06054 } else { 06055 number += p->stripmsd; 06056 while (isalpha(*number)) { 06057 ++number; 06058 } 06059 } 06060 06061 /* Fill buffer with extracted number and subaddress. */ 06062 if (ast_strlen_zero(subaddr)) { 06063 /* Put in called number only since there is no subaddress. */ 06064 snprintf(called, called_buff_size, "%s", number); 06065 } else { 06066 /* Put in called number and subaddress. */ 06067 snprintf(called, called_buff_size, "%s:%s", number, subaddr); 06068 } 06069 }
void sig_pri_fixup | ( | struct ast_channel * | oldchan, | |
struct ast_channel * | newchan, | |||
struct sig_pri_chan * | pchan | |||
) |
int sig_pri_hangup | ( | struct sig_pri_chan * | p, | |
struct ast_channel * | ast | |||
) |
Definition at line 5912 of file sig_pri.c.
References sig_pri_chan::alreadyhungup, ast_atomic_fetchadd_int(), ast_log(), sig_pri_chan::call, sig_pri_chan::call_level, cause, sig_pri_chan::channel, sig_pri_chan::cid_name, sig_pri_chan::cid_num, sig_pri_chan::cid_subaddr, sig_pri_chan::exten, ast_channel::hangupcause, LOG_DEBUG, LOG_WARNING, sig_pri_chan::outgoing, sig_pri_chan::owner, pbx_builtin_getvar_helper(), sig_pri_span::pri, sig_pri_chan::pri, pri_grab(), pri_rel(), sig_pri_chan::progress, SIG_PRI_CALL_LEVEL_IDLE, sig_pri_set_dialing(), sig_pri_set_digital(), sig_pri_span_devstate_changed(), sig_pri_span::span, ast_channel::tech_pvt, and sig_pri_chan::user_tag.
Referenced by dahdi_hangup().
05913 { 05914 int res; 05915 #ifdef SUPPORT_USERUSER 05916 const char *useruser = pbx_builtin_getvar_helper(ast, "USERUSERINFO"); 05917 #endif 05918 05919 ast_log(LOG_DEBUG, "%s %d\n", __FUNCTION__, p->channel); 05920 if (!ast->tech_pvt) { 05921 ast_log(LOG_WARNING, "Asked to hangup channel not connected\n"); 05922 return 0; 05923 } 05924 05925 p->owner = NULL; 05926 p->outgoing = 0; 05927 sig_pri_set_digital(p, 0); /* push up to parent for EC*/ 05928 #if defined(HAVE_PRI_CALL_WAITING) 05929 if (p->is_call_waiting) { 05930 p->is_call_waiting = 0; 05931 ast_atomic_fetchadd_int(&p->pri->num_call_waiting_calls, -1); 05932 } 05933 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 05934 p->call_level = SIG_PRI_CALL_LEVEL_IDLE; 05935 p->progress = 0; 05936 p->cid_num[0] = '\0'; 05937 p->cid_subaddr[0] = '\0'; 05938 p->cid_name[0] = '\0'; 05939 p->user_tag[0] = '\0'; 05940 p->exten[0] = '\0'; 05941 sig_pri_set_dialing(p, 0); 05942 05943 /* Make sure we have a call (or REALLY have a call in the case of a PRI) */ 05944 if (!pri_grab(p, p->pri)) { 05945 if (p->call) { 05946 if (p->alreadyhungup) { 05947 ast_log(LOG_DEBUG, "Already hungup... Calling hangup once, and clearing call\n"); 05948 05949 #ifdef SUPPORT_USERUSER 05950 pri_call_set_useruser(p->call, useruser); 05951 #endif 05952 05953 #if defined(HAVE_PRI_AOC_EVENTS) 05954 if (p->holding_aoce) { 05955 pri_aoc_e_send(p->pri->pri, p->call, &p->aoc_e); 05956 } 05957 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 05958 pri_hangup(p->pri->pri, p->call, -1); 05959 p->call = NULL; 05960 } else { 05961 const char *cause = pbx_builtin_getvar_helper(ast,"PRI_CAUSE"); 05962 int icause = ast->hangupcause ? ast->hangupcause : -1; 05963 ast_log(LOG_DEBUG, "Not yet hungup... Calling hangup once with icause, and clearing call\n"); 05964 05965 #ifdef SUPPORT_USERUSER 05966 pri_call_set_useruser(p->call, useruser); 05967 #endif 05968 05969 p->alreadyhungup = 1; 05970 if (cause) { 05971 if (atoi(cause)) 05972 icause = atoi(cause); 05973 } 05974 #if defined(HAVE_PRI_AOC_EVENTS) 05975 if (p->holding_aoce) { 05976 pri_aoc_e_send(p->pri->pri, p->call, &p->aoc_e); 05977 } 05978 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 05979 pri_hangup(p->pri->pri, p->call, icause); 05980 } 05981 } 05982 sig_pri_span_devstate_changed(p->pri); 05983 pri_rel(p->pri); 05984 res = 0; 05985 } else { 05986 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->pri->span); 05987 res = -1; 05988 } 05989 05990 #if defined(HAVE_PRI_AOC_EVENTS) 05991 p->aoc_s_request_invoke_id_valid = 0; 05992 p->holding_aoce = 0; 05993 p->waiting_for_aoce = 0; 05994 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 05995 ast->tech_pvt = NULL; 05996 return res; 05997 }
int sig_pri_indicate | ( | struct sig_pri_chan * | p, | |
struct ast_channel * | chan, | |||
int | condition, | |||
const void * | data, | |||
size_t | datalen | |||
) |
Definition at line 6527 of file sig_pri.c.
References ast_channel::_softhangup, ast_channel::_state, AST_AOC_D, ast_aoc_decode(), ast_aoc_destroy_decoded(), AST_AOC_E, ast_aoc_get_msg_type(), ast_aoc_get_termination_request(), AST_AOC_REQUEST, AST_AOC_S, AST_CAUSE_NORMAL_CLEARING, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_USER_BUSY, AST_CONTROL_AOC, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HOLD, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_REDIRECTING, AST_CONTROL_RINGING, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, ast_debug, ast_log(), ast_moh_start(), ast_moh_stop(), ast_setstate(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, sig_pri_chan::call, sig_pri_chan::call_level, ast_channel::connected, sig_pri_chan::digital, ast_channel::hangupcause, ast_party_connected_line::id, LOG_DEBUG, LOG_WARNING, sig_pri_chan::mohinterpret, ast_channel::name, sig_pri_chan::no_b_channel, sig_pri_chan::outgoing, sig_pri_span::pri, sig_pri_chan::pri, pri_grab(), pri_rel(), sig_pri_chan::priindication_oob, sig_pri_chan::prioffset, sig_pri_chan::progress, PVT_TO_CHANNEL(), SIG_PRI_AOC_GRANT_D, SIG_PRI_AOC_GRANT_E, SIG_PRI_AOC_GRANT_S, SIG_PRI_CALL_LEVEL_ALERTING, SIG_PRI_CALL_LEVEL_PROCEEDING, sig_pri_party_id_from_ast(), sig_pri_play_tone(), sig_pri_redirecting_update(), sig_pri_set_dialing(), sig_pri_set_digital(), SIG_PRI_TONE_BUSY, SIG_PRI_TONE_CONGESTION, SIG_PRI_TONE_RINGTONE, and sig_pri_span::span.
Referenced by dahdi_indicate().
06528 { 06529 int res = -1; 06530 06531 switch (condition) { 06532 case AST_CONTROL_BUSY: 06533 if (p->priindication_oob || p->no_b_channel) { 06534 chan->hangupcause = AST_CAUSE_USER_BUSY; 06535 chan->_softhangup |= AST_SOFTHANGUP_DEV; 06536 res = 0; 06537 break; 06538 } 06539 res = sig_pri_play_tone(p, SIG_PRI_TONE_BUSY); 06540 if (p->call_level < SIG_PRI_CALL_LEVEL_ALERTING && !p->outgoing) { 06541 chan->hangupcause = AST_CAUSE_USER_BUSY; 06542 p->progress = 1;/* No need to send plain PROGRESS after this. */ 06543 if (p->pri && p->pri->pri) { 06544 if (!pri_grab(p, p->pri)) { 06545 #ifdef HAVE_PRI_PROG_W_CAUSE 06546 pri_progress_with_cause(p->pri->pri, p->call, PVT_TO_CHANNEL(p), 1, chan->hangupcause); 06547 #else 06548 pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1); 06549 #endif 06550 pri_rel(p->pri); 06551 } else { 06552 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->pri->span); 06553 } 06554 } 06555 } 06556 break; 06557 case AST_CONTROL_RINGING: 06558 if (p->call_level < SIG_PRI_CALL_LEVEL_ALERTING && !p->outgoing) { 06559 p->call_level = SIG_PRI_CALL_LEVEL_ALERTING; 06560 if (p->pri && p->pri->pri) { 06561 if (!pri_grab(p, p->pri)) { 06562 pri_acknowledge(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 06563 p->no_b_channel || p->digital ? 0 : 1); 06564 pri_rel(p->pri); 06565 } else { 06566 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->pri->span); 06567 } 06568 } 06569 } 06570 res = sig_pri_play_tone(p, SIG_PRI_TONE_RINGTONE); 06571 if (chan->_state != AST_STATE_UP) { 06572 if (chan->_state != AST_STATE_RING) 06573 ast_setstate(chan, AST_STATE_RINGING); 06574 } 06575 break; 06576 case AST_CONTROL_PROCEEDING: 06577 ast_debug(1,"Received AST_CONTROL_PROCEEDING on %s\n",chan->name); 06578 if (p->call_level < SIG_PRI_CALL_LEVEL_PROCEEDING && !p->outgoing) { 06579 p->call_level = SIG_PRI_CALL_LEVEL_PROCEEDING; 06580 if (p->pri && p->pri->pri) { 06581 if (!pri_grab(p, p->pri)) { 06582 pri_proceeding(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 06583 p->no_b_channel || p->digital ? 0 : 1); 06584 if (!p->no_b_channel && !p->digital) { 06585 sig_pri_set_dialing(p, 0); 06586 } 06587 pri_rel(p->pri); 06588 } else { 06589 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->pri->span); 06590 } 06591 } 06592 } 06593 /* don't continue in ast_indicate */ 06594 res = 0; 06595 break; 06596 case AST_CONTROL_PROGRESS: 06597 ast_debug(1,"Received AST_CONTROL_PROGRESS on %s\n",chan->name); 06598 sig_pri_set_digital(p, 0); /* Digital-only calls isn't allowing any inband progress messages */ 06599 if (!p->progress && p->call_level < SIG_PRI_CALL_LEVEL_ALERTING && !p->outgoing 06600 && !p->no_b_channel) { 06601 p->progress = 1;/* No need to send plain PROGRESS again. */ 06602 if (p->pri && p->pri->pri) { 06603 if (!pri_grab(p, p->pri)) { 06604 #ifdef HAVE_PRI_PROG_W_CAUSE 06605 pri_progress_with_cause(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1, -1); /* no cause at all */ 06606 #else 06607 pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1); 06608 #endif 06609 pri_rel(p->pri); 06610 } else { 06611 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->pri->span); 06612 } 06613 } 06614 } 06615 /* don't continue in ast_indicate */ 06616 res = 0; 06617 break; 06618 case AST_CONTROL_CONGESTION: 06619 if (p->priindication_oob || p->no_b_channel) { 06620 /* There are many cause codes that generate an AST_CONTROL_CONGESTION. */ 06621 switch (chan->hangupcause) { 06622 case AST_CAUSE_USER_BUSY: 06623 case AST_CAUSE_NORMAL_CLEARING: 06624 case 0:/* Cause has not been set. */ 06625 /* Supply a more appropriate cause. */ 06626 chan->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 06627 break; 06628 default: 06629 break; 06630 } 06631 chan->_softhangup |= AST_SOFTHANGUP_DEV; 06632 res = 0; 06633 break; 06634 } 06635 res = sig_pri_play_tone(p, SIG_PRI_TONE_CONGESTION); 06636 if (p->call_level < SIG_PRI_CALL_LEVEL_ALERTING && !p->outgoing) { 06637 /* There are many cause codes that generate an AST_CONTROL_CONGESTION. */ 06638 switch (chan->hangupcause) { 06639 case AST_CAUSE_USER_BUSY: 06640 case AST_CAUSE_NORMAL_CLEARING: 06641 case 0:/* Cause has not been set. */ 06642 /* Supply a more appropriate cause. */ 06643 chan->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 06644 break; 06645 default: 06646 break; 06647 } 06648 p->progress = 1;/* No need to send plain PROGRESS after this. */ 06649 if (p->pri && p->pri->pri) { 06650 if (!pri_grab(p, p->pri)) { 06651 #ifdef HAVE_PRI_PROG_W_CAUSE 06652 pri_progress_with_cause(p->pri->pri, p->call, PVT_TO_CHANNEL(p), 1, chan->hangupcause); 06653 #else 06654 pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1); 06655 #endif 06656 pri_rel(p->pri); 06657 } else { 06658 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->pri->span); 06659 } 06660 } 06661 } 06662 break; 06663 case AST_CONTROL_HOLD: 06664 if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) { 06665 if (!pri_grab(p, p->pri)) { 06666 res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_HOLD); 06667 pri_rel(p->pri); 06668 } else { 06669 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->pri->span); 06670 } 06671 } else 06672 ast_moh_start(chan, data, p->mohinterpret); 06673 break; 06674 case AST_CONTROL_UNHOLD: 06675 if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) { 06676 if (!pri_grab(p, p->pri)) { 06677 res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_RETRIEVAL); 06678 pri_rel(p->pri); 06679 } 06680 } else 06681 ast_moh_stop(chan); 06682 break; 06683 case AST_CONTROL_SRCUPDATE: 06684 res = 0; 06685 break; 06686 case -1: 06687 res = sig_pri_play_tone(p, -1); 06688 break; 06689 case AST_CONTROL_CONNECTED_LINE: 06690 ast_debug(1, "Received AST_CONTROL_CONNECTED_LINE on %s\n", chan->name); 06691 if (p->pri && !pri_grab(p, p->pri)) { 06692 struct pri_party_connected_line connected; 06693 06694 memset(&connected, 0, sizeof(connected)); 06695 sig_pri_party_id_from_ast(&connected.id, &chan->connected.id); 06696 06697 pri_connected_line_update(p->pri->pri, p->call, &connected); 06698 pri_rel(p->pri); 06699 } 06700 break; 06701 case AST_CONTROL_REDIRECTING: 06702 ast_debug(1, "Received AST_CONTROL_REDIRECTING on %s\n", chan->name); 06703 if (p->pri && !pri_grab(p, p->pri)) { 06704 sig_pri_redirecting_update(p, chan); 06705 pri_rel(p->pri); 06706 } 06707 break; 06708 case AST_CONTROL_AOC: 06709 #if defined(HAVE_PRI_AOC_EVENTS) 06710 { 06711 struct ast_aoc_decoded *decoded 06712 = ast_aoc_decode((struct ast_aoc_encoded *) data, datalen, chan); 06713 ast_debug(1, "Received AST_CONTROL_AOC on %s\n", chan->name); 06714 if (decoded && p->pri && !pri_grab(p, p->pri)) { 06715 switch (ast_aoc_get_msg_type(decoded)) { 06716 case AST_AOC_S: 06717 if (p->pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_S) { 06718 sig_pri_aoc_s_from_ast(p, decoded); 06719 } 06720 break; 06721 case AST_AOC_D: 06722 if (p->pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_D) { 06723 sig_pri_aoc_d_from_ast(p, decoded); 06724 } 06725 break; 06726 case AST_AOC_E: 06727 if (p->pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_E) { 06728 sig_pri_aoc_e_from_ast(p, decoded); 06729 } 06730 /* if hangup was delayed for this AOC-E msg, waiting_for_aoc 06731 * will be set. A hangup is already occuring via a timeout during 06732 * this delay. Instead of waiting for that timeout to occur, go ahead 06733 * and initiate the softhangup since the delay is no longer necessary */ 06734 if (p->waiting_for_aoce) { 06735 p->waiting_for_aoce = 0; 06736 ast_log(LOG_DEBUG, 06737 "Received final AOC-E msg, continue with hangup on %s\n", 06738 chan->name); 06739 ast_softhangup_nolock(chan, AST_SOFTHANGUP_DEV); 06740 } 06741 break; 06742 case AST_AOC_REQUEST: 06743 /* We do not pass through AOC requests, So unless this 06744 * is an AOC termination request it will be ignored */ 06745 if (ast_aoc_get_termination_request(decoded)) { 06746 pri_hangup(p->pri->pri, p->call, -1); 06747 } 06748 break; 06749 default: 06750 break; 06751 } 06752 pri_rel(p->pri); 06753 } 06754 ast_aoc_destroy_decoded(decoded); 06755 } 06756 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 06757 break; 06758 } 06759 06760 return res; 06761 }
void sig_pri_init_pri | ( | struct sig_pri_span * | pri | ) |
Definition at line 5899 of file sig_pri.c.
References ast_mutex_init, AST_PTHREADT_NULL, and SIG_PRI_NUM_DCHANS.
Referenced by load_module().
05900 { 05901 int i; 05902 05903 memset(pri, 0, sizeof(*pri)); 05904 05905 ast_mutex_init(&pri->lock); 05906 05907 pri->master = AST_PTHREADT_NULL; 05908 for (i = 0; i < SIG_PRI_NUM_DCHANS; i++) 05909 pri->fds[i] = -1; 05910 }
int sig_pri_load | ( | const char * | cc_type_name | ) |
Load the sig_pri submodule.
cc_type_name | CC type name to use when looking up agent/monitor. |
0 | on success. | |
-1 | on error. |
Definition at line 8084 of file sig_pri.c.
References ao2_container_alloc.
Referenced by load_module().
08085 { 08086 #if defined(HAVE_PRI_CCSS) 08087 sig_pri_cc_type_name = cc_type_name; 08088 sig_pri_cc_monitors = ao2_container_alloc(37, sig_pri_cc_monitor_instance_hash_fn, 08089 sig_pri_cc_monitor_instance_cmp_fn); 08090 if (!sig_pri_cc_monitors) { 08091 return -1; 08092 } 08093 #endif /* defined(HAVE_PRI_CCSS) */ 08094 return 0; 08095 }
struct ast_channel* sig_pri_request | ( | struct sig_pri_chan * | p, | |
enum sig_pri_law | law, | |||
const struct ast_channel * | requestor, | |||
int | transfercapability | |||
) |
Definition at line 916 of file sig_pri.c.
References ast_log(), AST_STATE_RESERVED, sig_pri_chan::channel, sig_pri_chan::exten, LOG_DEBUG, sig_pri_chan::outgoing, and sig_pri_new_ast_channel().
Referenced by dahdi_request(), and pri_dchannel().
00917 { 00918 struct ast_channel *ast; 00919 00920 ast_log(LOG_DEBUG, "%s %d\n", __FUNCTION__, p->channel); 00921 00922 p->outgoing = 1; 00923 ast = sig_pri_new_ast_channel(p, AST_STATE_RESERVED, law, transfercapability, p->exten, requestor); 00924 if (!ast) { 00925 p->outgoing = 0; 00926 } 00927 return ast; 00928 }
int sig_pri_start_pri | ( | struct sig_pri_span * | pri | ) |
Definition at line 7118 of file sig_pri.c.
References ARRAY_LEN, AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_MWI, ast_event_subscribe(), ast_event_unsubscribe(), ast_log(), ast_mutex_init, ast_str_alloca, ast_str_buffer(), ast_str_set(), ast_strip(), ast_strlen_zero(), sig_pri_span::dchans, sig_pri_span::enable_service_message_support, sig_pri_span::fds, HAVE_PRI_SERVICE_MESSAGES, sig_pri_span::lock, LOG_ERROR, sig_pri_span::nodetype, sig_pri_span::sig, SIG_BRI, SIG_BRI_PTMP, SIG_PRI_NUM_DCHANS, sig_pri_sort_pri_chans(), sig_pri_span::span, strsep(), and sig_pri_span::switchtype.
Referenced by setup_dahdi_int().
07119 { 07120 int x; 07121 int i; 07122 #if defined(HAVE_PRI_MWI) 07123 char *saveptr; 07124 char *mbox_number; 07125 char *mbox_context; 07126 struct ast_str *mwi_description = ast_str_alloca(64); 07127 #endif /* defined(HAVE_PRI_MWI) */ 07128 07129 #if defined(HAVE_PRI_MWI) 07130 /* Prepare the mbox[] for use. */ 07131 for (i = 0; i < ARRAY_LEN(pri->mbox); ++i) { 07132 if (pri->mbox[i].sub) { 07133 pri->mbox[i].sub = ast_event_unsubscribe(pri->mbox[i].sub); 07134 } 07135 } 07136 #endif /* defined(HAVE_PRI_MWI) */ 07137 07138 ast_mutex_init(&pri->lock); 07139 sig_pri_sort_pri_chans(pri); 07140 07141 #if defined(HAVE_PRI_MWI) 07142 /* 07143 * Split the mwi_mailboxes configuration string into the mbox[]: 07144 * mailbox_number[@context]{,mailbox_number[@context]} 07145 */ 07146 i = 0; 07147 saveptr = pri->mwi_mailboxes; 07148 while (i < ARRAY_LEN(pri->mbox)) { 07149 mbox_number = strsep(&saveptr, ","); 07150 if (!mbox_number) { 07151 break; 07152 } 07153 /* Split the mailbox_number and context */ 07154 mbox_context = strchr(mbox_number, '@'); 07155 if (mbox_context) { 07156 *mbox_context++ = '\0'; 07157 mbox_context = ast_strip(mbox_context); 07158 } 07159 mbox_number = ast_strip(mbox_number); 07160 if (ast_strlen_zero(mbox_number)) { 07161 /* There is no mailbox number. Skip it. */ 07162 continue; 07163 } 07164 if (ast_strlen_zero(mbox_context)) { 07165 /* There was no context so use the default. */ 07166 mbox_context = "default"; 07167 } 07168 07169 /* Fill the mbox[] element. */ 07170 ast_str_set(&mwi_description, -1, "%s span %d[%d] MWI mailbox %s@%s", 07171 sig_pri_cc_type_name, pri->span, i, mbox_number, mbox_context); 07172 pri->mbox[i].sub = ast_event_subscribe(AST_EVENT_MWI, sig_pri_mwi_event_cb, 07173 ast_str_buffer(mwi_description), pri, 07174 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mbox_number, 07175 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, mbox_context, 07176 AST_EVENT_IE_END); 07177 if (!pri->mbox[i].sub) { 07178 ast_log(LOG_ERROR, "%s span %d could not subscribe to MWI events for %s@%s.", 07179 sig_pri_cc_type_name, pri->span, mbox_number, mbox_context); 07180 continue; 07181 } 07182 pri->mbox[i].number = mbox_number; 07183 pri->mbox[i].context = mbox_context; 07184 ++i; 07185 } 07186 #endif /* defined(HAVE_PRI_MWI) */ 07187 07188 for (i = 0; i < SIG_PRI_NUM_DCHANS; i++) { 07189 if (pri->fds[i] == -1) { 07190 break; 07191 } 07192 07193 switch (pri->sig) { 07194 case SIG_BRI: 07195 pri->dchans[i] = pri_new_bri(pri->fds[i], 1, pri->nodetype, pri->switchtype); 07196 break; 07197 case SIG_BRI_PTMP: 07198 pri->dchans[i] = pri_new_bri(pri->fds[i], 0, pri->nodetype, pri->switchtype); 07199 break; 07200 default: 07201 pri->dchans[i] = pri_new(pri->fds[i], pri->nodetype, pri->switchtype); 07202 #if defined(HAVE_PRI_SERVICE_MESSAGES) 07203 if (pri->enable_service_message_support) { 07204 pri_set_service_message_support(pri->dchans[i], 1); 07205 } 07206 #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */ 07207 break; 07208 } 07209 07210 pri_set_overlapdial(pri->dchans[i], (pri->overlapdial & DAHDI_OVERLAPDIAL_OUTGOING) ? 1 : 0); 07211 #ifdef HAVE_PRI_PROG_W_CAUSE 07212 pri_set_chan_mapping_logical(pri->dchans[i], pri->qsigchannelmapping == DAHDI_CHAN_MAPPING_LOGICAL); 07213 #endif 07214 #ifdef HAVE_PRI_INBANDDISCONNECT 07215 pri_set_inbanddisconnect(pri->dchans[i], pri->inbanddisconnect); 07216 #endif 07217 /* Enslave to master if appropriate */ 07218 if (i) 07219 pri_enslave(pri->dchans[0], pri->dchans[i]); 07220 if (!pri->dchans[i]) { 07221 if (pri->fds[i] > 0) 07222 close(pri->fds[i]); 07223 pri->fds[i] = -1; 07224 ast_log(LOG_ERROR, "Unable to create PRI structure\n"); 07225 return -1; 07226 } 07227 pri_set_debug(pri->dchans[i], SIG_PRI_DEBUG_DEFAULT); 07228 pri_set_nsf(pri->dchans[i], pri->nsf); 07229 #ifdef PRI_GETSET_TIMERS 07230 for (x = 0; x < PRI_MAX_TIMERS; x++) { 07231 if (pri->pritimers[x] != 0) 07232 pri_set_timer(pri->dchans[i], x, pri->pritimers[x]); 07233 } 07234 #endif 07235 } 07236 07237 /* Assume primary is the one we use */ 07238 pri->pri = pri->dchans[0]; 07239 07240 #if defined(HAVE_PRI_CALL_HOLD) 07241 pri_hold_enable(pri->pri, 1); 07242 #endif /* defined(HAVE_PRI_CALL_HOLD) */ 07243 #if defined(HAVE_PRI_CALL_REROUTING) 07244 pri_reroute_enable(pri->pri, 1); 07245 #endif /* defined(HAVE_PRI_CALL_REROUTING) */ 07246 #if defined(HAVE_PRI_HANGUP_FIX) 07247 pri_hangup_fix_enable(pri->pri, 1); 07248 #endif /* defined(HAVE_PRI_HANGUP_FIX) */ 07249 #if defined(HAVE_PRI_CCSS) 07250 pri_cc_enable(pri->pri, 1); 07251 pri_cc_recall_mode(pri->pri, pri->cc_ptmp_recall_mode); 07252 pri_cc_retain_signaling_req(pri->pri, pri->cc_qsig_signaling_link_req); 07253 pri_cc_retain_signaling_rsp(pri->pri, pri->cc_qsig_signaling_link_rsp); 07254 #endif /* defined(HAVE_PRI_CCSS) */ 07255 #if defined(HAVE_PRI_TRANSFER) 07256 pri_transfer_enable(pri->pri, 1); 07257 #endif /* defined(HAVE_PRI_TRANSFER) */ 07258 #if defined(HAVE_PRI_AOC_EVENTS) 07259 pri_aoc_events_enable(pri->pri, 1); 07260 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 07261 #if defined(HAVE_PRI_CALL_WAITING) 07262 pri_connect_ack_enable(pri->pri, 1); 07263 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 07264 #if defined(HAVE_PRI_MCID) 07265 pri_mcid_enable(pri->pri, 1); 07266 #endif /* defined(HAVE_PRI_MCID) */ 07267 07268 pri->resetpos = -1; 07269 if (ast_pthread_create_background(&pri->master, NULL, pri_dchannel, pri)) { 07270 for (i = 0; i < SIG_PRI_NUM_DCHANS; i++) { 07271 if (!pri->dchans[i]) 07272 break; 07273 if (pri->fds[i] > 0) 07274 close(pri->fds[i]); 07275 pri->fds[i] = -1; 07276 } 07277 ast_log(LOG_ERROR, "Unable to spawn D-channel: %s\n", strerror(errno)); 07278 return -1; 07279 } 07280 07281 #if defined(HAVE_PRI_MWI) 07282 /* 07283 * Send the initial MWI indications from the event cache for this span. 07284 * 07285 * If we were loaded after app_voicemail the event would already be in 07286 * the cache. If we were loaded before app_voicemail the event would not 07287 * be in the cache yet and app_voicemail will send the event when it 07288 * gets loaded. 07289 */ 07290 sig_pri_mwi_cache_update(pri); 07291 #endif /* defined(HAVE_PRI_MWI) */ 07292 07293 return 0; 07294 }
void sig_pri_stop_pri | ( | struct sig_pri_span * | pri | ) |
Stop PRI span.
pri | Asterisk D channel control structure. |
Definition at line 7053 of file sig_pri.c.
References ARRAY_LEN, and ast_event_unsubscribe().
Referenced by __unload_module().
07054 { 07055 #if defined(HAVE_PRI_MWI) 07056 int idx; 07057 #endif /* defined(HAVE_PRI_MWI) */ 07058 07059 #if defined(HAVE_PRI_MWI) 07060 for (idx = 0; idx < ARRAY_LEN(pri->mbox); ++idx) { 07061 if (pri->mbox[idx].sub) { 07062 pri->mbox[idx].sub = ast_event_unsubscribe(pri->mbox[idx].sub); 07063 } 07064 } 07065 #endif /* defined(HAVE_PRI_MWI) */ 07066 }
void sig_pri_unload | ( | void | ) |
Unload the sig_pri submodule.
Definition at line 8103 of file sig_pri.c.
References ao2_ref.
Referenced by __unload_module().
08104 { 08105 #if defined(HAVE_PRI_CCSS) 08106 if (sig_pri_cc_monitors) { 08107 ao2_ref(sig_pri_cc_monitors, -1); 08108 sig_pri_cc_monitors = NULL; 08109 } 08110 #endif /* defined(HAVE_PRI_CCSS) */ 08111 }
const char dahdi_db[] = "dahdi/registry" [static] |