#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_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_ack (struct ast_cc_agent *agent) |
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 146 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 132 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 151 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 163 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 161 of file sig_pri.h.
Referenced by pri_check_restart().
#define SRVST_TYPE_OOS "O" |
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 1671 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().
01672 { 01673 pri->dchanavail[index] &= ~(DCHAN_NOTINALARM | DCHAN_UP); 01674 if (!before_start_pri) 01675 pri_find_dchan(pri); 01676 }
void pri_event_noalarm | ( | struct sig_pri_span * | pri, | |
int | index, | |||
int | before_start_pri | |||
) |
Definition at line 1678 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().
01679 { 01680 pri->dchanavail[index] |= DCHAN_NOTINALARM; 01681 if (!before_start_pri) 01682 pri_restart(pri->dchans[index]); 01683 }
int pri_is_up | ( | struct sig_pri_span * | pri | ) |
Definition at line 926 of file sig_pri.c.
References DCHAN_AVAILABLE, sig_pri_span::dchanavail, and SIG_PRI_NUM_DCHANS.
Referenced by pri_dchannel().
00927 { 00928 int x; 00929 for (x = 0; x < SIG_PRI_NUM_DCHANS; x++) { 00930 if (pri->dchanavail[x] == DCHAN_AVAILABLE) 00931 return 1; 00932 } 00933 return 0; 00934 }
int pri_maintenance_bservice | ( | struct pri * | pri, | |
struct sig_pri_chan * | p, | |||
int | changestatus | |||
) |
Definition at line 7358 of file sig_pri.c.
References sig_pri_chan::channel, PRI_SPAN, and PVT_TO_CHANNEL().
07359 { 07360 int channel = PVT_TO_CHANNEL(p); 07361 int span = PRI_SPAN(channel); 07362 07363 return pri_maintenance_service(pri, span, channel, changestatus); 07364 }
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 7333 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().
07334 { 07335 int res = -1; 07336 07337 sig_pri_lock_private(p); 07338 07339 if (!p->pri || !p->call) { 07340 ast_log(LOG_DEBUG, "Unable to find pri or call on channel!\n"); 07341 sig_pri_unlock_private(p); 07342 return -1; 07343 } 07344 07345 if (!pri_grab(p, p->pri)) { 07346 res = pri_callrerouting_facility(p->pri->pri, p->call, destination, original, reason); 07347 pri_rel(p->pri); 07348 } else { 07349 ast_log(LOG_DEBUG, "Unable to grab pri to send callrerouting facility on span %d!\n", p->pri->span); 07350 } 07351 07352 sig_pri_unlock_private(p); 07353 07354 return res; 07355 }
int pri_send_keypad_facility_exec | ( | struct sig_pri_chan * | p, | |
const char * | digits | |||
) |
Definition at line 7309 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().
07310 { 07311 sig_pri_lock_private(p); 07312 07313 if (!p->pri || !p->call) { 07314 ast_debug(1, "Unable to find pri or call on channel!\n"); 07315 sig_pri_unlock_private(p); 07316 return -1; 07317 } 07318 07319 if (!pri_grab(p, p->pri)) { 07320 pri_keypad_facility(p->pri->pri, p->call, digits); 07321 pri_rel(p->pri); 07322 } else { 07323 ast_debug(1, "Unable to grab pri to send keypad facility!\n"); 07324 sig_pri_unlock_private(p); 07325 return -1; 07326 } 07327 07328 sig_pri_unlock_private(p); 07329 07330 return 0; 07331 }
int sig_pri_answer | ( | struct sig_pri_chan * | p, | |
struct ast_channel * | ast | |||
) |
Definition at line 6677 of file sig_pri.c.
References ast_setstate(), AST_STATE_UP, sig_pri_chan::call, sig_pri_chan::digital, sig_pri_span::pri, sig_pri_chan::pri, pri_grab(), pri_rel(), sig_pri_chan::proceeding, sig_pri_open_media(), and sig_pri_set_dialing().
Referenced by dahdi_answer().
06678 { 06679 int res = 0; 06680 /* Send a pri acknowledge */ 06681 if (!pri_grab(p, p->pri)) { 06682 #if defined(HAVE_PRI_AOC_EVENTS) 06683 if (p->aoc_s_request_invoke_id_valid) { 06684 /* if AOC-S was requested and the invoke id is still present on answer. That means 06685 * no AOC-S rate list was provided, so send a NULL response which will indicate that 06686 * AOC-S is not available */ 06687 pri_aoc_s_request_response_send(p->pri->pri, p->call, 06688 p->aoc_s_request_invoke_id, NULL); 06689 p->aoc_s_request_invoke_id_valid = 0; 06690 } 06691 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 06692 p->proceeding = 1; 06693 sig_pri_set_dialing(p, 0); 06694 sig_pri_open_media(p); 06695 res = pri_answer(p->pri->pri, p->call, 0, !p->digital); 06696 pri_rel(p->pri); 06697 } else { 06698 res = -1; 06699 } 06700 ast_setstate(ast, AST_STATE_UP); 06701 return res; 06702 }
int sig_pri_available | ( | struct sig_pri_chan ** | pvt, | |
int | is_specific_channel | |||
) |
Definition at line 6779 of file sig_pri.c.
References sig_pri_chan::pri, and sig_pri_available_check().
Referenced by available().
06780 { 06781 struct sig_pri_chan *p = *pvt; 06782 06783 if (!p->pri) { 06784 /* Something is wrong here. A PRI channel without the pri pointer? */ 06785 return 0; 06786 } 06787 06788 if ( 06789 #if defined(HAVE_PRI_CALL_WAITING) 06790 /* 06791 * Only do call waiting calls if we have any 06792 * call waiting call outstanding. We do not 06793 * want new calls to steal a B channel 06794 * freed for an earlier call waiting call. 06795 */ 06796 !p->pri->num_call_waiting_calls && 06797 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 06798 sig_pri_available_check(p)) { 06799 return 1; 06800 } 06801 06802 #if defined(HAVE_PRI_CALL_WAITING) 06803 if (!is_specific_channel) { 06804 struct sig_pri_chan *cw; 06805 06806 cw = sig_pri_cw_available(p->pri); 06807 if (cw) { 06808 /* We have a call waiting interface to use instead. */ 06809 *pvt = cw; 06810 return 1; 06811 } 06812 } 06813 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 06814 return 0; 06815 }
int sig_pri_call | ( | struct sig_pri_chan * | p, | |
struct ast_channel * | ast, | |||
char * | rdest, | |||
int | timeout, | |||
int | layer1 | |||
) |
Definition at line 6036 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, 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_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().
06037 { 06038 char dest[256]; /* must be same length as p->dialdest */ 06039 struct ast_party_subaddress dialed_subaddress; /* Called subaddress */ 06040 struct pri_sr *sr; 06041 char *c, *l, *n, *s; 06042 #ifdef SUPPORT_USERUSER 06043 const char *useruser; 06044 #endif 06045 int core_id; 06046 int pridialplan; 06047 int dp_strip; 06048 int prilocaldialplan; 06049 int ldp_strip; 06050 int exclusive; 06051 #if defined(HAVE_PRI_SETUP_KEYPAD) 06052 const char *keypad; 06053 #endif /* defined(HAVE_PRI_SETUP_KEYPAD) */ 06054 AST_DECLARE_APP_ARGS(args, 06055 AST_APP_ARG(group); /* channel/group token */ 06056 AST_APP_ARG(ext); /* extension token */ 06057 AST_APP_ARG(opts); /* options token */ 06058 AST_APP_ARG(other); /* Any remining unused arguments */ 06059 ); 06060 struct ast_flags opts; 06061 char *opt_args[OPT_ARG_ARRAY_SIZE]; 06062 06063 ast_log(LOG_DEBUG, "CALLER NAME: %s NUM: %s\n", 06064 S_COR(ast->connected.id.name.valid, ast->connected.id.name.str, ""), 06065 S_COR(ast->connected.id.number.valid, ast->connected.id.number.str, "")); 06066 06067 if (!p->pri) { 06068 ast_log(LOG_ERROR, "Could not find pri on channel %d\n", p->channel); 06069 return -1; 06070 } 06071 06072 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { 06073 ast_log(LOG_WARNING, "sig_pri_call called on %s, neither down nor reserved\n", ast->name); 06074 return -1; 06075 } 06076 06077 p->dialdest[0] = '\0'; 06078 p->outgoing = 1; 06079 06080 ast_copy_string(dest, rdest, sizeof(dest)); 06081 AST_NONSTANDARD_APP_ARGS(args, dest, '/'); 06082 if (ast_app_parse_options(sig_pri_call_opts, &opts, opt_args, args.opts)) { 06083 /* General invalid option syntax. */ 06084 return -1; 06085 } 06086 06087 c = args.ext; 06088 if (!c) { 06089 c = ""; 06090 } 06091 06092 /* setup dialed_subaddress if found */ 06093 ast_party_subaddress_init(&dialed_subaddress); 06094 s = strchr(c, ':'); 06095 if (s) { 06096 *s = '\0'; 06097 s++; 06098 /* prefix */ 06099 /* 'n' = NSAP */ 06100 /* 'U' = odd, 'u'= even */ 06101 /* Default = NSAP */ 06102 switch (*s) { 06103 case 'U': 06104 dialed_subaddress.odd_even_indicator = 1; 06105 /* fall through */ 06106 case 'u': 06107 s++; 06108 dialed_subaddress.type = 2; 06109 break; 06110 case 'N': 06111 case 'n': 06112 s++; 06113 /* default already covered with ast_party_subaddress_init */ 06114 break; 06115 } 06116 dialed_subaddress.str = s; 06117 dialed_subaddress.valid = 1; 06118 s = NULL; 06119 } 06120 06121 l = NULL; 06122 n = NULL; 06123 if (!p->hidecallerid) { 06124 if (ast->connected.id.number.valid) { 06125 /* If we get to the end of this loop without breaking, there's no 06126 * calleridnum. This is done instead of testing for "unknown" or 06127 * the thousands of other ways that the calleridnum could be 06128 * invalid. */ 06129 for (l = ast->connected.id.number.str; l && *l; l++) { 06130 if (strchr("0123456789", *l)) { 06131 l = ast->connected.id.number.str; 06132 break; 06133 } 06134 } 06135 } else { 06136 l = NULL; 06137 } 06138 if (!p->hidecalleridname) { 06139 n = ast->connected.id.name.valid ? ast->connected.id.name.str : NULL; 06140 } 06141 } 06142 06143 if (strlen(c) < p->stripmsd) { 06144 ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd); 06145 return -1; 06146 } 06147 if (pri_grab(p, p->pri)) { 06148 ast_log(LOG_WARNING, "Failed to grab PRI!\n"); 06149 return -1; 06150 } 06151 if (!(p->call = pri_new_call(p->pri->pri))) { 06152 ast_log(LOG_WARNING, "Unable to create call on channel %d\n", p->channel); 06153 pri_rel(p->pri); 06154 return -1; 06155 } 06156 if (!(sr = pri_sr_new())) { 06157 ast_log(LOG_WARNING, "Failed to allocate setup request channel %d\n", p->channel); 06158 pri_destroycall(p->pri->pri, p->call); 06159 p->call = NULL; 06160 pri_rel(p->pri); 06161 return -1; 06162 } 06163 06164 sig_pri_set_digital(p, IS_DIGITAL(ast->transfercapability)); /* push up to parent for EC */ 06165 06166 #if defined(HAVE_PRI_CALL_WAITING) 06167 if (p->is_call_waiting) { 06168 /* 06169 * Indicate that this is a call waiting call. 06170 * i.e., Normal call but with no B channel. 06171 */ 06172 pri_sr_set_channel(sr, 0, 0, 1); 06173 } else 06174 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 06175 { 06176 /* Should the picked channel be used exclusively? */ 06177 if (p->priexclusive || p->pri->nodetype == PRI_NETWORK) { 06178 exclusive = 1; 06179 } else { 06180 exclusive = 0; 06181 } 06182 pri_sr_set_channel(sr, PVT_TO_CHANNEL(p), exclusive, 1); 06183 } 06184 06185 pri_sr_set_bearer(sr, p->digital ? PRI_TRANS_CAP_DIGITAL : ast->transfercapability, 06186 (p->digital ? -1 : layer1)); 06187 06188 if (p->pri->facilityenable) 06189 pri_facility_enable(p->pri->pri); 06190 06191 ast_verb(3, "Requested transfer capability: 0x%.2x - %s\n", ast->transfercapability, ast_transfercapability2str(ast->transfercapability)); 06192 dp_strip = 0; 06193 pridialplan = p->pri->dialplan - 1; 06194 if (pridialplan == -2 || pridialplan == -3) { /* compute dynamically */ 06195 if (strncmp(c + p->stripmsd, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) { 06196 if (pridialplan == -2) { 06197 dp_strip = strlen(p->pri->internationalprefix); 06198 } 06199 pridialplan = PRI_INTERNATIONAL_ISDN; 06200 } else if (strncmp(c + p->stripmsd, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) { 06201 if (pridialplan == -2) { 06202 dp_strip = strlen(p->pri->nationalprefix); 06203 } 06204 pridialplan = PRI_NATIONAL_ISDN; 06205 } else { 06206 pridialplan = PRI_LOCAL_ISDN; 06207 } 06208 } 06209 while (c[p->stripmsd] > '9' && c[p->stripmsd] != '*' && c[p->stripmsd] != '#') { 06210 switch (c[p->stripmsd]) { 06211 case 'U': 06212 pridialplan = (PRI_TON_UNKNOWN << 4) | (pridialplan & 0xf); 06213 break; 06214 case 'I': 06215 pridialplan = (PRI_TON_INTERNATIONAL << 4) | (pridialplan & 0xf); 06216 break; 06217 case 'N': 06218 pridialplan = (PRI_TON_NATIONAL << 4) | (pridialplan & 0xf); 06219 break; 06220 case 'L': 06221 pridialplan = (PRI_TON_NET_SPECIFIC << 4) | (pridialplan & 0xf); 06222 break; 06223 case 'S': 06224 pridialplan = (PRI_TON_SUBSCRIBER << 4) | (pridialplan & 0xf); 06225 break; 06226 case 'V': 06227 pridialplan = (PRI_TON_ABBREVIATED << 4) | (pridialplan & 0xf); 06228 break; 06229 case 'R': 06230 pridialplan = (PRI_TON_RESERVED << 4) | (pridialplan & 0xf); 06231 break; 06232 case 'u': 06233 pridialplan = PRI_NPI_UNKNOWN | (pridialplan & 0xf0); 06234 break; 06235 case 'e': 06236 pridialplan = PRI_NPI_E163_E164 | (pridialplan & 0xf0); 06237 break; 06238 case 'x': 06239 pridialplan = PRI_NPI_X121 | (pridialplan & 0xf0); 06240 break; 06241 case 'f': 06242 pridialplan = PRI_NPI_F69 | (pridialplan & 0xf0); 06243 break; 06244 case 'n': 06245 pridialplan = PRI_NPI_NATIONAL | (pridialplan & 0xf0); 06246 break; 06247 case 'p': 06248 pridialplan = PRI_NPI_PRIVATE | (pridialplan & 0xf0); 06249 break; 06250 case 'r': 06251 pridialplan = PRI_NPI_RESERVED | (pridialplan & 0xf0); 06252 break; 06253 default: 06254 if (isalpha(c[p->stripmsd])) { 06255 ast_log(LOG_WARNING, "Unrecognized pridialplan %s modifier: %c\n", 06256 c[p->stripmsd] > 'Z' ? "NPI" : "TON", c[p->stripmsd]); 06257 } 06258 break; 06259 } 06260 c++; 06261 } 06262 #if defined(HAVE_PRI_SETUP_KEYPAD) 06263 if (ast_test_flag(&opts, OPT_KEYPAD) 06264 && !ast_strlen_zero(opt_args[OPT_ARG_KEYPAD])) { 06265 /* We have a keypad facility digits option with digits. */ 06266 keypad = opt_args[OPT_ARG_KEYPAD]; 06267 pri_sr_set_keypad_digits(sr, keypad); 06268 } else { 06269 keypad = NULL; 06270 } 06271 if (!keypad || !ast_strlen_zero(c + p->stripmsd + dp_strip)) 06272 #endif /* defined(HAVE_PRI_SETUP_KEYPAD) */ 06273 { 06274 pri_sr_set_called(sr, c + p->stripmsd + dp_strip, pridialplan, s ? 1 : 0); 06275 } 06276 06277 #if defined(HAVE_PRI_SUBADDR) 06278 if (dialed_subaddress.valid) { 06279 struct pri_party_subaddress subaddress; 06280 06281 memset(&subaddress, 0, sizeof(subaddress)); 06282 sig_pri_party_subaddress_from_ast(&subaddress, &dialed_subaddress); 06283 pri_sr_set_called_subaddress(sr, &subaddress); 06284 } 06285 #endif /* defined(HAVE_PRI_SUBADDR) */ 06286 #if defined(HAVE_PRI_REVERSE_CHARGE) 06287 if (ast_test_flag(&opts, OPT_REVERSE_CHARGE)) { 06288 pri_sr_set_reversecharge(sr, PRI_REVERSECHARGE_REQUESTED); 06289 } 06290 #endif /* defined(HAVE_PRI_REVERSE_CHARGE) */ 06291 #if defined(HAVE_PRI_AOC_EVENTS) 06292 if (ast_test_flag(&opts, OPT_AOC_REQUEST) 06293 && !ast_strlen_zero(opt_args[OPT_ARG_AOC_REQUEST])) { 06294 if (strchr(opt_args[OPT_ARG_AOC_REQUEST], 's')) { 06295 pri_sr_set_aoc_charging_request(sr, PRI_AOC_REQUEST_S); 06296 } 06297 if (strchr(opt_args[OPT_ARG_AOC_REQUEST], 'd')) { 06298 pri_sr_set_aoc_charging_request(sr, PRI_AOC_REQUEST_D); 06299 } 06300 if (strchr(opt_args[OPT_ARG_AOC_REQUEST], 'e')) { 06301 pri_sr_set_aoc_charging_request(sr, PRI_AOC_REQUEST_E); 06302 } 06303 } 06304 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 06305 06306 /* Setup the user tag for party id's from this device for this call. */ 06307 if (p->pri->append_msn_to_user_tag) { 06308 snprintf(p->user_tag, sizeof(p->user_tag), "%s_%s", p->pri->initial_user_tag, 06309 p->pri->nodetype == PRI_NETWORK 06310 ? c + p->stripmsd + dp_strip 06311 : S_COR(ast->connected.id.number.valid, 06312 ast->connected.id.number.str, "")); 06313 } else { 06314 ast_copy_string(p->user_tag, p->pri->initial_user_tag, sizeof(p->user_tag)); 06315 } 06316 06317 /* 06318 * Replace the caller id tag from the channel creation 06319 * with the actual tag value. 06320 */ 06321 ast_free(ast->caller.id.tag); 06322 ast->caller.id.tag = ast_strdup(p->user_tag); 06323 06324 ldp_strip = 0; 06325 prilocaldialplan = p->pri->localdialplan - 1; 06326 if ((l != NULL) && (prilocaldialplan == -2 || prilocaldialplan == -3)) { /* compute dynamically */ 06327 if (strncmp(l, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) { 06328 if (prilocaldialplan == -2) { 06329 ldp_strip = strlen(p->pri->internationalprefix); 06330 } 06331 prilocaldialplan = PRI_INTERNATIONAL_ISDN; 06332 } else if (strncmp(l, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) { 06333 if (prilocaldialplan == -2) { 06334 ldp_strip = strlen(p->pri->nationalprefix); 06335 } 06336 prilocaldialplan = PRI_NATIONAL_ISDN; 06337 } else { 06338 prilocaldialplan = PRI_LOCAL_ISDN; 06339 } 06340 } 06341 if (l != NULL) { 06342 while (*l > '9' && *l != '*' && *l != '#') { 06343 switch (*l) { 06344 case 'U': 06345 prilocaldialplan = (PRI_TON_UNKNOWN << 4) | (prilocaldialplan & 0xf); 06346 break; 06347 case 'I': 06348 prilocaldialplan = (PRI_TON_INTERNATIONAL << 4) | (prilocaldialplan & 0xf); 06349 break; 06350 case 'N': 06351 prilocaldialplan = (PRI_TON_NATIONAL << 4) | (prilocaldialplan & 0xf); 06352 break; 06353 case 'L': 06354 prilocaldialplan = (PRI_TON_NET_SPECIFIC << 4) | (prilocaldialplan & 0xf); 06355 break; 06356 case 'S': 06357 prilocaldialplan = (PRI_TON_SUBSCRIBER << 4) | (prilocaldialplan & 0xf); 06358 break; 06359 case 'V': 06360 prilocaldialplan = (PRI_TON_ABBREVIATED << 4) | (prilocaldialplan & 0xf); 06361 break; 06362 case 'R': 06363 prilocaldialplan = (PRI_TON_RESERVED << 4) | (prilocaldialplan & 0xf); 06364 break; 06365 case 'u': 06366 prilocaldialplan = PRI_NPI_UNKNOWN | (prilocaldialplan & 0xf0); 06367 break; 06368 case 'e': 06369 prilocaldialplan = PRI_NPI_E163_E164 | (prilocaldialplan & 0xf0); 06370 break; 06371 case 'x': 06372 prilocaldialplan = PRI_NPI_X121 | (prilocaldialplan & 0xf0); 06373 break; 06374 case 'f': 06375 prilocaldialplan = PRI_NPI_F69 | (prilocaldialplan & 0xf0); 06376 break; 06377 case 'n': 06378 prilocaldialplan = PRI_NPI_NATIONAL | (prilocaldialplan & 0xf0); 06379 break; 06380 case 'p': 06381 prilocaldialplan = PRI_NPI_PRIVATE | (prilocaldialplan & 0xf0); 06382 break; 06383 case 'r': 06384 prilocaldialplan = PRI_NPI_RESERVED | (prilocaldialplan & 0xf0); 06385 break; 06386 default: 06387 if (isalpha(*l)) { 06388 ast_log(LOG_WARNING, 06389 "Unrecognized prilocaldialplan %s modifier: %c\n", 06390 *l > 'Z' ? "NPI" : "TON", *l); 06391 } 06392 break; 06393 } 06394 l++; 06395 } 06396 } 06397 pri_sr_set_caller(sr, l ? (l + ldp_strip) : NULL, n, prilocaldialplan, 06398 p->use_callingpres ? ast->connected.id.number.presentation : (l ? PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN : PRES_NUMBER_NOT_AVAILABLE)); 06399 06400 #if defined(HAVE_PRI_SUBADDR) 06401 if (ast->connected.id.subaddress.valid) { 06402 struct pri_party_subaddress subaddress; 06403 06404 memset(&subaddress, 0, sizeof(subaddress)); 06405 sig_pri_party_subaddress_from_ast(&subaddress, &ast->connected.id.subaddress); 06406 pri_sr_set_caller_subaddress(sr, &subaddress); 06407 } 06408 #endif /* defined(HAVE_PRI_SUBADDR) */ 06409 06410 sig_pri_redirecting_update(p, ast); 06411 06412 #ifdef SUPPORT_USERUSER 06413 /* User-user info */ 06414 useruser = pbx_builtin_getvar_helper(p->owner, "USERUSERINFO"); 06415 if (useruser) 06416 pri_sr_set_useruser(sr, useruser); 06417 #endif 06418 06419 #if defined(HAVE_PRI_CCSS) 06420 if (ast_cc_is_recall(ast, &core_id, sig_pri_cc_type_name)) { 06421 struct ast_cc_monitor *monitor; 06422 char device_name[AST_CHANNEL_NAME]; 06423 06424 /* This is a CC recall call. */ 06425 ast_channel_get_device_name(ast, device_name, sizeof(device_name)); 06426 monitor = ast_cc_get_monitor_by_recall_core_id(core_id, device_name); 06427 if (monitor) { 06428 struct sig_pri_cc_monitor_instance *instance; 06429 06430 instance = monitor->private_data; 06431 06432 /* If this fails then we have monitor instance ambiguity. */ 06433 ast_assert(p->pri == instance->pri); 06434 06435 if (pri_cc_call(p->pri->pri, instance->cc_id, p->call, sr)) { 06436 /* The CC recall call failed for some reason. */ 06437 ast_log(LOG_WARNING, "Unable to setup CC recall call to device %s\n", 06438 device_name); 06439 ao2_ref(monitor, -1); 06440 pri_rel(p->pri); 06441 pri_sr_free(sr); 06442 return -1; 06443 } 06444 ao2_ref(monitor, -1); 06445 } else { 06446 core_id = -1; 06447 } 06448 } else 06449 #endif /* defined(HAVE_PRI_CCSS) */ 06450 { 06451 core_id = -1; 06452 } 06453 if (core_id == -1 && pri_setup(p->pri->pri, p->call, sr)) { 06454 ast_log(LOG_WARNING, "Unable to setup call to %s (using %s)\n", 06455 c + p->stripmsd + dp_strip, dialplan2str(p->pri->dialplan)); 06456 pri_rel(p->pri); 06457 pri_sr_free(sr); 06458 return -1; 06459 } 06460 pri_sr_free(sr); 06461 ast_setstate(ast, AST_STATE_DIALING); 06462 sig_pri_set_dialing(p, 1); 06463 pri_rel(p->pri); 06464 return 0; 06465 }
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_ack | ( | struct ast_cc_agent * | agent | ) |
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 7193 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().
07194 { 07195 sig_pri_set_alarm(p, !noalarm); 07196 if (!noalarm) { 07197 if (!p->pri || !p->pri->pri || (pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0)) { 07198 /* T309 is not enabled : hangup calls when alarm occurs */ 07199 if (p->call) { 07200 if (p->pri && p->pri->pri) { 07201 if (!pri_grab(p, p->pri)) { 07202 pri_hangup(p->pri->pri, p->call, -1); 07203 pri_destroycall(p->pri->pri, p->call); 07204 p->call = NULL; 07205 pri_rel(p->pri); 07206 } else 07207 ast_log(LOG_WARNING, "Failed to grab PRI!\n"); 07208 } else 07209 ast_log(LOG_WARNING, "The PRI Call has not been destroyed\n"); 07210 } 07211 if (p->owner) 07212 p->owner->_softhangup |= AST_SOFTHANGUP_DEV; 07213 } 07214 } 07215 }
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 7245 of file sig_pri.c.
References ast_free.
Referenced by destroy_dahdi_pvt().
07246 { 07247 ast_free(doomed); 07248 }
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 7217 of file sig_pri.c.
References ast_calloc, and sig_pri_chan::pri.
07218 { 07219 struct sig_pri_chan *p; 07220 07221 p = ast_calloc(1, sizeof(*p)); 07222 if (!p) 07223 return p; 07224 07225 p->logicalspan = logicalspan; 07226 p->prioffset = channo; 07227 p->mastertrunkgroup = trunkgroup; 07228 07229 p->calls = callback; 07230 p->chan_pvt = pvt_data; 07231 07232 p->pri = pri; 07233 07234 return p; 07235 }
void sig_pri_cli_show_span | ( | int | fd, | |
int * | dchannels, | |||
struct sig_pri_span * | pri | |||
) |
Definition at line 7281 of file sig_pri.c.
References ast_cli(), build_status(), DAHDI_OVERLAPDIAL_INCOMING, sig_pri_span::dchanavail, sig_pri_span::dchans, free, sig_pri_span::overlapdial, sig_pri_span::pri, sig_pri_chan::pri, pri_order(), and status.
Referenced by handle_pri_show_span().
07282 { 07283 int x; 07284 char status[256]; 07285 07286 for (x = 0; x < SIG_PRI_NUM_DCHANS; x++) { 07287 if (pri->dchans[x]) { 07288 #ifdef PRI_DUMP_INFO_STR 07289 char *info_str = NULL; 07290 #endif 07291 ast_cli(fd, "%s D-channel: %d\n", pri_order(x), dchannels[x]); 07292 build_status(status, sizeof(status), pri->dchanavail[x], pri->dchans[x] == pri->pri); 07293 ast_cli(fd, "Status: %s\n", status); 07294 #ifdef PRI_DUMP_INFO_STR 07295 info_str = pri_dump_info_str(pri->pri); 07296 if (info_str) { 07297 ast_cli(fd, "%s", info_str); 07298 free(info_str); 07299 } 07300 #else 07301 pri_dump_info(pri->pri); 07302 #endif 07303 ast_cli(fd, "Overlap Recv: %s\n\n", (pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)?"Yes":"No"); 07304 ast_cli(fd, "\n"); 07305 } 07306 } 07307 }
void sig_pri_cli_show_spans | ( | int | fd, | |
int | span, | |||
struct sig_pri_span * | pri | |||
) |
Definition at line 7269 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().
07270 { 07271 char status[256]; 07272 int x; 07273 for (x = 0; x < SIG_PRI_NUM_DCHANS; x++) { 07274 if (pri->dchans[x]) { 07275 build_status(status, sizeof(status), pri->dchanavail[x], pri->dchans[x] == pri->pri); 07276 ast_cli(fd, "PRI span %d/%d: %s\n", span, x, status); 07277 } 07278 } 07279 }
int sig_pri_digit_begin | ( | struct sig_pri_chan * | pvt, | |
struct ast_channel * | ast, | |||
char | digit | |||
) |
Definition at line 6819 of file sig_pri.c.
References ast_channel::_state, ast_debug, ast_log(), AST_STATE_DIALING, sig_pri_chan::call, sig_pri_chan::dialdest, LOG_WARNING, sig_pri_span::pri, sig_pri_chan::pri, pri_grab(), pri_rel(), sig_pri_chan::proceeding, sig_pri_chan::setup_ack, and sig_pri_span::span.
Referenced by dahdi_digit_begin().
06820 { 06821 if ((ast->_state == AST_STATE_DIALING) && !pvt->proceeding) { 06822 if (pvt->setup_ack) { 06823 if (!pri_grab(pvt, pvt->pri)) { 06824 pri_information(pvt->pri->pri, pvt->call, digit); 06825 pri_rel(pvt->pri); 06826 } else { 06827 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", pvt->pri->span); 06828 } 06829 } else if (strlen(pvt->dialdest) < sizeof(pvt->dialdest) - 1) { 06830 int res; 06831 ast_debug(1, "Queueing digit '%c' since setup_ack not yet received\n", digit); 06832 res = strlen(pvt->dialdest); 06833 pvt->dialdest[res++] = digit; 06834 pvt->dialdest[res] = '\0'; 06835 } 06836 return 0; 06837 } 06838 return 1; 06839 }
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 5957 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().
05958 { 05959 char *dial; 05960 char *number; 05961 char *subaddr; 05962 AST_DECLARE_APP_ARGS(args, 05963 AST_APP_ARG(group); /* channel/group token */ 05964 AST_APP_ARG(ext); /* extension token */ 05965 //AST_APP_ARG(opts); /* options token */ 05966 AST_APP_ARG(other); /* Any remining unused arguments */ 05967 ); 05968 05969 /* Get private copy of dial string and break it up. */ 05970 dial = ast_strdupa(rdest); 05971 AST_NONSTANDARD_APP_ARGS(args, dial, '/'); 05972 05973 number = args.ext; 05974 if (!number) { 05975 number = ""; 05976 } 05977 05978 /* Find and extract dialed_subaddress */ 05979 subaddr = strchr(number, ':'); 05980 if (subaddr) { 05981 *subaddr++ = '\0'; 05982 05983 /* Skip subaddress type prefix. */ 05984 switch (*subaddr) { 05985 case 'U': 05986 case 'u': 05987 case 'N': 05988 case 'n': 05989 ++subaddr; 05990 break; 05991 default: 05992 break; 05993 } 05994 } 05995 05996 /* Skip type-of-number/dial-plan prefix characters. */ 05997 if (strlen(number) < p->stripmsd) { 05998 number = ""; 05999 } else { 06000 number += p->stripmsd; 06001 while (isalpha(*number)) { 06002 ++number; 06003 } 06004 } 06005 06006 /* Fill buffer with extracted number and subaddress. */ 06007 if (ast_strlen_zero(subaddr)) { 06008 /* Put in called number only since there is no subaddress. */ 06009 snprintf(called, called_buff_size, "%s", number); 06010 } else { 06011 /* Put in called number and subaddress. */ 06012 snprintf(called, called_buff_size, "%s:%s", number, subaddr); 06013 } 06014 }
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 5855 of file sig_pri.c.
References sig_pri_chan::alerting, sig_pri_chan::alreadyhungup, ast_atomic_fetchadd_int(), ast_log(), sig_pri_chan::call, 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::proceeding, sig_pri_chan::progress, sig_pri_chan::setup_ack, 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().
05856 { 05857 int res; 05858 #ifdef SUPPORT_USERUSER 05859 const char *useruser = pbx_builtin_getvar_helper(ast, "USERUSERINFO"); 05860 #endif 05861 05862 ast_log(LOG_DEBUG, "%s %d\n", __FUNCTION__, p->channel); 05863 if (!ast->tech_pvt) { 05864 ast_log(LOG_WARNING, "Asked to hangup channel not connected\n"); 05865 return 0; 05866 } 05867 05868 p->owner = NULL; 05869 p->outgoing = 0; 05870 sig_pri_set_digital(p, 0); /* push up to parent for EC*/ 05871 #if defined(HAVE_PRI_CALL_WAITING) 05872 if (p->is_call_waiting) { 05873 p->is_call_waiting = 0; 05874 ast_atomic_fetchadd_int(&p->pri->num_call_waiting_calls, -1); 05875 } 05876 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 05877 p->proceeding = 0; 05878 p->progress = 0; 05879 p->alerting = 0; 05880 p->setup_ack = 0; 05881 p->cid_num[0] = '\0'; 05882 p->cid_subaddr[0] = '\0'; 05883 p->cid_name[0] = '\0'; 05884 p->user_tag[0] = '\0'; 05885 p->exten[0] = '\0'; 05886 sig_pri_set_dialing(p, 0); 05887 05888 /* Make sure we have a call (or REALLY have a call in the case of a PRI) */ 05889 if (!pri_grab(p, p->pri)) { 05890 if (p->call) { 05891 if (p->alreadyhungup) { 05892 ast_log(LOG_DEBUG, "Already hungup... Calling hangup once, and clearing call\n"); 05893 05894 #ifdef SUPPORT_USERUSER 05895 pri_call_set_useruser(p->call, useruser); 05896 #endif 05897 05898 #if defined(HAVE_PRI_AOC_EVENTS) 05899 if (p->holding_aoce) { 05900 pri_aoc_e_send(p->pri->pri, p->call, &p->aoc_e); 05901 } 05902 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 05903 pri_hangup(p->pri->pri, p->call, -1); 05904 p->call = NULL; 05905 } else { 05906 const char *cause = pbx_builtin_getvar_helper(ast,"PRI_CAUSE"); 05907 int icause = ast->hangupcause ? ast->hangupcause : -1; 05908 ast_log(LOG_DEBUG, "Not yet hungup... Calling hangup once with icause, and clearing call\n"); 05909 05910 #ifdef SUPPORT_USERUSER 05911 pri_call_set_useruser(p->call, useruser); 05912 #endif 05913 05914 p->alreadyhungup = 1; 05915 if (cause) { 05916 if (atoi(cause)) 05917 icause = atoi(cause); 05918 } 05919 #if defined(HAVE_PRI_AOC_EVENTS) 05920 if (p->holding_aoce) { 05921 pri_aoc_e_send(p->pri->pri, p->call, &p->aoc_e); 05922 } 05923 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 05924 pri_hangup(p->pri->pri, p->call, icause); 05925 } 05926 } 05927 sig_pri_span_devstate_changed(p->pri); 05928 pri_rel(p->pri); 05929 res = 0; 05930 } else { 05931 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->pri->span); 05932 res = -1; 05933 } 05934 05935 #if defined(HAVE_PRI_AOC_EVENTS) 05936 p->aoc_s_request_invoke_id_valid = 0; 05937 p->holding_aoce = 0; 05938 p->waiting_for_aoce = 0; 05939 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 05940 ast->tech_pvt = NULL; 05941 return res; 05942 }
int sig_pri_indicate | ( | struct sig_pri_chan * | p, | |
struct ast_channel * | chan, | |||
int | condition, | |||
const void * | data, | |||
size_t | datalen | |||
) |
Definition at line 6467 of file sig_pri.c.
References ast_channel::_softhangup, ast_channel::_state, sig_pri_chan::alerting, 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_CONGESTION, 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, 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::proceeding, sig_pri_chan::progress, PVT_TO_CHANNEL(), SIG_PRI_AOC_GRANT_D, SIG_PRI_AOC_GRANT_E, SIG_PRI_AOC_GRANT_S, 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().
06468 { 06469 int res = -1; 06470 06471 switch (condition) { 06472 case AST_CONTROL_BUSY: 06473 if (p->priindication_oob || p->no_b_channel) { 06474 chan->hangupcause = AST_CAUSE_USER_BUSY; 06475 chan->_softhangup |= AST_SOFTHANGUP_DEV; 06476 res = 0; 06477 } else if (!p->progress && p->pri && !p->outgoing) { 06478 if (p->pri->pri) { 06479 if (!pri_grab(p, p->pri)) { 06480 #ifdef HAVE_PRI_PROG_W_CAUSE 06481 pri_progress_with_cause(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1, PRI_CAUSE_USER_BUSY); /* cause = 17 */ 06482 #else 06483 pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1); 06484 #endif 06485 pri_rel(p->pri); 06486 } else { 06487 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->pri->span); 06488 } 06489 } 06490 p->progress = 1; 06491 res = sig_pri_play_tone(p, SIG_PRI_TONE_BUSY); 06492 } 06493 break; 06494 case AST_CONTROL_RINGING: 06495 if ((!p->alerting) && p->pri && !p->outgoing && (chan->_state != AST_STATE_UP)) { 06496 if (p->pri->pri) { 06497 if (!pri_grab(p, p->pri)) { 06498 pri_acknowledge(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 06499 p->no_b_channel || p->digital ? 0 : 1); 06500 pri_rel(p->pri); 06501 } else { 06502 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->pri->span); 06503 } 06504 } 06505 p->alerting = 1; 06506 } 06507 res = sig_pri_play_tone(p, SIG_PRI_TONE_RINGTONE); 06508 if (chan->_state != AST_STATE_UP) { 06509 if (chan->_state != AST_STATE_RING) 06510 ast_setstate(chan, AST_STATE_RINGING); 06511 } 06512 break; 06513 case AST_CONTROL_PROCEEDING: 06514 ast_debug(1,"Received AST_CONTROL_PROCEEDING on %s\n",chan->name); 06515 if (!p->proceeding && p->pri && !p->outgoing) { 06516 if (p->pri->pri) { 06517 if (!pri_grab(p, p->pri)) { 06518 pri_proceeding(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 06519 p->no_b_channel || p->digital ? 0 : 1); 06520 p->proceeding = 1; 06521 if (!p->no_b_channel && !p->digital) { 06522 sig_pri_set_dialing(p, 0); 06523 } 06524 pri_rel(p->pri); 06525 } else { 06526 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->pri->span); 06527 } 06528 } 06529 } 06530 /* don't continue in ast_indicate */ 06531 res = 0; 06532 break; 06533 case AST_CONTROL_PROGRESS: 06534 ast_debug(1,"Received AST_CONTROL_PROGRESS on %s\n",chan->name); 06535 sig_pri_set_digital(p, 0); /* Digital-only calls isn't allowing any inband progress messages */ 06536 if (!p->progress && !p->alerting && p->pri && !p->outgoing && !p->no_b_channel) { 06537 if (p->pri->pri) { 06538 if (!pri_grab(p, p->pri)) { 06539 #ifdef HAVE_PRI_PROG_W_CAUSE 06540 pri_progress_with_cause(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1, -1); /* no cause at all */ 06541 #else 06542 pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1); 06543 #endif 06544 pri_rel(p->pri); 06545 } else { 06546 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->pri->span); 06547 } 06548 } 06549 p->progress = 1; 06550 } 06551 /* don't continue in ast_indicate */ 06552 res = 0; 06553 break; 06554 case AST_CONTROL_CONGESTION: 06555 chan->hangupcause = AST_CAUSE_CONGESTION; 06556 if (p->priindication_oob || p->no_b_channel) { 06557 chan->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 06558 chan->_softhangup |= AST_SOFTHANGUP_DEV; 06559 res = 0; 06560 } else if (!p->progress && p->pri && !p->outgoing) { 06561 if (p->pri->pri) { 06562 if (!pri_grab(p, p->pri)) { 06563 #ifdef HAVE_PRI_PROG_W_CAUSE 06564 pri_progress_with_cause(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1, PRI_CAUSE_SWITCH_CONGESTION); /* cause = 42 */ 06565 #else 06566 pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1); 06567 #endif 06568 pri_rel(p->pri); 06569 } else { 06570 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->pri->span); 06571 } 06572 } 06573 p->progress = 1; 06574 res = sig_pri_play_tone(p, SIG_PRI_TONE_CONGESTION); 06575 } 06576 break; 06577 case AST_CONTROL_HOLD: 06578 if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) { 06579 if (!pri_grab(p, p->pri)) { 06580 res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_HOLD); 06581 pri_rel(p->pri); 06582 } else { 06583 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->pri->span); 06584 } 06585 } else 06586 ast_moh_start(chan, data, p->mohinterpret); 06587 break; 06588 case AST_CONTROL_UNHOLD: 06589 if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) { 06590 if (!pri_grab(p, p->pri)) { 06591 res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_RETRIEVAL); 06592 pri_rel(p->pri); 06593 } 06594 } else 06595 ast_moh_stop(chan); 06596 break; 06597 case AST_CONTROL_SRCUPDATE: 06598 res = 0; 06599 break; 06600 case -1: 06601 res = sig_pri_play_tone(p, -1); 06602 break; 06603 case AST_CONTROL_CONNECTED_LINE: 06604 ast_debug(1, "Received AST_CONTROL_CONNECTED_LINE on %s\n", chan->name); 06605 if (p->pri && !pri_grab(p, p->pri)) { 06606 struct pri_party_connected_line connected; 06607 06608 memset(&connected, 0, sizeof(connected)); 06609 sig_pri_party_id_from_ast(&connected.id, &chan->connected.id); 06610 06611 pri_connected_line_update(p->pri->pri, p->call, &connected); 06612 pri_rel(p->pri); 06613 } 06614 break; 06615 case AST_CONTROL_REDIRECTING: 06616 ast_debug(1, "Received AST_CONTROL_REDIRECTING on %s\n", chan->name); 06617 if (p->pri && !pri_grab(p, p->pri)) { 06618 sig_pri_redirecting_update(p, chan); 06619 pri_rel(p->pri); 06620 } 06621 break; 06622 case AST_CONTROL_AOC: 06623 #if defined(HAVE_PRI_AOC_EVENTS) 06624 { 06625 struct ast_aoc_decoded *decoded 06626 = ast_aoc_decode((struct ast_aoc_encoded *) data, datalen, chan); 06627 ast_debug(1, "Received AST_CONTROL_AOC on %s\n", chan->name); 06628 if (decoded && p->pri && !pri_grab(p, p->pri)) { 06629 switch (ast_aoc_get_msg_type(decoded)) { 06630 case AST_AOC_S: 06631 if (p->pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_S) { 06632 sig_pri_aoc_s_from_ast(p, decoded); 06633 } 06634 break; 06635 case AST_AOC_D: 06636 if (p->pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_D) { 06637 sig_pri_aoc_d_from_ast(p, decoded); 06638 } 06639 break; 06640 case AST_AOC_E: 06641 if (p->pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_E) { 06642 sig_pri_aoc_e_from_ast(p, decoded); 06643 } 06644 /* if hangup was delayed for this AOC-E msg, waiting_for_aoc 06645 * will be set. A hangup is already occuring via a timeout during 06646 * this delay. Instead of waiting for that timeout to occur, go ahead 06647 * and initiate the softhangup since the delay is no longer necessary */ 06648 if (p->waiting_for_aoce) { 06649 p->waiting_for_aoce = 0; 06650 ast_log(LOG_DEBUG, 06651 "Received final AOC-E msg, continue with hangup on %s\n", 06652 chan->name); 06653 ast_softhangup_nolock(chan, AST_SOFTHANGUP_DEV); 06654 } 06655 break; 06656 case AST_AOC_REQUEST: 06657 /* We do not pass through AOC requests, So unless this 06658 * is an AOC termination request it will be ignored */ 06659 if (ast_aoc_get_termination_request(decoded)) { 06660 pri_hangup(p->pri->pri, p->call, -1); 06661 } 06662 break; 06663 default: 06664 break; 06665 } 06666 pri_rel(p->pri); 06667 } 06668 ast_aoc_destroy_decoded(decoded); 06669 } 06670 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 06671 break; 06672 } 06673 06674 return res; 06675 }
void sig_pri_init_pri | ( | struct sig_pri_span * | pri | ) |
Definition at line 5842 of file sig_pri.c.
References ast_mutex_init, AST_PTHREADT_NULL, and SIG_PRI_NUM_DCHANS.
Referenced by load_module().
05843 { 05844 int i; 05845 05846 memset(pri, 0, sizeof(*pri)); 05847 05848 ast_mutex_init(&pri->lock); 05849 05850 pri->master = AST_PTHREADT_NULL; 05851 for (i = 0; i < SIG_PRI_NUM_DCHANS; i++) 05852 pri->fds[i] = -1; 05853 }
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 7942 of file sig_pri.c.
References ao2_container_alloc.
Referenced by load_module().
07943 { 07944 #if defined(HAVE_PRI_CCSS) 07945 sig_pri_cc_type_name = cc_type_name; 07946 sig_pri_cc_monitors = ao2_container_alloc(37, sig_pri_cc_monitor_instance_hash_fn, 07947 sig_pri_cc_monitor_instance_cmp_fn); 07948 if (!sig_pri_cc_monitors) { 07949 return -1; 07950 } 07951 #endif /* defined(HAVE_PRI_CCSS) */ 07952 return 0; 07953 }
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 912 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().
00913 { 00914 struct ast_channel *ast; 00915 00916 ast_log(LOG_DEBUG, "%s %d\n", __FUNCTION__, p->channel); 00917 00918 p->outgoing = 1; 00919 ast = sig_pri_new_ast_channel(p, AST_STATE_RESERVED, law, transfercapability, p->exten, requestor); 00920 if (!ast) { 00921 p->outgoing = 0; 00922 } 00923 return ast; 00924 }
int sig_pri_start_pri | ( | struct sig_pri_span * | pri | ) |
Definition at line 7015 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().
07016 { 07017 int x; 07018 int i; 07019 #if defined(HAVE_PRI_MWI) 07020 char *saveptr; 07021 char *mbox_number; 07022 char *mbox_context; 07023 struct ast_str *mwi_description = ast_str_alloca(64); 07024 #endif /* defined(HAVE_PRI_MWI) */ 07025 07026 #if defined(HAVE_PRI_MWI) 07027 /* Prepare the mbox[] for use. */ 07028 for (i = 0; i < ARRAY_LEN(pri->mbox); ++i) { 07029 if (pri->mbox[i].sub) { 07030 pri->mbox[i].sub = ast_event_unsubscribe(pri->mbox[i].sub); 07031 } 07032 } 07033 #endif /* defined(HAVE_PRI_MWI) */ 07034 07035 ast_mutex_init(&pri->lock); 07036 sig_pri_sort_pri_chans(pri); 07037 07038 #if defined(HAVE_PRI_MWI) 07039 /* 07040 * Split the mwi_mailboxes configuration string into the mbox[]: 07041 * mailbox_number[@context]{,mailbox_number[@context]} 07042 */ 07043 i = 0; 07044 saveptr = pri->mwi_mailboxes; 07045 while (i < ARRAY_LEN(pri->mbox)) { 07046 mbox_number = strsep(&saveptr, ","); 07047 if (!mbox_number) { 07048 break; 07049 } 07050 /* Split the mailbox_number and context */ 07051 mbox_context = strchr(mbox_number, '@'); 07052 if (mbox_context) { 07053 *mbox_context++ = '\0'; 07054 mbox_context = ast_strip(mbox_context); 07055 } 07056 mbox_number = ast_strip(mbox_number); 07057 if (ast_strlen_zero(mbox_number)) { 07058 /* There is no mailbox number. Skip it. */ 07059 continue; 07060 } 07061 if (ast_strlen_zero(mbox_context)) { 07062 /* There was no context so use the default. */ 07063 mbox_context = "default"; 07064 } 07065 07066 /* Fill the mbox[] element. */ 07067 ast_str_set(&mwi_description, -1, "%s span %d[%d] MWI mailbox %s@%s", 07068 sig_pri_cc_type_name, pri->span, i, mbox_number, mbox_context); 07069 pri->mbox[i].sub = ast_event_subscribe(AST_EVENT_MWI, sig_pri_mwi_event_cb, 07070 ast_str_buffer(mwi_description), pri, 07071 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mbox_number, 07072 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, mbox_context, 07073 AST_EVENT_IE_END); 07074 if (!pri->mbox[i].sub) { 07075 ast_log(LOG_ERROR, "%s span %d could not subscribe to MWI events for %s@%s.", 07076 sig_pri_cc_type_name, pri->span, mbox_number, mbox_context); 07077 continue; 07078 } 07079 pri->mbox[i].number = mbox_number; 07080 pri->mbox[i].context = mbox_context; 07081 ++i; 07082 } 07083 #endif /* defined(HAVE_PRI_MWI) */ 07084 07085 for (i = 0; i < SIG_PRI_NUM_DCHANS; i++) { 07086 if (pri->fds[i] == -1) { 07087 break; 07088 } 07089 07090 switch (pri->sig) { 07091 case SIG_BRI: 07092 pri->dchans[i] = pri_new_bri(pri->fds[i], 1, pri->nodetype, pri->switchtype); 07093 break; 07094 case SIG_BRI_PTMP: 07095 pri->dchans[i] = pri_new_bri(pri->fds[i], 0, pri->nodetype, pri->switchtype); 07096 break; 07097 default: 07098 pri->dchans[i] = pri_new(pri->fds[i], pri->nodetype, pri->switchtype); 07099 #if defined(HAVE_PRI_SERVICE_MESSAGES) 07100 if (pri->enable_service_message_support) { 07101 pri_set_service_message_support(pri->dchans[i], 1); 07102 } 07103 #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */ 07104 break; 07105 } 07106 07107 pri_set_overlapdial(pri->dchans[i], (pri->overlapdial & DAHDI_OVERLAPDIAL_OUTGOING) ? 1 : 0); 07108 #ifdef HAVE_PRI_PROG_W_CAUSE 07109 pri_set_chan_mapping_logical(pri->dchans[i], pri->qsigchannelmapping == DAHDI_CHAN_MAPPING_LOGICAL); 07110 #endif 07111 #ifdef HAVE_PRI_INBANDDISCONNECT 07112 pri_set_inbanddisconnect(pri->dchans[i], pri->inbanddisconnect); 07113 #endif 07114 /* Enslave to master if appropriate */ 07115 if (i) 07116 pri_enslave(pri->dchans[0], pri->dchans[i]); 07117 if (!pri->dchans[i]) { 07118 if (pri->fds[i] > 0) 07119 close(pri->fds[i]); 07120 pri->fds[i] = -1; 07121 ast_log(LOG_ERROR, "Unable to create PRI structure\n"); 07122 return -1; 07123 } 07124 pri_set_debug(pri->dchans[i], SIG_PRI_DEBUG_DEFAULT); 07125 pri_set_nsf(pri->dchans[i], pri->nsf); 07126 #ifdef PRI_GETSET_TIMERS 07127 for (x = 0; x < PRI_MAX_TIMERS; x++) { 07128 if (pri->pritimers[x] != 0) 07129 pri_set_timer(pri->dchans[i], x, pri->pritimers[x]); 07130 } 07131 #endif 07132 } 07133 07134 /* Assume primary is the one we use */ 07135 pri->pri = pri->dchans[0]; 07136 07137 #if defined(HAVE_PRI_CALL_HOLD) 07138 pri_hold_enable(pri->pri, 1); 07139 #endif /* defined(HAVE_PRI_CALL_HOLD) */ 07140 #if defined(HAVE_PRI_CALL_REROUTING) 07141 pri_reroute_enable(pri->pri, 1); 07142 #endif /* defined(HAVE_PRI_CALL_REROUTING) */ 07143 #if defined(HAVE_PRI_HANGUP_FIX) 07144 pri_hangup_fix_enable(pri->pri, 1); 07145 #endif /* defined(HAVE_PRI_HANGUP_FIX) */ 07146 #if defined(HAVE_PRI_CCSS) 07147 pri_cc_enable(pri->pri, 1); 07148 pri_cc_recall_mode(pri->pri, pri->cc_ptmp_recall_mode); 07149 pri_cc_retain_signaling_req(pri->pri, pri->cc_qsig_signaling_link_req); 07150 pri_cc_retain_signaling_rsp(pri->pri, pri->cc_qsig_signaling_link_rsp); 07151 #endif /* defined(HAVE_PRI_CCSS) */ 07152 #if defined(HAVE_PRI_TRANSFER) 07153 pri_transfer_enable(pri->pri, 1); 07154 #endif /* defined(HAVE_PRI_TRANSFER) */ 07155 #if defined(HAVE_PRI_AOC_EVENTS) 07156 pri_aoc_events_enable(pri->pri, 1); 07157 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 07158 #if defined(HAVE_PRI_CALL_WAITING) 07159 pri_connect_ack_enable(pri->pri, 1); 07160 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 07161 #if defined(HAVE_PRI_MCID) 07162 pri_mcid_enable(pri->pri, 1); 07163 #endif /* defined(HAVE_PRI_MCID) */ 07164 07165 pri->resetpos = -1; 07166 if (ast_pthread_create_background(&pri->master, NULL, pri_dchannel, pri)) { 07167 for (i = 0; i < SIG_PRI_NUM_DCHANS; i++) { 07168 if (!pri->dchans[i]) 07169 break; 07170 if (pri->fds[i] > 0) 07171 close(pri->fds[i]); 07172 pri->fds[i] = -1; 07173 } 07174 ast_log(LOG_ERROR, "Unable to spawn D-channel: %s\n", strerror(errno)); 07175 return -1; 07176 } 07177 07178 #if defined(HAVE_PRI_MWI) 07179 /* 07180 * Send the initial MWI indications from the event cache for this span. 07181 * 07182 * If we were loaded after app_voicemail the event would already be in 07183 * the cache. If we were loaded before app_voicemail the event would not 07184 * be in the cache yet and app_voicemail will send the event when it 07185 * gets loaded. 07186 */ 07187 sig_pri_mwi_cache_update(pri); 07188 #endif /* defined(HAVE_PRI_MWI) */ 07189 07190 return 0; 07191 }
void sig_pri_stop_pri | ( | struct sig_pri_span * | pri | ) |
Stop PRI span.
pri | Asterisk D channel control structure. |
Definition at line 6950 of file sig_pri.c.
References ARRAY_LEN, and ast_event_unsubscribe().
Referenced by __unload_module().
06951 { 06952 #if defined(HAVE_PRI_MWI) 06953 int idx; 06954 #endif /* defined(HAVE_PRI_MWI) */ 06955 06956 #if defined(HAVE_PRI_MWI) 06957 for (idx = 0; idx < ARRAY_LEN(pri->mbox); ++idx) { 06958 if (pri->mbox[idx].sub) { 06959 pri->mbox[idx].sub = ast_event_unsubscribe(pri->mbox[idx].sub); 06960 } 06961 } 06962 #endif /* defined(HAVE_PRI_MWI) */ 06963 }
void sig_pri_unload | ( | void | ) |
Unload the sig_pri submodule.
Definition at line 7961 of file sig_pri.c.
References ao2_ref.
Referenced by __unload_module().
07962 { 07963 #if defined(HAVE_PRI_CCSS) 07964 if (sig_pri_cc_monitors) { 07965 ao2_ref(sig_pri_cc_monitors, -1); 07966 sig_pri_cc_monitors = NULL; 07967 } 07968 #endif /* defined(HAVE_PRI_CCSS) */ 07969 }
const char dahdi_db[] = "dahdi/registry" [static] |