#include "asterisk.h"
#include <errno.h>
#include <ctype.h>
#include <signal.h>
#include "asterisk/utils.h"
#include "asterisk/options.h"
#include "asterisk/pbx.h"
#include "asterisk/app.h"
#include "asterisk/file.h"
#include "asterisk/callerid.h"
#include "asterisk/say.h"
#include "asterisk/manager.h"
#include "asterisk/astdb.h"
#include "asterisk/causes.h"
#include "asterisk/musiconhold.h"
#include "asterisk/cli.h"
#include "asterisk/transcap.h"
#include "asterisk/features.h"
#include "asterisk/aoc.h"
#include "sig_pri.h"
Go to the source code of this file.
Data Structures | |
struct | sig_pri_cc_agent_prv |
struct | sig_pri_cc_monitor_instance |
struct | xfer_rsp_data |
Defines | |
#define | DCHAN_AVAILABLE (DCHAN_NOTINALARM | DCHAN_UP) |
#define | DCHAN_NOTINALARM (1 << 0) |
#define | DCHAN_UP (1 << 1) |
#define | FORCE_RESTART_UNAVAIL_CHANS 1 |
#define | PRI_CHANNEL(p) ((p) & 0xff) |
#define | PRI_CIS_CALL (1 << 17) |
#define | PRI_EXPLICIT (1 << 16) |
#define | PRI_HELD_CALL (1 << 18) |
#define | PRI_SPAN(p) (((p) >> 8) & 0xff) |
#define | SIG_PRI_SC_HEADER "%-4s %4s %-4s %-4s %-10s %-4s %s\n" |
#define | SIG_PRI_SC_LINE "%4d %4d %-4s %-4s %-10s %-4s %s" |
Typedefs | |
typedef void(*) | xfer_rsp_callback (void *data, int is_successful) |
Protocol callback to indicate if transfer will happen. | |
Enumerations | |
enum | SIG_PRI_CALL_OPT_ARGS { OPT_ARG_KEYPAD = 0, OPT_ARG_AOC_REQUEST, OPT_ARG_ARRAY_SIZE } |
enum | SIG_PRI_CALL_OPT_FLAGS { OPT_KEYPAD = (1 << 0), OPT_REVERSE_CHARGE = (1 << 1), OPT_AOC_REQUEST = (1 << 2) } |
Functions | |
static void | apply_plan_to_existing_number (char *buf, size_t size, const struct sig_pri_span *pri, const char *number, int plan) |
static void | apply_plan_to_number (char *buf, size_t size, const struct sig_pri_span *pri, const char *number, int plan) |
static unsigned char | ast_pri_pack_hex_char (char c) |
static int | ast_pri_pack_hex_string (unsigned char *dst, char *src, int maxlen) |
static int | ast_to_pri_char_set (enum AST_PARTY_CHAR_SET ast_char_set) |
static int | ast_to_pri_presentation (int ast_presentation) |
static int | ast_to_pri_reason (enum AST_REDIRECTING_REASON ast_reason) |
static void | build_status (char *s, size_t len, int status, int active) |
static int | detect_aoc_e_subcmd (const struct pri_subcommands *subcmds) |
static char * | dialplan2str (int dialplan) |
static void * | do_idle_thread (void *v_pvt) |
static int | pri_active_dchan_index (struct sig_pri_span *pri) |
static void | pri_check_restart (struct sig_pri_span *pri) |
static void * | pri_dchannel (void *vpri) |
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) |
static void | pri_find_dchan (struct sig_pri_span *pri) |
static int | pri_find_empty_chan (struct sig_pri_span *pri, int backwards) |
static int | pri_find_empty_nobch (struct sig_pri_span *pri) |
static int | pri_find_fixup_principle (struct sig_pri_span *pri, int channel, q931_call *call) |
static int | pri_find_principle (struct sig_pri_span *pri, int channel, q931_call *call) |
static int | pri_find_principle_by_call (struct sig_pri_span *pri, q931_call *call) |
static int | pri_fixup_principle (struct sig_pri_span *pri, int principle, q931_call *call) |
static int | pri_grab (struct sig_pri_chan *p, struct sig_pri_span *pri) |
int | pri_is_up (struct sig_pri_span *pri) |
int | pri_maintenance_bservice (struct pri *pri, struct sig_pri_chan *p, int changestatus) |
static const char * | pri_order (int level) |
static void | pri_queue_control (struct sig_pri_span *pri, int chanpos, int subclass) |
static void | pri_queue_frame (struct sig_pri_span *pri, int chanpos, struct ast_frame *frame) |
static void | pri_rel (struct sig_pri_span *pri) |
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) |
static void * | pri_ss_thread (void *data) |
static enum AST_PARTY_CHAR_SET | pri_to_ast_char_set (int pri_char_set) |
static int | pri_to_ast_presentation (int pri_presentation) |
static enum AST_REDIRECTING_REASON | pri_to_ast_reason (int pri_reason) |
static unsigned int | PVT_TO_CHANNEL (struct sig_pri_chan *p) |
static char * | redirectingreason2str (int redirectingreason) |
static void | sig_pri_ami_channel_event (struct sig_pri_chan *p) |
int | sig_pri_answer (struct sig_pri_chan *p, struct ast_channel *ast) |
static enum ast_aoc_s_charged_item | sig_pri_aoc_charged_item_to_ast (enum PRI_AOC_CHARGED_ITEM value) |
static enum PRI_AOC_CHARGED_ITEM | sig_pri_aoc_charged_item_to_pri (enum PRI_AOC_CHARGED_ITEM value) |
static void | sig_pri_aoc_d_from_ast (struct sig_pri_chan *pvt, struct ast_aoc_decoded *decoded) |
static void | sig_pri_aoc_d_from_pri (const struct pri_subcmd_aoc_d *aoc_d, struct ast_channel *owner, int passthrough) |
static void | sig_pri_aoc_e_from_ast (struct sig_pri_chan *pvt, struct ast_aoc_decoded *decoded) |
static void | sig_pri_aoc_e_from_pri (const struct pri_subcmd_aoc_e *aoc_e, struct ast_channel *owner, int passthrough) |
static int | sig_pri_aoc_multiplier_from_ast (enum ast_aoc_currency_multiplier mult) |
static int | sig_pri_aoc_multiplier_from_pri (const int mult) |
static void | sig_pri_aoc_request_from_pri (const struct pri_subcmd_aoc_request *aoc_request, struct sig_pri_chan *pvt, q931_call *call) |
static void | sig_pri_aoc_s_from_ast (struct sig_pri_chan *pvt, struct ast_aoc_decoded *decoded) |
static void | sig_pri_aoc_s_from_pri (const struct pri_subcmd_aoc_s *aoc_s, struct ast_channel *owner, int passthrough) |
static enum ast_aoc_time_scale | sig_pri_aoc_scale_to_ast (enum PRI_AOC_TIME_SCALE value) |
static enum PRI_AOC_TIME_SCALE | sig_pri_aoc_scale_to_pri (enum ast_aoc_time_scale value) |
static int | sig_pri_attempt_transfer (struct sig_pri_span *pri, q931_call *call_1_pri, int call_1_held, q931_call *call_2_pri, int call_2_held, xfer_rsp_callback rsp_callback, void *data) |
int | sig_pri_available (struct sig_pri_chan **pvt, int is_specific_channel) |
static int | sig_pri_available_check (struct sig_pri_chan *pvt) |
int | sig_pri_call (struct sig_pri_chan *p, struct ast_channel *ast, char *rdest, int timeout, int layer1) |
static const char * | sig_pri_call_level2str (enum sig_pri_call_level level) |
int | sig_pri_cc_agent_callee_available (struct ast_cc_agent *agent) |
Alert the caller that it is time to try recalling. | |
static int | sig_pri_cc_agent_cmp_cc_id (void *obj, void *arg, int flags) |
void | sig_pri_cc_agent_destructor (struct ast_cc_agent *agent) |
Destroy private data on the agent. | |
int | sig_pri_cc_agent_init (struct ast_cc_agent *agent, struct sig_pri_chan *pvt_chan) |
PRI CC agent initialization. | |
int | sig_pri_cc_agent_party_b_free (struct ast_cc_agent *agent) |
Let the caller know that the callee has become free but that the caller cannot attempt to call back because he is either busy or there is congestion on his line. | |
void | sig_pri_cc_agent_req_rsp (struct ast_cc_agent *agent, enum ast_cc_agent_response_reason reason) |
Response to a CC request. | |
int | sig_pri_cc_agent_start_monitoring (struct ast_cc_agent *agent) |
Begin monitoring a busy device. | |
int | sig_pri_cc_agent_start_offer_timer (struct ast_cc_agent *agent) |
Start the offer timer. | |
int | sig_pri_cc_agent_status_req (struct ast_cc_agent *agent) |
Request the status of the agent's device. | |
int | sig_pri_cc_agent_stop_offer_timer (struct ast_cc_agent *agent) |
Stop the offer timer. | |
int | sig_pri_cc_agent_stop_ringing (struct ast_cc_agent *agent) |
Request for an agent's phone to stop ringing. | |
static int | sig_pri_cc_available (struct sig_pri_span *pri, int chanpos, long cc_id, enum ast_cc_service_type service) |
static void | sig_pri_cc_generic_check (struct sig_pri_span *pri, int chanpos, enum ast_cc_service_type service) |
static void | sig_pri_cc_link_canceled (struct sig_pri_span *pri, long cc_id, int is_agent) |
int | sig_pri_cc_monitor_cancel_available_timer (struct ast_cc_monitor *monitor, int *sched_id) |
Cancel the running available timer. | |
static int | sig_pri_cc_monitor_cmp_cc_id (void *obj, void *arg, int flags) |
void | sig_pri_cc_monitor_destructor (void *monitor_pvt) |
Destroy PRI private data on the monitor. | |
static int | sig_pri_cc_monitor_instance_cmp_fn (void *obj, void *arg, int flags) |
static void | sig_pri_cc_monitor_instance_destroy (void *data) |
static int | sig_pri_cc_monitor_instance_hash_fn (const void *obj, const int flags) |
static struct sig_pri_cc_monitor_instance * | sig_pri_cc_monitor_instance_init (int core_id, struct sig_pri_span *pri, long cc_id, const char *device_name) |
int | sig_pri_cc_monitor_req_cc (struct ast_cc_monitor *monitor, int *available_timer_id) |
Request CCSS. | |
int | sig_pri_cc_monitor_status_rsp (struct ast_cc_monitor *monitor, enum ast_device_state devstate) |
Status response to an ast_cc_monitor_status_request(). | |
int | sig_pri_cc_monitor_suspend (struct ast_cc_monitor *monitor) |
Suspend monitoring. | |
int | sig_pri_cc_monitor_unsuspend (struct ast_cc_monitor *monitor) |
Unsuspend monitoring. | |
void | sig_pri_chan_alarm_notify (struct sig_pri_chan *p, int noalarm) |
Notify new alarm status. | |
void | sig_pri_chan_delete (struct sig_pri_chan *doomed) |
Delete the sig_pri private channel structure. | |
sig_pri_chan * | sig_pri_chan_new (void *pvt_data, struct sig_pri_callback *callback, struct sig_pri_span *pri, int logicalspan, int channo, int trunkgroup) |
void | sig_pri_cli_show_channels (int fd, struct sig_pri_span *pri) |
void | sig_pri_cli_show_channels_header (int fd) |
void | sig_pri_cli_show_span (int fd, int *dchannels, struct sig_pri_span *pri) |
void | sig_pri_cli_show_spans (int fd, int span, struct sig_pri_span *pri) |
static int | sig_pri_cmp_pri_chans (const void *left, const void *right) |
static struct sig_pri_chan * | sig_pri_cw_available (struct sig_pri_span *pri) |
void | sig_pri_dial_complete (struct sig_pri_chan *pvt, struct ast_channel *ast) |
DTMF dial string complete. | |
static void | sig_pri_dial_digits (struct sig_pri_chan *p, const char *dial_string) |
int | sig_pri_digit_begin (struct sig_pri_chan *pvt, struct ast_channel *ast, char digit) |
static void | sig_pri_dsp_reset_and_flush_digits (struct sig_pri_chan *p) |
static void | sig_pri_event_party_id (struct ast_str **msg, const char *prefix, struct ast_party_id *party) |
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. | |
static struct ast_cc_agent * | sig_pri_find_cc_agent_by_cc_id (struct sig_pri_span *pri, long cc_id) |
static struct sig_pri_cc_monitor_instance * | sig_pri_find_cc_monitor_by_cc_id (struct sig_pri_span *pri, long cc_id) |
void | sig_pri_fixup (struct ast_channel *oldchan, struct ast_channel *newchan, struct sig_pri_chan *pchan) |
static void | sig_pri_fixup_chans (struct sig_pri_chan *old_chan, struct sig_pri_chan *new_chan) |
static const char * | sig_pri_get_orig_dialstring (struct sig_pri_chan *p) |
static void | sig_pri_handle_cis_subcmds (struct sig_pri_span *pri, int event_id, const struct pri_subcommands *subcmds, q931_call *call_rsp) |
static void | sig_pri_handle_dchan_exception (struct sig_pri_span *pri, int index) |
static int | sig_pri_handle_hold (struct sig_pri_span *pri, pri_event *ev) |
static void | sig_pri_handle_retrieve (struct sig_pri_span *pri, pri_event *ev) |
static void | sig_pri_handle_subcmds (struct sig_pri_span *pri, int chanpos, int event_id, int channel, const struct pri_subcommands *subcmds, q931_call *call_rsp) |
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) |
static void | sig_pri_init_config (struct sig_pri_chan *pvt, struct sig_pri_span *pri) |
void | sig_pri_init_pri (struct sig_pri_span *pri) |
int | sig_pri_is_alarm_ignored (struct sig_pri_span *pri) |
Determine if layer 1 alarms are ignored. | |
int | sig_pri_is_chan_available (struct sig_pri_chan *pvt) |
Determine if a private channel structure is available. | |
static int | sig_pri_is_chan_in_use (struct sig_pri_chan *pvt) |
static int | sig_pri_is_cis_call (int channel) |
static void | sig_pri_kill_call (struct sig_pri_span *pri, q931_call *call, int cause) |
int | sig_pri_load (const char *cc_type_name) |
Load the sig_pri submodule. | |
static void | sig_pri_lock_owner (struct sig_pri_span *pri, int chanpos) |
static void | sig_pri_lock_private (struct sig_pri_chan *p) |
static void | sig_pri_make_cc_dialstring (struct sig_pri_chan *p, char *buf, size_t buf_size) |
static void | sig_pri_mcid_event (struct sig_pri_span *pri, const struct pri_subcmd_mcid_req *mcid, struct ast_channel *owner) |
static int | sig_pri_msn_match (const char *msn_patterns, const char *exten) |
static void | sig_pri_mwi_cache_update (struct sig_pri_span *pri) |
static void | sig_pri_mwi_event_cb (const struct ast_event *event, void *userdata) |
static struct ast_channel * | sig_pri_new_ast_channel (struct sig_pri_chan *p, int state, int ulaw, int transfercapability, char *exten, const struct ast_channel *requestor) |
static void | sig_pri_open_media (struct sig_pri_chan *p) |
static void | sig_pri_party_id_convert (struct ast_party_id *ast_id, const struct pri_party_id *pri_id, struct sig_pri_span *pri) |
static void | sig_pri_party_id_from_ast (struct pri_party_id *pri_id, const struct ast_party_id *ast_id) |
static void | sig_pri_party_name_convert (struct ast_party_name *ast_name, const struct pri_party_name *pri_name) |
static void | sig_pri_party_name_from_ast (struct pri_party_name *pri_name, const struct ast_party_name *ast_name) |
static void | sig_pri_party_number_convert (struct ast_party_number *ast_number, const struct pri_party_number *pri_number, struct sig_pri_span *pri) |
static void | sig_pri_party_number_from_ast (struct pri_party_number *pri_number, const struct ast_party_number *ast_number) |
static void | sig_pri_party_subaddress_from_ast (struct pri_party_subaddress *pri_subaddress, const struct ast_party_subaddress *ast_subaddress) |
static int | sig_pri_play_tone (struct sig_pri_chan *p, enum sig_pri_tone tone) |
static void | sig_pri_redirecting_convert (struct ast_party_redirecting *ast_redirecting, const struct pri_party_redirecting *pri_redirecting, const struct ast_party_redirecting *ast_guide, struct sig_pri_span *pri) |
static void | sig_pri_redirecting_update (struct sig_pri_chan *pvt, struct ast_channel *ast) |
ast_channel * | sig_pri_request (struct sig_pri_chan *p, enum sig_pri_law law, const struct ast_channel *requestor, int transfercapability) |
static void | sig_pri_send_aoce_termination_request (struct sig_pri_span *pri, int chanpos, unsigned int ms) |
static void | sig_pri_send_mwi_indication (struct sig_pri_span *pri, const char *mbox_number, const char *mbox_context, int num_messages) |
void | sig_pri_set_alarm (struct sig_pri_chan *p, int in_alarm) |
static void | sig_pri_set_caller_id (struct sig_pri_chan *p) |
static void | sig_pri_set_dialing (struct sig_pri_chan *p, int is_dialing) |
static void | sig_pri_set_digital (struct sig_pri_chan *p, int is_digital) |
static void | sig_pri_set_dnid (struct sig_pri_chan *p, const char *dnid) |
static int | sig_pri_set_echocanceller (struct sig_pri_chan *p, int enable) |
static void | sig_pri_set_outgoing (struct sig_pri_chan *p, int is_outgoing) |
static void | sig_pri_set_rdnis (struct sig_pri_chan *p, const char *rdnis) |
static void | sig_pri_set_subaddress (struct ast_party_subaddress *ast_subaddress, const struct pri_party_subaddress *pri_subaddress) |
static void | sig_pri_sort_pri_chans (struct sig_pri_span *pri) |
static void | sig_pri_span_devstate_changed (struct sig_pri_span *pri) |
int | sig_pri_start_pri (struct sig_pri_span *pri) |
void | sig_pri_stop_pri (struct sig_pri_span *pri) |
Stop PRI span. | |
static void | sig_pri_transfer_rsp (void *data, int is_successful) |
void | sig_pri_unload (void) |
Unload the sig_pri submodule. | |
static void | sig_pri_unlock_private (struct sig_pri_chan *p) |
Variables | |
static int | pri_gendigittimeout = 8000 |
static int | pri_matchdigittimeout = 3000 |
static struct ast_app_option | sig_pri_call_opts [128] = { [ 'K' ] = { .flag = OPT_KEYPAD , .arg_index = OPT_ARG_KEYPAD + 1 }, [ 'R' ] = { .flag = OPT_REVERSE_CHARGE }, [ 'A' ] = { .flag = OPT_AOC_REQUEST , .arg_index = OPT_ARG_AOC_REQUEST + 1 }, } |
static struct ao2_container * | sig_pri_cc_monitors |
static const char * | sig_pri_cc_type_name |
Definition in file sig_pri.c.
#define DCHAN_AVAILABLE (DCHAN_NOTINALARM | DCHAN_UP) |
#define DCHAN_NOTINALARM (1 << 0) |
Definition at line 108 of file sig_pri.c.
Referenced by build_status(), pri_event_alarm(), and pri_event_noalarm().
#define DCHAN_UP (1 << 1) |
#define FORCE_RESTART_UNAVAIL_CHANS 1 |
#define PRI_CHANNEL | ( | p | ) | ((p) & 0xff) |
Definition at line 112 of file sig_pri.c.
Referenced by pri_find_fixup_principle(), pri_find_principle(), sig_pri_handle_retrieve(), and sig_pri_handle_subcmds().
#define PRI_CIS_CALL (1 << 17) |
#define PRI_EXPLICIT (1 << 16) |
#define PRI_HELD_CALL (1 << 18) |
Definition at line 116 of file sig_pri.c.
Referenced by pri_find_principle(), and sig_pri_handle_retrieve().
#define PRI_SPAN | ( | p | ) | (((p) >> 8) & 0xff) |
Definition at line 113 of file sig_pri.c.
Referenced by pri_find_fixup_principle(), pri_maintenance_bservice(), and sig_pri_handle_subcmds().
#define SIG_PRI_SC_HEADER "%-4s %4s %-4s %-4s %-10s %-4s %s\n" |
#define SIG_PRI_SC_LINE "%4d %4d %-4s %-4s %-10s %-4s %s" |
typedef void(*) xfer_rsp_callback(void *data, int is_successful) |
Definition at line 6549 of file sig_pri.c.
06549 { 06550 OPT_ARG_KEYPAD = 0, 06551 OPT_ARG_AOC_REQUEST, 06552 06553 /* note: this entry _MUST_ be the last one in the enum */ 06554 OPT_ARG_ARRAY_SIZE, 06555 };
Definition at line 6544 of file sig_pri.c.
06544 { 06545 OPT_KEYPAD = (1 << 0), 06546 OPT_REVERSE_CHARGE = (1 << 1), /* Collect call */ 06547 OPT_AOC_REQUEST = (1 << 2), /* AOC Request */ 06548 };
static void apply_plan_to_existing_number | ( | char * | buf, | |
size_t | size, | |||
const struct sig_pri_span * | pri, | |||
const char * | number, | |||
int | plan | |||
) | [static] |
Definition at line 1663 of file sig_pri.c.
References apply_plan_to_number(), ast_strlen_zero(), and sig_pri_chan::pri.
Referenced by sig_pri_party_number_convert().
01664 { 01665 /* Make sure a number exists so the prefix isn't placed on an empty string. */ 01666 if (ast_strlen_zero(number)) { 01667 if (size) { 01668 *buf = '\0'; 01669 } 01670 return; 01671 } 01672 apply_plan_to_number(buf, size, pri, number, plan); 01673 }
static void apply_plan_to_number | ( | char * | buf, | |
size_t | size, | |||
const struct sig_pri_span * | pri, | |||
const char * | number, | |||
int | plan | |||
) | [static] |
Definition at line 1627 of file sig_pri.c.
References sig_pri_span::internationalprefix, sig_pri_span::localprefix, sig_pri_span::nationalprefix, sig_pri_chan::pri, sig_pri_span::privateprefix, and sig_pri_span::unknownprefix.
Referenced by apply_plan_to_existing_number().
01628 { 01629 switch (plan) { 01630 case PRI_INTERNATIONAL_ISDN: /* Q.931 dialplan == 0x11 international dialplan => prepend international prefix digits */ 01631 snprintf(buf, size, "%s%s", pri->internationalprefix, number); 01632 break; 01633 case PRI_NATIONAL_ISDN: /* Q.931 dialplan == 0x21 national dialplan => prepend national prefix digits */ 01634 snprintf(buf, size, "%s%s", pri->nationalprefix, number); 01635 break; 01636 case PRI_LOCAL_ISDN: /* Q.931 dialplan == 0x41 local dialplan => prepend local prefix digits */ 01637 snprintf(buf, size, "%s%s", pri->localprefix, number); 01638 break; 01639 case PRI_PRIVATE: /* Q.931 dialplan == 0x49 private dialplan => prepend private prefix digits */ 01640 snprintf(buf, size, "%s%s", pri->privateprefix, number); 01641 break; 01642 case PRI_UNKNOWN: /* Q.931 dialplan == 0x00 unknown dialplan => prepend unknown prefix digits */ 01643 snprintf(buf, size, "%s%s", pri->unknownprefix, number); 01644 break; 01645 default: /* other Q.931 dialplan => don't twiddle with callingnum */ 01646 snprintf(buf, size, "%s", number); 01647 break; 01648 } 01649 }
static unsigned char ast_pri_pack_hex_char | ( | char | c | ) | [static] |
Definition at line 695 of file sig_pri.c.
Referenced by ast_pri_pack_hex_string().
00696 { 00697 unsigned char res; 00698 00699 if (c < '0') { 00700 res = 0; 00701 } else if (c < ('9' + 1)) { 00702 res = c - '0'; 00703 } else if (c < 'A') { 00704 res = 0; 00705 } else if (c < ('F' + 1)) { 00706 res = c - 'A' + 10; 00707 } else if (c < 'a') { 00708 res = 0; 00709 } else if (c < ('f' + 1)) { 00710 res = c - 'a' + 10; 00711 } else { 00712 res = 0; 00713 } 00714 return res; 00715 }
static int ast_pri_pack_hex_string | ( | unsigned char * | dst, | |
char * | src, | |||
int | maxlen | |||
) | [static] |
Definition at line 734 of file sig_pri.c.
References ast_pri_pack_hex_char(), and len().
Referenced by sig_pri_party_subaddress_from_ast().
00735 { 00736 int res = 0; 00737 int len = strlen(src); 00738 00739 if (len > (2 * maxlen)) { 00740 len = 2 * maxlen; 00741 } 00742 00743 res = len / 2 + len % 2; 00744 00745 while (len > 1) { 00746 *dst = ast_pri_pack_hex_char(*src) << 4; 00747 src++; 00748 *dst |= ast_pri_pack_hex_char(*src); 00749 dst++, src++; 00750 len -= 2; 00751 } 00752 if (len) { /* 1 left */ 00753 *dst = ast_pri_pack_hex_char(*src) << 4; 00754 } 00755 return res; 00756 }
static int ast_to_pri_char_set | ( | enum AST_PARTY_CHAR_SET | ast_char_set | ) | [static] |
Definition at line 597 of file sig_pri.c.
References AST_PARTY_CHAR_SET_ISO10646_BMPSTRING, AST_PARTY_CHAR_SET_ISO10646_UTF_8STRING, AST_PARTY_CHAR_SET_ISO8859_1, AST_PARTY_CHAR_SET_ISO8859_2, AST_PARTY_CHAR_SET_ISO8859_3, AST_PARTY_CHAR_SET_ISO8859_4, AST_PARTY_CHAR_SET_ISO8859_5, AST_PARTY_CHAR_SET_ISO8859_7, AST_PARTY_CHAR_SET_UNKNOWN, and AST_PARTY_CHAR_SET_WITHDRAWN.
Referenced by sig_pri_party_name_from_ast().
00598 { 00599 int pri_char_set; 00600 00601 switch (ast_char_set) { 00602 default: 00603 case AST_PARTY_CHAR_SET_UNKNOWN: 00604 pri_char_set = PRI_CHAR_SET_UNKNOWN; 00605 break; 00606 case AST_PARTY_CHAR_SET_ISO8859_1: 00607 pri_char_set = PRI_CHAR_SET_ISO8859_1; 00608 break; 00609 case AST_PARTY_CHAR_SET_WITHDRAWN: 00610 pri_char_set = PRI_CHAR_SET_WITHDRAWN; 00611 break; 00612 case AST_PARTY_CHAR_SET_ISO8859_2: 00613 pri_char_set = PRI_CHAR_SET_ISO8859_2; 00614 break; 00615 case AST_PARTY_CHAR_SET_ISO8859_3: 00616 pri_char_set = PRI_CHAR_SET_ISO8859_3; 00617 break; 00618 case AST_PARTY_CHAR_SET_ISO8859_4: 00619 pri_char_set = PRI_CHAR_SET_ISO8859_4; 00620 break; 00621 case AST_PARTY_CHAR_SET_ISO8859_5: 00622 pri_char_set = PRI_CHAR_SET_ISO8859_5; 00623 break; 00624 case AST_PARTY_CHAR_SET_ISO8859_7: 00625 pri_char_set = PRI_CHAR_SET_ISO8859_7; 00626 break; 00627 case AST_PARTY_CHAR_SET_ISO10646_BMPSTRING: 00628 pri_char_set = PRI_CHAR_SET_ISO10646_BMPSTRING; 00629 break; 00630 case AST_PARTY_CHAR_SET_ISO10646_UTF_8STRING: 00631 pri_char_set = PRI_CHAR_SET_ISO10646_UTF_8STRING; 00632 break; 00633 } 00634 00635 return pri_char_set; 00636 }
static int ast_to_pri_presentation | ( | int | ast_presentation | ) | [static] |
Definition at line 492 of file sig_pri.c.
References AST_PRES_ALLOWED, AST_PRES_NETWORK_NUMBER, AST_PRES_RESTRICTED, AST_PRES_UNAVAILABLE, AST_PRES_USER_NUMBER_FAILED_SCREEN, AST_PRES_USER_NUMBER_PASSED_SCREEN, and AST_PRES_USER_NUMBER_UNSCREENED.
Referenced by sig_pri_party_name_from_ast(), and sig_pri_party_number_from_ast().
00493 { 00494 int pri_presentation; 00495 00496 switch (ast_presentation) { 00497 case AST_PRES_ALLOWED | AST_PRES_USER_NUMBER_UNSCREENED: 00498 pri_presentation = PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_UNSCREENED; 00499 break; 00500 case AST_PRES_ALLOWED | AST_PRES_USER_NUMBER_PASSED_SCREEN: 00501 pri_presentation = PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_PASSED_SCREEN; 00502 break; 00503 case AST_PRES_ALLOWED | AST_PRES_USER_NUMBER_FAILED_SCREEN: 00504 pri_presentation = PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_FAILED_SCREEN; 00505 break; 00506 case AST_PRES_ALLOWED | AST_PRES_NETWORK_NUMBER: 00507 pri_presentation = PRI_PRES_ALLOWED | PRI_PRES_NETWORK_NUMBER; 00508 break; 00509 00510 case AST_PRES_RESTRICTED | AST_PRES_USER_NUMBER_UNSCREENED: 00511 pri_presentation = PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_UNSCREENED; 00512 break; 00513 case AST_PRES_RESTRICTED | AST_PRES_USER_NUMBER_PASSED_SCREEN: 00514 pri_presentation = PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_PASSED_SCREEN; 00515 break; 00516 case AST_PRES_RESTRICTED | AST_PRES_USER_NUMBER_FAILED_SCREEN: 00517 pri_presentation = PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_FAILED_SCREEN; 00518 break; 00519 case AST_PRES_RESTRICTED | AST_PRES_NETWORK_NUMBER: 00520 pri_presentation = PRI_PRES_RESTRICTED | PRI_PRES_NETWORK_NUMBER; 00521 break; 00522 00523 case AST_PRES_UNAVAILABLE | AST_PRES_USER_NUMBER_UNSCREENED: 00524 case AST_PRES_UNAVAILABLE | AST_PRES_USER_NUMBER_PASSED_SCREEN: 00525 case AST_PRES_UNAVAILABLE | AST_PRES_USER_NUMBER_FAILED_SCREEN: 00526 case AST_PRES_UNAVAILABLE | AST_PRES_NETWORK_NUMBER: 00527 pri_presentation = PRES_NUMBER_NOT_AVAILABLE; 00528 break; 00529 00530 default: 00531 pri_presentation = PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_UNSCREENED; 00532 break; 00533 } 00534 00535 return pri_presentation; 00536 }
static int ast_to_pri_reason | ( | enum AST_REDIRECTING_REASON | ast_reason | ) | [static] |
Definition at line 402 of file sig_pri.c.
References AST_REDIRECTING_REASON_DEFLECTION, AST_REDIRECTING_REASON_NO_ANSWER, AST_REDIRECTING_REASON_UNCONDITIONAL, AST_REDIRECTING_REASON_UNKNOWN, and AST_REDIRECTING_REASON_USER_BUSY.
Referenced by sig_pri_redirecting_update().
00403 { 00404 int pri_reason; 00405 00406 switch (ast_reason) { 00407 case AST_REDIRECTING_REASON_USER_BUSY: 00408 pri_reason = PRI_REDIR_FORWARD_ON_BUSY; 00409 break; 00410 case AST_REDIRECTING_REASON_NO_ANSWER: 00411 pri_reason = PRI_REDIR_FORWARD_ON_NO_REPLY; 00412 break; 00413 case AST_REDIRECTING_REASON_UNCONDITIONAL: 00414 pri_reason = PRI_REDIR_UNCONDITIONAL; 00415 break; 00416 case AST_REDIRECTING_REASON_DEFLECTION: 00417 pri_reason = PRI_REDIR_DEFLECTION; 00418 break; 00419 case AST_REDIRECTING_REASON_UNKNOWN: 00420 default: 00421 pri_reason = PRI_REDIR_UNKNOWN; 00422 break; 00423 } 00424 00425 return pri_reason; 00426 }
static void build_status | ( | char * | s, | |
size_t | len, | |||
int | status, | |||
int | active | |||
) | [static] |
Definition at line 7929 of file sig_pri.c.
References DCHAN_NOTINALARM.
Referenced by sig_pri_cli_show_span(), and sig_pri_cli_show_spans().
07930 { 07931 if (!s || len < 1) { 07932 return; 07933 } 07934 s[0] = '\0'; 07935 if (!(status & DCHAN_NOTINALARM)) 07936 strncat(s, "In Alarm, ", len - strlen(s) - 1); 07937 if (status & DCHAN_UP) 07938 strncat(s, "Up", len - strlen(s) - 1); 07939 else 07940 strncat(s, "Down", len - strlen(s) - 1); 07941 if (active) 07942 strncat(s, ", Active", len - strlen(s) - 1); 07943 else 07944 strncat(s, ", Standby", len - strlen(s) - 1); 07945 s[len - 1] = '\0'; 07946 }
static int detect_aoc_e_subcmd | ( | const struct pri_subcommands * | subcmds | ) | [static] |
Definition at line 4057 of file sig_pri.c.
04058 { 04059 int i; 04060 04061 if (!subcmds) { 04062 return 0; 04063 } 04064 for (i = 0; i < subcmds->counter_subcmd; ++i) { 04065 const struct pri_subcommand *subcmd = &subcmds->subcmd[i]; 04066 if (subcmd->cmd == PRI_SUBCMD_AOC_E) { 04067 return 1; 04068 } 04069 } 04070 return 0; 04071 }
static char* dialplan2str | ( | int | dialplan | ) | [static] |
Definition at line 1607 of file sig_pri.c.
Referenced by sig_pri_call().
01608 { 01609 if (dialplan == -1) { 01610 return("Dynamically set dialplan in ISDN"); 01611 } 01612 return (pri_plan2str(dialplan)); 01613 }
static void* do_idle_thread | ( | void * | v_pvt | ) | [static] |
Definition at line 1827 of file sig_pri.c.
References ast_call(), AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, ast_copy_string(), AST_FRAME_CONTROL, ast_frfree, ast_hangup(), ast_log(), ast_pbx_run(), ast_read(), ast_verb, ast_waitfor(), sig_pri_chan::channel, ast_channel::context, ast_channel::exten, f, sig_pri_span::idlecontext, sig_pri_span::idledial, sig_pri_span::idleext, LOG_WARNING, ast_channel::name, sig_pri_chan::owner, sig_pri_chan::pri, and ast_channel::priority.
Referenced by pri_dchannel().
01828 { 01829 struct sig_pri_chan *pvt = v_pvt; 01830 struct ast_channel *chan = pvt->owner; 01831 struct ast_frame *f; 01832 char ex[80]; 01833 /* Wait up to 30 seconds for an answer */ 01834 int newms, ms = 30000; 01835 01836 ast_verb(3, "Initiating idle call on channel %s\n", chan->name); 01837 snprintf(ex, sizeof(ex), "%d/%s", pvt->channel, pvt->pri->idledial); 01838 if (ast_call(chan, ex, 0)) { 01839 ast_log(LOG_WARNING, "Idle dial failed on '%s' to '%s'\n", chan->name, ex); 01840 ast_hangup(chan); 01841 return NULL; 01842 } 01843 while ((newms = ast_waitfor(chan, ms)) > 0) { 01844 f = ast_read(chan); 01845 if (!f) { 01846 /* Got hangup */ 01847 break; 01848 } 01849 if (f->frametype == AST_FRAME_CONTROL) { 01850 switch (f->subclass.integer) { 01851 case AST_CONTROL_ANSWER: 01852 /* Launch the PBX */ 01853 ast_copy_string(chan->exten, pvt->pri->idleext, sizeof(chan->exten)); 01854 ast_copy_string(chan->context, pvt->pri->idlecontext, sizeof(chan->context)); 01855 chan->priority = 1; 01856 ast_verb(4, "Idle channel '%s' answered, sending to %s@%s\n", chan->name, chan->exten, chan->context); 01857 ast_pbx_run(chan); 01858 /* It's already hungup, return immediately */ 01859 return NULL; 01860 case AST_CONTROL_BUSY: 01861 ast_verb(4, "Idle channel '%s' busy, waiting...\n", chan->name); 01862 break; 01863 case AST_CONTROL_CONGESTION: 01864 ast_verb(4, "Idle channel '%s' congested, waiting...\n", chan->name); 01865 break; 01866 }; 01867 } 01868 ast_frfree(f); 01869 ms = newms; 01870 } 01871 /* Hangup the channel since nothing happend */ 01872 ast_hangup(chan); 01873 return NULL; 01874 }
static int pri_active_dchan_index | ( | struct sig_pri_span * | pri | ) | [static] |
Definition at line 1053 of file sig_pri.c.
References ast_log(), sig_pri_span::dchans, LOG_WARNING, sig_pri_span::pri, and SIG_PRI_NUM_DCHANS.
01054 { 01055 int x; 01056 01057 for (x = 0; x < SIG_PRI_NUM_DCHANS; x++) { 01058 if ((pri->dchans[x] == pri->pri)) 01059 return x; 01060 } 01061 01062 ast_log(LOG_WARNING, "No active dchan found!\n"); 01063 return -1; 01064 }
static void pri_check_restart | ( | struct sig_pri_span * | pri | ) | [static] |
Definition at line 1685 of file sig_pri.c.
References ast_log(), sig_pri_span::lastreset, LOG_NOTICE, sig_pri_span::numchans, sig_pri_span::pri, sig_pri_chan::pri, PVT_TO_CHANNEL(), sig_pri_span::pvts, sig_pri_span::resetpos, sig_pri_span::resetting, sig_pri_chan::resetting, sig_pri_chan::service_status, sig_pri_is_chan_in_use(), SIG_PRI_RESET_ACTIVE, sig_pri_span_devstate_changed(), sig_pri_span::span, SRVST_FAREND, and SRVST_NEAREND.
Referenced by pri_dchannel().
01686 { 01687 #if defined(HAVE_PRI_SERVICE_MESSAGES) 01688 unsigned why; 01689 #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */ 01690 01691 for (++pri->resetpos; pri->resetpos < pri->numchans; ++pri->resetpos) { 01692 if (!pri->pvts[pri->resetpos] 01693 || pri->pvts[pri->resetpos]->no_b_channel 01694 || sig_pri_is_chan_in_use(pri->pvts[pri->resetpos])) { 01695 continue; 01696 } 01697 #if defined(HAVE_PRI_SERVICE_MESSAGES) 01698 why = pri->pvts[pri->resetpos]->service_status; 01699 if (why) { 01700 ast_log(LOG_NOTICE, 01701 "Span %d: channel %d out-of-service (reason: %s), not sending RESTART\n", 01702 pri->span, pri->pvts[pri->resetpos]->channel, 01703 (why & SRVST_FAREND) ? (why & SRVST_NEAREND) ? "both ends" : "far end" : "near end"); 01704 continue; 01705 } 01706 #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */ 01707 break; 01708 } 01709 if (pri->resetpos < pri->numchans) { 01710 /* Mark the channel as resetting and restart it */ 01711 pri->pvts[pri->resetpos]->resetting = SIG_PRI_RESET_ACTIVE; 01712 pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[pri->resetpos])); 01713 } else { 01714 pri->resetting = 0; 01715 time(&pri->lastreset); 01716 sig_pri_span_devstate_changed(pri); 01717 } 01718 }
static void* pri_dchannel | ( | void * | vpri | ) | [static] |
Definition at line 4585 of file sig_pri.c.
References ast_channel::_softhangup, sig_pri_chan::allocated, ast_copy_string(), ast_exists_extension(), AST_FORMAT_ULAW, ast_hangup(), ast_log(), AST_MAX_EXTENSION, ast_mutex_lock, ast_mutex_unlock, ast_pthread_create_background, AST_SOFTHANGUP_DEV, ast_strlen_zero(), ast_tv(), ast_tvcmp(), ast_tvdiff_ms(), ast_tvnow(), ast_tvsub(), ast_verb, ast_verbose, sig_pri_chan::channel, DCHAN_UP, sig_pri_span::dchanavail, sig_pri_span::dchans, sig_pri_span::debug, do_idle_thread(), errno, sig_pri_span::fds, sig_pri_span::idlecontext, sig_pri_span::idledial, sig_pri_span::idleext, sig_pri_chan::isidlecall, sig_pri_span::lastreset, len(), sig_pri_span::lock, LOG_WARNING, sig_pri_span::minidle, sig_pri_span::minunused, ast_channel::name, sig_pri_chan::no_b_channel, sig_pri_span::numchans, sig_pri_chan::owner, sig_pri_span::pri, pri_check_restart(), pri_is_up(), pri_order(), sig_pri_span::pvts, sig_pri_span::resetinterval, sig_pri_span::resetpos, sig_pri_span::resetting, sig_pri_span::sig, SIG_BRI_PTMP, sig_pri_handle_dchan_exception(), sig_pri_is_chan_available(), sig_pri_lock_private(), sig_pri_request(), sig_pri_span_devstate_changed(), sig_pri_unlock_private(), sig_pri_span::span, and sig_pri_span::switchtype.
04586 { 04587 struct sig_pri_span *pri = vpri; 04588 pri_event *e; 04589 struct pollfd fds[SIG_PRI_NUM_DCHANS]; 04590 int res; 04591 int chanpos = 0; 04592 int x; 04593 int law; 04594 struct ast_channel *c; 04595 struct timeval tv, lowest, *next; 04596 int doidling=0; 04597 char *cc; 04598 time_t t; 04599 int i, which=-1; 04600 int numdchans; 04601 pthread_t threadid; 04602 char ani2str[6]; 04603 char plancallingnum[AST_MAX_EXTENSION]; 04604 char plancallingani[AST_MAX_EXTENSION]; 04605 char calledtonstr[10]; 04606 struct timeval lastidle = { 0, 0 }; 04607 pthread_t p; 04608 struct ast_channel *idle; 04609 char idlen[80]; 04610 int nextidle = -1; 04611 int haveidles; 04612 int activeidles; 04613 unsigned int len; 04614 04615 gettimeofday(&lastidle, NULL); 04616 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); 04617 04618 if (!ast_strlen_zero(pri->idledial) && !ast_strlen_zero(pri->idleext)) { 04619 /* Need to do idle dialing, check to be sure though */ 04620 cc = strchr(pri->idleext, '@'); 04621 if (cc) { 04622 *cc = '\0'; 04623 cc++; 04624 ast_copy_string(pri->idlecontext, cc, sizeof(pri->idlecontext)); 04625 #if 0 04626 /* Extensions may not be loaded yet */ 04627 if (!ast_exists_extension(NULL, pri->idlecontext, pri->idleext, 1, NULL)) 04628 ast_log(LOG_WARNING, "Extension '%s @ %s' does not exist\n", pri->idleext, pri->idlecontext); 04629 else 04630 #endif 04631 doidling = 1; 04632 } else 04633 ast_log(LOG_WARNING, "Idle dial string '%s' lacks '@context'\n", pri->idleext); 04634 } 04635 for (;;) { 04636 for (i = 0; i < SIG_PRI_NUM_DCHANS; i++) { 04637 if (!pri->dchans[i]) 04638 break; 04639 fds[i].fd = pri->fds[i]; 04640 fds[i].events = POLLIN | POLLPRI; 04641 fds[i].revents = 0; 04642 } 04643 numdchans = i; 04644 time(&t); 04645 ast_mutex_lock(&pri->lock); 04646 if (pri->switchtype != PRI_SWITCH_GR303_TMC && (pri->sig != SIG_BRI_PTMP) && (pri->resetinterval > 0)) { 04647 if (pri->resetting && pri_is_up(pri)) { 04648 if (pri->resetpos < 0) { 04649 pri_check_restart(pri); 04650 if (pri->resetting) { 04651 sig_pri_span_devstate_changed(pri); 04652 } 04653 } 04654 } else { 04655 if (!pri->resetting && (t - pri->lastreset) >= pri->resetinterval) { 04656 pri->resetting = 1; 04657 pri->resetpos = -1; 04658 } 04659 } 04660 } 04661 /* Look for any idle channels if appropriate */ 04662 if (doidling && pri_is_up(pri)) { 04663 nextidle = -1; 04664 haveidles = 0; 04665 activeidles = 0; 04666 for (x = pri->numchans; x >= 0; x--) { 04667 if (pri->pvts[x] && !pri->pvts[x]->no_b_channel) { 04668 if (sig_pri_is_chan_available(pri->pvts[x])) { 04669 if (haveidles < pri->minunused) { 04670 haveidles++; 04671 } else { 04672 nextidle = x; 04673 break; 04674 } 04675 } else if (pri->pvts[x]->owner && pri->pvts[x]->isidlecall) { 04676 activeidles++; 04677 } 04678 } 04679 } 04680 if (nextidle > -1) { 04681 if (ast_tvdiff_ms(ast_tvnow(), lastidle) > 1000) { 04682 /* Don't create a new idle call more than once per second */ 04683 snprintf(idlen, sizeof(idlen), "%d/%s", pri->pvts[nextidle]->channel, pri->idledial); 04684 pri->pvts[nextidle]->allocated = 1; 04685 /* 04686 * Release the PRI lock while we create the channel so other 04687 * threads can send D channel messages. 04688 */ 04689 ast_mutex_unlock(&pri->lock); 04690 /* 04691 * We already have the B channel reserved for this call. We 04692 * just need to make sure that sig_pri_hangup() has completed 04693 * cleaning up before continuing. 04694 */ 04695 sig_pri_lock_private(pri->pvts[nextidle]); 04696 sig_pri_unlock_private(pri->pvts[nextidle]); 04697 idle = sig_pri_request(pri->pvts[nextidle], AST_FORMAT_ULAW, NULL, 0); 04698 ast_mutex_lock(&pri->lock); 04699 if (idle) { 04700 pri->pvts[nextidle]->isidlecall = 1; 04701 if (ast_pthread_create_background(&p, NULL, do_idle_thread, pri->pvts[nextidle])) { 04702 ast_log(LOG_WARNING, "Unable to start new thread for idle channel '%s'\n", idle->name); 04703 ast_mutex_unlock(&pri->lock); 04704 ast_hangup(idle); 04705 ast_mutex_lock(&pri->lock); 04706 } 04707 } else { 04708 pri->pvts[nextidle]->allocated = 0; 04709 ast_log(LOG_WARNING, "Unable to request channel 'DAHDI/%s' for idle call\n", idlen); 04710 } 04711 gettimeofday(&lastidle, NULL); 04712 } 04713 } else if ((haveidles < pri->minunused) && 04714 (activeidles > pri->minidle)) { 04715 /* Mark something for hangup if there is something 04716 that can be hungup */ 04717 for (x = pri->numchans; x >= 0; x--) { 04718 /* find a candidate channel */ 04719 if (pri->pvts[x] && pri->pvts[x]->owner && pri->pvts[x]->isidlecall) { 04720 pri->pvts[x]->owner->_softhangup |= AST_SOFTHANGUP_DEV; 04721 haveidles++; 04722 /* Stop if we have enough idle channels or 04723 can't spare any more active idle ones */ 04724 if ((haveidles >= pri->minunused) || 04725 (activeidles <= pri->minidle)) 04726 break; 04727 } 04728 } 04729 } 04730 } 04731 /* Start with reasonable max */ 04732 if (doidling || pri->resetting) { 04733 /* 04734 * Make sure we stop at least once per second if we're 04735 * monitoring idle channels 04736 */ 04737 lowest = ast_tv(1, 0); 04738 } else { 04739 /* Don't poll for more than 60 seconds */ 04740 lowest = ast_tv(60, 0); 04741 } 04742 for (i = 0; i < SIG_PRI_NUM_DCHANS; i++) { 04743 if (!pri->dchans[i]) { 04744 /* We scanned all D channels on this span. */ 04745 break; 04746 } 04747 next = pri_schedule_next(pri->dchans[i]); 04748 if (next) { 04749 /* We need relative time here */ 04750 tv = ast_tvsub(*next, ast_tvnow()); 04751 if (tv.tv_sec < 0) { 04752 /* 04753 * A timer has already expired. 04754 * By definition zero time is the lowest so we can quit early. 04755 */ 04756 lowest = ast_tv(0, 0); 04757 break; 04758 } 04759 if (ast_tvcmp(tv, lowest) < 0) { 04760 lowest = tv; 04761 } 04762 } 04763 } 04764 ast_mutex_unlock(&pri->lock); 04765 04766 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); 04767 pthread_testcancel(); 04768 e = NULL; 04769 res = poll(fds, numdchans, lowest.tv_sec * 1000 + lowest.tv_usec / 1000); 04770 pthread_testcancel(); 04771 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); 04772 04773 ast_mutex_lock(&pri->lock); 04774 if (!res) { 04775 for (which = 0; which < SIG_PRI_NUM_DCHANS; which++) { 04776 if (!pri->dchans[which]) 04777 break; 04778 /* Just a timeout, run the scheduler */ 04779 e = pri_schedule_run(pri->dchans[which]); 04780 if (e) 04781 break; 04782 } 04783 } else if (res > -1) { 04784 for (which = 0; which < SIG_PRI_NUM_DCHANS; which++) { 04785 if (!pri->dchans[which]) 04786 break; 04787 if (fds[which].revents & POLLPRI) { 04788 sig_pri_handle_dchan_exception(pri, which); 04789 } else if (fds[which].revents & POLLIN) { 04790 e = pri_check_event(pri->dchans[which]); 04791 } 04792 if (e) 04793 break; 04794 } 04795 } else if (errno != EINTR) 04796 ast_log(LOG_WARNING, "pri_event returned error %d (%s)\n", errno, strerror(errno)); 04797 04798 if (e) { 04799 if (pri->debug) { 04800 ast_verbose("Span %d: Processing event %s\n", 04801 pri->span, pri_event2str(e->e)); 04802 } 04803 04804 if (e->e != PRI_EVENT_DCHAN_DOWN) { 04805 if (!(pri->dchanavail[which] & DCHAN_UP)) { 04806 ast_verb(2, "%s D-Channel on span %d up\n", pri_order(which), pri->span); 04807 } 04808 pri->dchanavail[which] |= DCHAN_UP; 04809 } else { 04810 if (pri->dchanavail[which] & DCHAN_UP) { 04811 ast_verb(2, "%s D-Channel on span %d down\n", pri_order(which), pri->span); 04812 } 04813 pri->dchanavail[which] &= ~DCHAN_UP; 04814 } 04815 04816 if ((e->e != PRI_EVENT_DCHAN_UP) && (e->e != PRI_EVENT_DCHAN_DOWN) && (pri->pri != pri->dchans[which])) 04817 /* Must be an NFAS group that has the secondary dchan active */ 04818 pri->pri = pri->dchans[which]; 04819 04820 switch (e->e) { 04821 case PRI_EVENT_DCHAN_UP: 04822 pri->no_d_channels = 0; 04823 if (!pri->pri) { 04824 pri_find_dchan(pri); 04825 } 04826 04827 /* Note presense of D-channel */ 04828 time(&pri->lastreset); 04829 04830 /* Restart in 5 seconds */ 04831 if (pri->resetinterval > -1) { 04832 pri->lastreset -= pri->resetinterval; 04833 pri->lastreset += 5; 04834 } 04835 /* Take the channels from inalarm condition */ 04836 pri->resetting = 0; 04837 for (i = 0; i < pri->numchans; i++) { 04838 if (pri->pvts[i]) { 04839 sig_pri_set_alarm(pri->pvts[i], 0); 04840 } 04841 } 04842 sig_pri_span_devstate_changed(pri); 04843 break; 04844 case PRI_EVENT_DCHAN_DOWN: 04845 pri_find_dchan(pri); 04846 if (!pri_is_up(pri)) { 04847 if (pri->sig == SIG_BRI_PTMP) { 04848 /* 04849 * For PTMP connections with non-persistent layer 2 we want to 04850 * *not* declare inalarm unless there actually is an alarm. 04851 */ 04852 break; 04853 } 04854 /* Hangup active channels and put them in alarm mode */ 04855 pri->resetting = 0; 04856 for (i = 0; i < pri->numchans; i++) { 04857 struct sig_pri_chan *p = pri->pvts[i]; 04858 04859 if (p) { 04860 if (pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0) { 04861 /* T309 is not enabled : destroy calls when alarm occurs */ 04862 if (p->call) { 04863 pri_destroycall(p->pri->pri, p->call); 04864 p->call = NULL; 04865 } 04866 if (p->owner) 04867 p->owner->_softhangup |= AST_SOFTHANGUP_DEV; 04868 } 04869 sig_pri_set_alarm(p, 1); 04870 } 04871 } 04872 sig_pri_span_devstate_changed(pri); 04873 } 04874 break; 04875 case PRI_EVENT_RESTART: 04876 if (e->restart.channel > -1 && PRI_CHANNEL(e->restart.channel) != 0xFF) { 04877 chanpos = pri_find_principle(pri, e->restart.channel, NULL); 04878 if (chanpos < 0) 04879 ast_log(LOG_WARNING, 04880 "Span %d: Restart requested on odd/unavailable channel number %d/%d\n", 04881 pri->span, PRI_SPAN(e->restart.channel), 04882 PRI_CHANNEL(e->restart.channel)); 04883 else { 04884 int skipit = 0; 04885 #if defined(HAVE_PRI_SERVICE_MESSAGES) 04886 unsigned why; 04887 04888 why = pri->pvts[chanpos]->service_status; 04889 if (why) { 04890 ast_log(LOG_NOTICE, 04891 "Span %d: Channel %d/%d out-of-service (reason: %s), ignoring RESTART\n", 04892 pri->span, PRI_SPAN(e->restart.channel), 04893 PRI_CHANNEL(e->restart.channel), 04894 (why & SRVST_FAREND) ? (why & SRVST_NEAREND) ? "both ends" : "far end" : "near end"); 04895 skipit = 1; 04896 } 04897 #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */ 04898 sig_pri_lock_private(pri->pvts[chanpos]); 04899 if (!skipit) { 04900 ast_verb(3, "Span %d: Channel %d/%d restarted\n", pri->span, 04901 PRI_SPAN(e->restart.channel), 04902 PRI_CHANNEL(e->restart.channel)); 04903 if (pri->pvts[chanpos]->call) { 04904 pri_destroycall(pri->pri, pri->pvts[chanpos]->call); 04905 pri->pvts[chanpos]->call = NULL; 04906 } 04907 } 04908 /* Force soft hangup if appropriate */ 04909 if (pri->pvts[chanpos]->owner) 04910 pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV; 04911 sig_pri_unlock_private(pri->pvts[chanpos]); 04912 } 04913 } else { 04914 ast_verb(3, "Restart requested on entire span %d\n", pri->span); 04915 for (x = 0; x < pri->numchans; x++) 04916 if (pri->pvts[x]) { 04917 sig_pri_lock_private(pri->pvts[x]); 04918 if (pri->pvts[x]->call) { 04919 pri_destroycall(pri->pri, pri->pvts[x]->call); 04920 pri->pvts[x]->call = NULL; 04921 } 04922 if (pri->pvts[x]->owner) 04923 pri->pvts[x]->owner->_softhangup |= AST_SOFTHANGUP_DEV; 04924 sig_pri_unlock_private(pri->pvts[x]); 04925 } 04926 } 04927 sig_pri_span_devstate_changed(pri); 04928 break; 04929 case PRI_EVENT_KEYPAD_DIGIT: 04930 if (sig_pri_is_cis_call(e->digit.channel)) { 04931 sig_pri_handle_cis_subcmds(pri, e->e, e->digit.subcmds, 04932 e->digit.call); 04933 break; 04934 } 04935 chanpos = pri_find_principle_by_call(pri, e->digit.call); 04936 if (chanpos < 0) { 04937 ast_log(LOG_WARNING, 04938 "Span %d: Received keypad digits for unknown call.\n", pri->span); 04939 break; 04940 } 04941 sig_pri_lock_private(pri->pvts[chanpos]); 04942 sig_pri_handle_subcmds(pri, chanpos, e->e, e->digit.channel, 04943 e->digit.subcmds, e->digit.call); 04944 /* queue DTMF frame if the PBX for this call was already started (we're forwarding KEYPAD_DIGITs further on */ 04945 if ((pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING) 04946 && pri->pvts[chanpos]->owner) { 04947 /* how to do that */ 04948 int digitlen = strlen(e->digit.digits); 04949 int i; 04950 04951 for (i = 0; i < digitlen; i++) { 04952 struct ast_frame f = { AST_FRAME_DTMF, .subclass.integer = e->digit.digits[i], }; 04953 04954 pri_queue_frame(pri, chanpos, &f); 04955 } 04956 } 04957 sig_pri_unlock_private(pri->pvts[chanpos]); 04958 break; 04959 04960 case PRI_EVENT_INFO_RECEIVED: 04961 if (sig_pri_is_cis_call(e->ring.channel)) { 04962 sig_pri_handle_cis_subcmds(pri, e->e, e->ring.subcmds, 04963 e->ring.call); 04964 break; 04965 } 04966 chanpos = pri_find_principle_by_call(pri, e->ring.call); 04967 if (chanpos < 0) { 04968 ast_log(LOG_WARNING, 04969 "Span %d: Received INFORMATION for unknown call.\n", pri->span); 04970 break; 04971 } 04972 sig_pri_lock_private(pri->pvts[chanpos]); 04973 sig_pri_handle_subcmds(pri, chanpos, e->e, e->ring.channel, 04974 e->ring.subcmds, e->ring.call); 04975 /* queue DTMF frame if the PBX for this call was already started (we're forwarding INFORMATION further on */ 04976 if ((pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING) 04977 && pri->pvts[chanpos]->owner) { 04978 /* how to do that */ 04979 int digitlen = strlen(e->ring.callednum); 04980 int i; 04981 04982 for (i = 0; i < digitlen; i++) { 04983 struct ast_frame f = { AST_FRAME_DTMF, .subclass.integer = e->ring.callednum[i], }; 04984 04985 pri_queue_frame(pri, chanpos, &f); 04986 } 04987 } 04988 sig_pri_unlock_private(pri->pvts[chanpos]); 04989 break; 04990 #if defined(HAVE_PRI_SERVICE_MESSAGES) 04991 case PRI_EVENT_SERVICE: 04992 chanpos = pri_find_principle(pri, e->service.channel, NULL); 04993 if (chanpos < 0) { 04994 ast_log(LOG_WARNING, "Received service change status %d on unconfigured channel %d/%d span %d\n", 04995 e->service_ack.changestatus, PRI_SPAN(e->service_ack.channel), PRI_CHANNEL(e->service_ack.channel), pri->span); 04996 } else { 04997 char db_chan_name[20]; 04998 char db_answer[5]; 04999 int ch; 05000 unsigned *why; 05001 05002 ch = pri->pvts[chanpos]->channel; 05003 snprintf(db_chan_name, sizeof(db_chan_name), "%s/%d:%d", dahdi_db, pri->span, ch); 05004 why = &pri->pvts[chanpos]->service_status; 05005 switch (e->service.changestatus) { 05006 case 0: /* in-service */ 05007 /* Far end wants to be in service now. */ 05008 ast_db_del(db_chan_name, SRVST_DBKEY); 05009 *why &= ~SRVST_FAREND; 05010 if (*why) { 05011 snprintf(db_answer, sizeof(db_answer), "%s:%u", 05012 SRVST_TYPE_OOS, *why); 05013 ast_db_put(db_chan_name, SRVST_DBKEY, db_answer); 05014 } else { 05015 sig_pri_span_devstate_changed(pri); 05016 } 05017 break; 05018 case 2: /* out-of-service */ 05019 /* Far end wants to be out-of-service now. */ 05020 ast_db_del(db_chan_name, SRVST_DBKEY); 05021 *why |= SRVST_FAREND; 05022 snprintf(db_answer, sizeof(db_answer), "%s:%u", SRVST_TYPE_OOS, 05023 *why); 05024 ast_db_put(db_chan_name, SRVST_DBKEY, db_answer); 05025 sig_pri_span_devstate_changed(pri); 05026 break; 05027 default: 05028 ast_log(LOG_ERROR, "Huh? changestatus is: %d\n", e->service.changestatus); 05029 break; 05030 } 05031 ast_log(LOG_NOTICE, "Channel %d/%d span %d (logical: %d) received a change of service message, status '%d'\n", 05032 PRI_SPAN(e->service.channel), PRI_CHANNEL(e->service.channel), pri->span, ch, e->service.changestatus); 05033 } 05034 break; 05035 case PRI_EVENT_SERVICE_ACK: 05036 chanpos = pri_find_principle(pri, e->service_ack.channel, NULL); 05037 if (chanpos < 0) { 05038 ast_log(LOG_WARNING, "Received service acknowledge change status '%d' on unconfigured channel %d/%d span %d\n", 05039 e->service_ack.changestatus, PRI_SPAN(e->service_ack.channel), PRI_CHANNEL(e->service_ack.channel), pri->span); 05040 } else { 05041 ast_debug(2, "Channel %d/%d span %d received a change os service acknowledgement message, status '%d'\n", 05042 PRI_SPAN(e->service_ack.channel), PRI_CHANNEL(e->service_ack.channel), pri->span, e->service_ack.changestatus); 05043 } 05044 break; 05045 #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */ 05046 case PRI_EVENT_RING: 05047 if (!ast_strlen_zero(pri->msn_list) 05048 && !sig_pri_msn_match(pri->msn_list, e->ring.callednum)) { 05049 /* The call is not for us so ignore it. */ 05050 ast_verb(3, 05051 "Ignoring call to '%s' on span %d. Its not in the MSN list: %s\n", 05052 e->ring.callednum, pri->span, pri->msn_list); 05053 pri_destroycall(pri->pri, e->ring.call); 05054 break; 05055 } 05056 if (sig_pri_is_cis_call(e->ring.channel)) { 05057 sig_pri_handle_cis_subcmds(pri, e->e, e->ring.subcmds, 05058 e->ring.call); 05059 break; 05060 } 05061 chanpos = pri_find_principle_by_call(pri, e->ring.call); 05062 if (-1 < chanpos) { 05063 /* Libpri has already filtered out duplicate SETUPs. */ 05064 ast_log(LOG_WARNING, 05065 "Span %d: Got SETUP with duplicate call ptr (%p). Dropping call.\n", 05066 pri->span, e->ring.call); 05067 pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_NORMAL_TEMPORARY_FAILURE); 05068 break; 05069 } 05070 if (e->ring.channel == -1 || PRI_CHANNEL(e->ring.channel) == 0xFF) { 05071 /* Any channel requested. */ 05072 chanpos = pri_find_empty_chan(pri, 1); 05073 } else if (PRI_CHANNEL(e->ring.channel) == 0x00) { 05074 /* No channel specified. */ 05075 #if defined(HAVE_PRI_CALL_WAITING) 05076 if (!pri->allow_call_waiting_calls) 05077 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 05078 { 05079 /* We will not accept incoming call waiting calls. */ 05080 pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION); 05081 break; 05082 } 05083 #if defined(HAVE_PRI_CALL_WAITING) 05084 chanpos = pri_find_empty_nobch(pri); 05085 if (chanpos < 0) { 05086 /* We could not find/create a call interface. */ 05087 pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION); 05088 break; 05089 } 05090 /* Setup the call interface to use. */ 05091 sig_pri_init_config(pri->pvts[chanpos], pri); 05092 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 05093 } else { 05094 /* A channel is specified. */ 05095 chanpos = pri_find_principle(pri, e->ring.channel, e->ring.call); 05096 if (chanpos < 0) { 05097 ast_log(LOG_WARNING, 05098 "Span %d: SETUP on unconfigured channel %d/%d\n", 05099 pri->span, PRI_SPAN(e->ring.channel), 05100 PRI_CHANNEL(e->ring.channel)); 05101 } else { 05102 switch (pri->pvts[chanpos]->resetting) { 05103 case SIG_PRI_RESET_IDLE: 05104 break; 05105 case SIG_PRI_RESET_ACTIVE: 05106 /* 05107 * The peer may have lost the expected ack or not received the 05108 * RESTART yet. 05109 */ 05110 pri->pvts[chanpos]->resetting = SIG_PRI_RESET_NO_ACK; 05111 break; 05112 case SIG_PRI_RESET_NO_ACK: 05113 /* The peer likely is not going to ack the RESTART. */ 05114 ast_debug(1, 05115 "Span %d: Second SETUP while waiting for RESTART ACKNOWLEDGE on channel %d/%d\n", 05116 pri->span, PRI_SPAN(e->ring.channel), 05117 PRI_CHANNEL(e->ring.channel)); 05118 05119 /* Assume we got the ack. */ 05120 pri->pvts[chanpos]->resetting = SIG_PRI_RESET_IDLE; 05121 if (pri->resetting) { 05122 /* Go on to the next idle channel to RESTART. */ 05123 pri_check_restart(pri); 05124 } 05125 break; 05126 } 05127 if (!sig_pri_is_chan_available(pri->pvts[chanpos])) { 05128 /* This is where we handle initial glare */ 05129 ast_debug(1, 05130 "Span %d: SETUP requested unavailable channel %d/%d. Attempting to renegotiate.\n", 05131 pri->span, PRI_SPAN(e->ring.channel), 05132 PRI_CHANNEL(e->ring.channel)); 05133 chanpos = -1; 05134 } 05135 } 05136 #if defined(ALWAYS_PICK_CHANNEL) 05137 if (e->ring.flexible) { 05138 chanpos = -1; 05139 } 05140 #endif /* defined(ALWAYS_PICK_CHANNEL) */ 05141 if (chanpos < 0 && e->ring.flexible) { 05142 /* We can try to pick another channel. */ 05143 chanpos = pri_find_empty_chan(pri, 1); 05144 } 05145 } 05146 if (chanpos < 0) { 05147 if (e->ring.flexible) { 05148 pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION); 05149 } else { 05150 pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_REQUESTED_CHAN_UNAVAIL); 05151 } 05152 break; 05153 } 05154 05155 sig_pri_lock_private(pri->pvts[chanpos]); 05156 05157 /* Mark channel as in use so noone else will steal it. */ 05158 pri->pvts[chanpos]->call = e->ring.call; 05159 05160 /* Use plancallingnum as a scratch buffer since it is initialized next. */ 05161 apply_plan_to_existing_number(plancallingnum, sizeof(plancallingnum), pri, 05162 e->ring.redirectingnum, e->ring.callingplanrdnis); 05163 sig_pri_set_rdnis(pri->pvts[chanpos], plancallingnum); 05164 05165 /* Setup caller-id info */ 05166 apply_plan_to_existing_number(plancallingnum, sizeof(plancallingnum), pri, 05167 e->ring.callingnum, e->ring.callingplan); 05168 pri->pvts[chanpos]->cid_ani2 = 0; 05169 if (pri->pvts[chanpos]->use_callerid) { 05170 ast_shrink_phone_number(plancallingnum); 05171 ast_copy_string(pri->pvts[chanpos]->cid_num, plancallingnum, sizeof(pri->pvts[chanpos]->cid_num)); 05172 #ifdef PRI_ANI 05173 apply_plan_to_existing_number(plancallingani, sizeof(plancallingani), 05174 pri, e->ring.callingani, e->ring.callingplanani); 05175 ast_shrink_phone_number(plancallingani); 05176 ast_copy_string(pri->pvts[chanpos]->cid_ani, plancallingani, 05177 sizeof(pri->pvts[chanpos]->cid_ani)); 05178 #endif 05179 pri->pvts[chanpos]->cid_subaddr[0] = '\0'; 05180 #if defined(HAVE_PRI_SUBADDR) 05181 if (e->ring.calling.subaddress.valid) { 05182 struct ast_party_subaddress calling_subaddress; 05183 05184 ast_party_subaddress_init(&calling_subaddress); 05185 sig_pri_set_subaddress(&calling_subaddress, 05186 &e->ring.calling.subaddress); 05187 if (calling_subaddress.str) { 05188 ast_copy_string(pri->pvts[chanpos]->cid_subaddr, 05189 calling_subaddress.str, 05190 sizeof(pri->pvts[chanpos]->cid_subaddr)); 05191 } 05192 ast_party_subaddress_free(&calling_subaddress); 05193 } 05194 #endif /* defined(HAVE_PRI_SUBADDR) */ 05195 ast_copy_string(pri->pvts[chanpos]->cid_name, e->ring.callingname, sizeof(pri->pvts[chanpos]->cid_name)); 05196 pri->pvts[chanpos]->cid_ton = e->ring.callingplan; /* this is the callingplan (TON/NPI), e->ring.callingplan>>4 would be the TON */ 05197 pri->pvts[chanpos]->callingpres = e->ring.callingpres; 05198 if (e->ring.ani2 >= 0) { 05199 pri->pvts[chanpos]->cid_ani2 = e->ring.ani2; 05200 } 05201 } else { 05202 pri->pvts[chanpos]->cid_num[0] = '\0'; 05203 pri->pvts[chanpos]->cid_subaddr[0] = '\0'; 05204 pri->pvts[chanpos]->cid_ani[0] = '\0'; 05205 pri->pvts[chanpos]->cid_name[0] = '\0'; 05206 pri->pvts[chanpos]->cid_ton = 0; 05207 pri->pvts[chanpos]->callingpres = 0; 05208 } 05209 05210 /* Setup the user tag for party id's from this device for this call. */ 05211 if (pri->append_msn_to_user_tag) { 05212 snprintf(pri->pvts[chanpos]->user_tag, 05213 sizeof(pri->pvts[chanpos]->user_tag), "%s_%s", 05214 pri->initial_user_tag, 05215 pri->nodetype == PRI_NETWORK 05216 ? plancallingnum : e->ring.callednum); 05217 } else { 05218 ast_copy_string(pri->pvts[chanpos]->user_tag, 05219 pri->initial_user_tag, sizeof(pri->pvts[chanpos]->user_tag)); 05220 } 05221 05222 sig_pri_set_caller_id(pri->pvts[chanpos]); 05223 05224 /* Set DNID on all incoming calls -- even immediate */ 05225 sig_pri_set_dnid(pri->pvts[chanpos], e->ring.callednum); 05226 05227 /* If immediate=yes go to s|1 */ 05228 if (pri->pvts[chanpos]->immediate) { 05229 ast_verb(3, "Going to extension s|1 because of immediate=yes\n"); 05230 pri->pvts[chanpos]->exten[0] = 's'; 05231 pri->pvts[chanpos]->exten[1] = '\0'; 05232 } 05233 /* Get called number */ 05234 else if (!ast_strlen_zero(e->ring.callednum)) { 05235 ast_copy_string(pri->pvts[chanpos]->exten, e->ring.callednum, sizeof(pri->pvts[chanpos]->exten)); 05236 } else if (pri->overlapdial) 05237 pri->pvts[chanpos]->exten[0] = '\0'; 05238 else { 05239 /* Some PRI circuits are set up to send _no_ digits. Handle them as 's'. */ 05240 pri->pvts[chanpos]->exten[0] = 's'; 05241 pri->pvts[chanpos]->exten[1] = '\0'; 05242 } 05243 /* No number yet, but received "sending complete"? */ 05244 if (e->ring.complete && (ast_strlen_zero(e->ring.callednum))) { 05245 ast_verb(3, "Going to extension s|1 because of Complete received\n"); 05246 pri->pvts[chanpos]->exten[0] = 's'; 05247 pri->pvts[chanpos]->exten[1] = '\0'; 05248 } 05249 05250 /* Make sure extension exists (or in overlap dial mode, can exist) */ 05251 if (((pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING) && ast_canmatch_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) || 05252 ast_exists_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) { 05253 /* Select audio companding mode. */ 05254 switch (e->ring.layer1) { 05255 case PRI_LAYER_1_ALAW: 05256 law = SIG_PRI_ALAW; 05257 break; 05258 case PRI_LAYER_1_ULAW: 05259 law = SIG_PRI_ULAW; 05260 break; 05261 default: 05262 /* This is a data call to us. */ 05263 law = SIG_PRI_DEFLAW; 05264 break; 05265 } 05266 05267 if (e->ring.complete || !(pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)) { 05268 /* Just announce proceeding */ 05269 pri->pvts[chanpos]->call_level = SIG_PRI_CALL_LEVEL_PROCEEDING; 05270 pri_proceeding(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 0); 05271 } else if (pri->switchtype == PRI_SWITCH_GR303_TMC) { 05272 pri->pvts[chanpos]->call_level = SIG_PRI_CALL_LEVEL_CONNECT; 05273 pri_answer(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 1); 05274 } else { 05275 pri->pvts[chanpos]->call_level = SIG_PRI_CALL_LEVEL_OVERLAP; 05276 pri_need_more_info(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 1); 05277 } 05278 05279 /* Start PBX */ 05280 if (!e->ring.complete 05281 && (pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING) 05282 && ast_matchmore_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) { 05283 /* 05284 * Release the PRI lock while we create the channel so other 05285 * threads can send D channel messages. We must also release 05286 * the private lock to prevent deadlock while creating the 05287 * channel. 05288 */ 05289 sig_pri_unlock_private(pri->pvts[chanpos]); 05290 ast_mutex_unlock(&pri->lock); 05291 c = sig_pri_new_ast_channel(pri->pvts[chanpos], 05292 AST_STATE_RESERVED, law, e->ring.ctype, 05293 pri->pvts[chanpos]->exten, NULL); 05294 ast_mutex_lock(&pri->lock); 05295 sig_pri_lock_private(pri->pvts[chanpos]); 05296 if (c) { 05297 #if defined(HAVE_PRI_SUBADDR) 05298 if (e->ring.calling.subaddress.valid) { 05299 /* Set Calling Subaddress */ 05300 sig_pri_lock_owner(pri, chanpos); 05301 sig_pri_set_subaddress( 05302 &pri->pvts[chanpos]->owner->caller.id.subaddress, 05303 &e->ring.calling.subaddress); 05304 if (!e->ring.calling.subaddress.type 05305 && !ast_strlen_zero( 05306 (char *) e->ring.calling.subaddress.data)) { 05307 /* NSAP */ 05308 pbx_builtin_setvar_helper(c, "CALLINGSUBADDR", 05309 (char *) e->ring.calling.subaddress.data); 05310 } 05311 ast_channel_unlock(c); 05312 } 05313 if (e->ring.called_subaddress.valid) { 05314 /* Set Called Subaddress */ 05315 sig_pri_lock_owner(pri, chanpos); 05316 sig_pri_set_subaddress( 05317 &pri->pvts[chanpos]->owner->dialed.subaddress, 05318 &e->ring.called_subaddress); 05319 if (!e->ring.called_subaddress.type 05320 && !ast_strlen_zero( 05321 (char *) e->ring.called_subaddress.data)) { 05322 /* NSAP */ 05323 pbx_builtin_setvar_helper(c, "CALLEDSUBADDR", 05324 (char *) e->ring.called_subaddress.data); 05325 } 05326 ast_channel_unlock(c); 05327 } 05328 #else 05329 if (!ast_strlen_zero(e->ring.callingsubaddr)) { 05330 pbx_builtin_setvar_helper(c, "CALLINGSUBADDR", e->ring.callingsubaddr); 05331 } 05332 #endif /* !defined(HAVE_PRI_SUBADDR) */ 05333 if (e->ring.ani2 >= 0) { 05334 snprintf(ani2str, sizeof(ani2str), "%d", e->ring.ani2); 05335 pbx_builtin_setvar_helper(c, "ANI2", ani2str); 05336 } 05337 05338 #ifdef SUPPORT_USERUSER 05339 if (!ast_strlen_zero(e->ring.useruserinfo)) { 05340 pbx_builtin_setvar_helper(c, "USERUSERINFO", e->ring.useruserinfo); 05341 } 05342 #endif 05343 05344 snprintf(calledtonstr, sizeof(calledtonstr), "%d", e->ring.calledplan); 05345 pbx_builtin_setvar_helper(c, "CALLEDTON", calledtonstr); 05346 if (e->ring.redirectingreason >= 0) { 05347 /* This is now just a status variable. Use REDIRECTING() dialplan function. */ 05348 pbx_builtin_setvar_helper(c, "PRIREDIRECTREASON", redirectingreason2str(e->ring.redirectingreason)); 05349 } 05350 #if defined(HAVE_PRI_REVERSE_CHARGE) 05351 pri->pvts[chanpos]->reverse_charging_indication = e->ring.reversecharge; 05352 #endif 05353 #if defined(HAVE_PRI_SETUP_KEYPAD) 05354 ast_copy_string(pri->pvts[chanpos]->keypad_digits, 05355 e->ring.keypad_digits, 05356 sizeof(pri->pvts[chanpos]->keypad_digits)); 05357 #endif /* defined(HAVE_PRI_SETUP_KEYPAD) */ 05358 05359 sig_pri_handle_subcmds(pri, chanpos, e->e, e->ring.channel, 05360 e->ring.subcmds, e->ring.call); 05361 05362 if (!pri->pvts[chanpos]->digital 05363 && !pri->pvts[chanpos]->no_b_channel) { 05364 /* 05365 * Call has a channel. 05366 * Indicate that we are providing dialtone. 05367 */ 05368 pri->pvts[chanpos]->progress = 1;/* No need to send plain PROGRESS again. */ 05369 #ifdef HAVE_PRI_PROG_W_CAUSE 05370 pri_progress_with_cause(pri->pri, e->ring.call, 05371 PVT_TO_CHANNEL(pri->pvts[chanpos]), 1, -1);/* no cause at all */ 05372 #else 05373 pri_progress(pri->pri, e->ring.call, 05374 PVT_TO_CHANNEL(pri->pvts[chanpos]), 1); 05375 #endif 05376 } 05377 } 05378 if (c && !ast_pthread_create_detached(&threadid, NULL, pri_ss_thread, pri->pvts[chanpos])) { 05379 ast_verb(3, "Accepting overlap call from '%s' to '%s' on channel %d/%d, span %d\n", 05380 plancallingnum, S_OR(pri->pvts[chanpos]->exten, "<unspecified>"), 05381 pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span); 05382 } else { 05383 ast_log(LOG_WARNING, "Unable to start PBX on channel %d/%d, span %d\n", 05384 pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span); 05385 if (c) { 05386 /* Avoid deadlock while destroying channel */ 05387 sig_pri_unlock_private(pri->pvts[chanpos]); 05388 ast_mutex_unlock(&pri->lock); 05389 ast_hangup(c); 05390 ast_mutex_lock(&pri->lock); 05391 } else { 05392 pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_SWITCH_CONGESTION); 05393 pri->pvts[chanpos]->call = NULL; 05394 sig_pri_unlock_private(pri->pvts[chanpos]); 05395 sig_pri_span_devstate_changed(pri); 05396 } 05397 break; 05398 } 05399 } else { 05400 /* 05401 * Release the PRI lock while we create the channel so other 05402 * threads can send D channel messages. We must also release 05403 * the private lock to prevent deadlock while creating the 05404 * channel. 05405 */ 05406 sig_pri_unlock_private(pri->pvts[chanpos]); 05407 ast_mutex_unlock(&pri->lock); 05408 c = sig_pri_new_ast_channel(pri->pvts[chanpos], 05409 AST_STATE_RING, law, e->ring.ctype, 05410 pri->pvts[chanpos]->exten, NULL); 05411 ast_mutex_lock(&pri->lock); 05412 sig_pri_lock_private(pri->pvts[chanpos]); 05413 if (c) { 05414 /* 05415 * It is reasonably safe to set the following 05416 * channel variables while the PRI and DAHDI private 05417 * structures are locked. The PBX has not been 05418 * started yet and it is unlikely that any other task 05419 * will do anything with the channel we have just 05420 * created. 05421 */ 05422 #if defined(HAVE_PRI_SUBADDR) 05423 if (e->ring.calling.subaddress.valid) { 05424 /* Set Calling Subaddress */ 05425 sig_pri_lock_owner(pri, chanpos); 05426 sig_pri_set_subaddress( 05427 &pri->pvts[chanpos]->owner->caller.id.subaddress, 05428 &e->ring.calling.subaddress); 05429 if (!e->ring.calling.subaddress.type 05430 && !ast_strlen_zero( 05431 (char *) e->ring.calling.subaddress.data)) { 05432 /* NSAP */ 05433 pbx_builtin_setvar_helper(c, "CALLINGSUBADDR", 05434 (char *) e->ring.calling.subaddress.data); 05435 } 05436 ast_channel_unlock(c); 05437 } 05438 if (e->ring.called_subaddress.valid) { 05439 /* Set Called Subaddress */ 05440 sig_pri_lock_owner(pri, chanpos); 05441 sig_pri_set_subaddress( 05442 &pri->pvts[chanpos]->owner->dialed.subaddress, 05443 &e->ring.called_subaddress); 05444 if (!e->ring.called_subaddress.type 05445 && !ast_strlen_zero( 05446 (char *) e->ring.called_subaddress.data)) { 05447 /* NSAP */ 05448 pbx_builtin_setvar_helper(c, "CALLEDSUBADDR", 05449 (char *) e->ring.called_subaddress.data); 05450 } 05451 ast_channel_unlock(c); 05452 } 05453 #else 05454 if (!ast_strlen_zero(e->ring.callingsubaddr)) { 05455 pbx_builtin_setvar_helper(c, "CALLINGSUBADDR", e->ring.callingsubaddr); 05456 } 05457 #endif /* !defined(HAVE_PRI_SUBADDR) */ 05458 if (e->ring.ani2 >= 0) { 05459 snprintf(ani2str, sizeof(ani2str), "%d", e->ring.ani2); 05460 pbx_builtin_setvar_helper(c, "ANI2", ani2str); 05461 } 05462 05463 #ifdef SUPPORT_USERUSER 05464 if (!ast_strlen_zero(e->ring.useruserinfo)) { 05465 pbx_builtin_setvar_helper(c, "USERUSERINFO", e->ring.useruserinfo); 05466 } 05467 #endif 05468 05469 if (e->ring.redirectingreason >= 0) { 05470 /* This is now just a status variable. Use REDIRECTING() dialplan function. */ 05471 pbx_builtin_setvar_helper(c, "PRIREDIRECTREASON", redirectingreason2str(e->ring.redirectingreason)); 05472 } 05473 #if defined(HAVE_PRI_REVERSE_CHARGE) 05474 pri->pvts[chanpos]->reverse_charging_indication = e->ring.reversecharge; 05475 #endif 05476 #if defined(HAVE_PRI_SETUP_KEYPAD) 05477 ast_copy_string(pri->pvts[chanpos]->keypad_digits, 05478 e->ring.keypad_digits, 05479 sizeof(pri->pvts[chanpos]->keypad_digits)); 05480 #endif /* defined(HAVE_PRI_SETUP_KEYPAD) */ 05481 05482 snprintf(calledtonstr, sizeof(calledtonstr), "%d", e->ring.calledplan); 05483 pbx_builtin_setvar_helper(c, "CALLEDTON", calledtonstr); 05484 05485 sig_pri_handle_subcmds(pri, chanpos, e->e, e->ring.channel, 05486 e->ring.subcmds, e->ring.call); 05487 05488 } 05489 if (c && !ast_pbx_start(c)) { 05490 ast_verb(3, "Accepting call from '%s' to '%s' on channel %d/%d, span %d\n", 05491 plancallingnum, pri->pvts[chanpos]->exten, 05492 pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span); 05493 sig_pri_set_echocanceller(pri->pvts[chanpos], 1); 05494 } else { 05495 ast_log(LOG_WARNING, "Unable to start PBX on channel %d/%d, span %d\n", 05496 pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span); 05497 if (c) { 05498 /* Avoid deadlock while destroying channel */ 05499 sig_pri_unlock_private(pri->pvts[chanpos]); 05500 ast_mutex_unlock(&pri->lock); 05501 ast_hangup(c); 05502 ast_mutex_lock(&pri->lock); 05503 } else { 05504 pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_SWITCH_CONGESTION); 05505 pri->pvts[chanpos]->call = NULL; 05506 sig_pri_unlock_private(pri->pvts[chanpos]); 05507 sig_pri_span_devstate_changed(pri); 05508 } 05509 break; 05510 } 05511 } 05512 } else { 05513 ast_verb(3, 05514 "Span %d: Extension %s@%s does not exist. Rejecting call from '%s'.\n", 05515 pri->span, pri->pvts[chanpos]->exten, pri->pvts[chanpos]->context, 05516 pri->pvts[chanpos]->cid_num); 05517 pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_UNALLOCATED); 05518 pri->pvts[chanpos]->call = NULL; 05519 pri->pvts[chanpos]->exten[0] = '\0'; 05520 sig_pri_unlock_private(pri->pvts[chanpos]); 05521 sig_pri_span_devstate_changed(pri); 05522 break; 05523 } 05524 sig_pri_unlock_private(pri->pvts[chanpos]); 05525 break; 05526 case PRI_EVENT_RINGING: 05527 if (sig_pri_is_cis_call(e->ringing.channel)) { 05528 sig_pri_handle_cis_subcmds(pri, e->e, e->ringing.subcmds, 05529 e->ringing.call); 05530 break; 05531 } 05532 chanpos = pri_find_fixup_principle(pri, e->ringing.channel, 05533 e->ringing.call); 05534 if (chanpos < 0) { 05535 break; 05536 } 05537 sig_pri_lock_private(pri->pvts[chanpos]); 05538 05539 sig_pri_handle_subcmds(pri, chanpos, e->e, e->ringing.channel, 05540 e->ringing.subcmds, e->ringing.call); 05541 sig_pri_cc_generic_check(pri, chanpos, AST_CC_CCNR); 05542 sig_pri_set_echocanceller(pri->pvts[chanpos], 1); 05543 sig_pri_lock_owner(pri, chanpos); 05544 if (pri->pvts[chanpos]->owner) { 05545 ast_setstate(pri->pvts[chanpos]->owner, AST_STATE_RINGING); 05546 ast_channel_unlock(pri->pvts[chanpos]->owner); 05547 } 05548 pri_queue_control(pri, chanpos, AST_CONTROL_RINGING); 05549 if (pri->pvts[chanpos]->call_level < SIG_PRI_CALL_LEVEL_ALERTING) { 05550 pri->pvts[chanpos]->call_level = SIG_PRI_CALL_LEVEL_ALERTING; 05551 } 05552 05553 if (!pri->pvts[chanpos]->progress 05554 && !pri->pvts[chanpos]->no_b_channel 05555 #ifdef PRI_PROGRESS_MASK 05556 && (e->ringing.progressmask 05557 & (PRI_PROG_CALL_NOT_E2E_ISDN | PRI_PROG_INBAND_AVAILABLE)) 05558 #else 05559 && e->ringing.progress == 8 05560 #endif 05561 ) { 05562 /* Bring voice path up */ 05563 pri_queue_control(pri, chanpos, AST_CONTROL_PROGRESS); 05564 pri->pvts[chanpos]->progress = 1; 05565 sig_pri_set_dialing(pri->pvts[chanpos], 0); 05566 sig_pri_open_media(pri->pvts[chanpos]); 05567 } 05568 05569 #ifdef SUPPORT_USERUSER 05570 if (!ast_strlen_zero(e->ringing.useruserinfo)) { 05571 struct ast_channel *owner; 05572 05573 sig_pri_lock_owner(pri, chanpos); 05574 owner = pri->pvts[chanpos]->owner; 05575 if (owner) { 05576 pbx_builtin_setvar_helper(owner, "USERUSERINFO", 05577 e->ringing.useruserinfo); 05578 ast_channel_unlock(owner); 05579 } 05580 } 05581 #endif 05582 05583 sig_pri_unlock_private(pri->pvts[chanpos]); 05584 break; 05585 case PRI_EVENT_PROGRESS: 05586 if (sig_pri_is_cis_call(e->proceeding.channel)) { 05587 sig_pri_handle_cis_subcmds(pri, e->e, e->proceeding.subcmds, 05588 e->proceeding.call); 05589 break; 05590 } 05591 chanpos = pri_find_fixup_principle(pri, e->proceeding.channel, 05592 e->proceeding.call); 05593 if (chanpos < 0) { 05594 break; 05595 } 05596 sig_pri_lock_private(pri->pvts[chanpos]); 05597 sig_pri_handle_subcmds(pri, chanpos, e->e, e->proceeding.channel, 05598 e->proceeding.subcmds, e->proceeding.call); 05599 05600 if (e->proceeding.cause > -1) { 05601 ast_verb(3, "PROGRESS with cause code %d received\n", e->proceeding.cause); 05602 05603 /* Work around broken, out of spec USER_BUSY cause in a progress message */ 05604 if (e->proceeding.cause == AST_CAUSE_USER_BUSY) { 05605 if (pri->pvts[chanpos]->owner) { 05606 ast_verb(3, "PROGRESS with 'user busy' received, signaling AST_CONTROL_BUSY instead of AST_CONTROL_PROGRESS\n"); 05607 05608 pri->pvts[chanpos]->owner->hangupcause = e->proceeding.cause; 05609 pri_queue_control(pri, chanpos, AST_CONTROL_BUSY); 05610 } 05611 } 05612 } 05613 05614 if (!pri->pvts[chanpos]->progress 05615 && !pri->pvts[chanpos]->no_b_channel 05616 #ifdef PRI_PROGRESS_MASK 05617 && (e->proceeding.progressmask 05618 & (PRI_PROG_CALL_NOT_E2E_ISDN | PRI_PROG_INBAND_AVAILABLE)) 05619 #else 05620 && e->proceeding.progress == 8 05621 #endif 05622 ) { 05623 /* Bring voice path up */ 05624 ast_debug(1, 05625 "Queuing frame from PRI_EVENT_PROGRESS on channel %d/%d span %d\n", 05626 pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, 05627 pri->span); 05628 pri_queue_control(pri, chanpos, AST_CONTROL_PROGRESS); 05629 pri->pvts[chanpos]->progress = 1; 05630 sig_pri_set_dialing(pri->pvts[chanpos], 0); 05631 sig_pri_open_media(pri->pvts[chanpos]); 05632 } 05633 sig_pri_unlock_private(pri->pvts[chanpos]); 05634 break; 05635 case PRI_EVENT_PROCEEDING: 05636 if (sig_pri_is_cis_call(e->proceeding.channel)) { 05637 sig_pri_handle_cis_subcmds(pri, e->e, e->proceeding.subcmds, 05638 e->proceeding.call); 05639 break; 05640 } 05641 chanpos = pri_find_fixup_principle(pri, e->proceeding.channel, 05642 e->proceeding.call); 05643 if (chanpos < 0) { 05644 break; 05645 } 05646 sig_pri_lock_private(pri->pvts[chanpos]); 05647 sig_pri_handle_subcmds(pri, chanpos, e->e, e->proceeding.channel, 05648 e->proceeding.subcmds, e->proceeding.call); 05649 if (pri->pvts[chanpos]->call_level < SIG_PRI_CALL_LEVEL_PROCEEDING) { 05650 pri->pvts[chanpos]->call_level = SIG_PRI_CALL_LEVEL_PROCEEDING; 05651 ast_debug(1, 05652 "Queuing frame from PRI_EVENT_PROCEEDING on channel %d/%d span %d\n", 05653 pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, 05654 pri->span); 05655 pri_queue_control(pri, chanpos, AST_CONTROL_PROCEEDING); 05656 } 05657 if (!pri->pvts[chanpos]->progress 05658 && !pri->pvts[chanpos]->no_b_channel 05659 #ifdef PRI_PROGRESS_MASK 05660 && (e->proceeding.progressmask 05661 & (PRI_PROG_CALL_NOT_E2E_ISDN | PRI_PROG_INBAND_AVAILABLE)) 05662 #else 05663 && e->proceeding.progress == 8 05664 #endif 05665 ) { 05666 /* Bring voice path up */ 05667 pri_queue_control(pri, chanpos, AST_CONTROL_PROGRESS); 05668 pri->pvts[chanpos]->progress = 1; 05669 sig_pri_open_media(pri->pvts[chanpos]); 05670 } 05671 sig_pri_set_dialing(pri->pvts[chanpos], 0); 05672 sig_pri_unlock_private(pri->pvts[chanpos]); 05673 break; 05674 case PRI_EVENT_FACILITY: 05675 if (!e->facility.call || sig_pri_is_cis_call(e->facility.channel)) { 05676 /* Event came in on the dummy channel or a CIS call. */ 05677 #if defined(HAVE_PRI_CALL_REROUTING) 05678 sig_pri_handle_cis_subcmds(pri, e->e, e->facility.subcmds, 05679 e->facility.subcall); 05680 #else 05681 sig_pri_handle_cis_subcmds(pri, e->e, e->facility.subcmds, 05682 e->facility.call); 05683 #endif /* !defined(HAVE_PRI_CALL_REROUTING) */ 05684 break; 05685 } 05686 chanpos = pri_find_principle_by_call(pri, e->facility.call); 05687 if (chanpos < 0) { 05688 ast_log(LOG_WARNING, "Span %d: Received facility for unknown call.\n", 05689 pri->span); 05690 break; 05691 } 05692 sig_pri_lock_private(pri->pvts[chanpos]); 05693 #if defined(HAVE_PRI_CALL_REROUTING) 05694 sig_pri_handle_subcmds(pri, chanpos, e->e, e->facility.channel, 05695 e->facility.subcmds, e->facility.subcall); 05696 #else 05697 sig_pri_handle_subcmds(pri, chanpos, e->e, e->facility.channel, 05698 e->facility.subcmds, e->facility.call); 05699 #endif /* !defined(HAVE_PRI_CALL_REROUTING) */ 05700 sig_pri_unlock_private(pri->pvts[chanpos]); 05701 break; 05702 case PRI_EVENT_ANSWER: 05703 if (sig_pri_is_cis_call(e->answer.channel)) { 05704 #if defined(HAVE_PRI_CALL_WAITING) 05705 /* Call is CIS so do normal CONNECT_ACKNOWLEDGE. */ 05706 pri_connect_ack(pri->pri, e->answer.call, 0); 05707 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 05708 sig_pri_handle_cis_subcmds(pri, e->e, e->answer.subcmds, 05709 e->answer.call); 05710 break; 05711 } 05712 chanpos = pri_find_fixup_principle(pri, e->answer.channel, e->answer.call); 05713 if (chanpos < 0) { 05714 break; 05715 } 05716 #if defined(HAVE_PRI_CALL_WAITING) 05717 if (pri->pvts[chanpos]->is_call_waiting) { 05718 if (pri->pvts[chanpos]->no_b_channel) { 05719 int new_chanpos; 05720 05721 /* 05722 * Need to find a free channel now or 05723 * kill the call with PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION. 05724 */ 05725 new_chanpos = pri_find_empty_chan(pri, 1); 05726 if (0 <= new_chanpos) { 05727 new_chanpos = pri_fixup_principle(pri, new_chanpos, 05728 e->answer.call); 05729 } 05730 if (new_chanpos < 0) { 05731 /* 05732 * Either no channel was available or someone stole 05733 * the channel! 05734 */ 05735 ast_verb(3, 05736 "Span %d: Channel not available for call waiting call.\n", 05737 pri->span); 05738 sig_pri_lock_private(pri->pvts[chanpos]); 05739 sig_pri_handle_subcmds(pri, chanpos, e->e, e->answer.channel, 05740 e->answer.subcmds, e->answer.call); 05741 sig_pri_cc_generic_check(pri, chanpos, AST_CC_CCBS); 05742 sig_pri_lock_owner(pri, chanpos); 05743 if (pri->pvts[chanpos]->owner) { 05744 pri->pvts[chanpos]->owner->hangupcause = PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION; 05745 switch (pri->pvts[chanpos]->owner->_state) { 05746 case AST_STATE_BUSY: 05747 case AST_STATE_UP: 05748 ast_softhangup_nolock(pri->pvts[chanpos]->owner, AST_SOFTHANGUP_DEV); 05749 break; 05750 default: 05751 pri_queue_control(pri, chanpos, AST_CONTROL_CONGESTION); 05752 break; 05753 } 05754 ast_channel_unlock(pri->pvts[chanpos]->owner); 05755 } else { 05756 pri->pvts[chanpos]->is_call_waiting = 0; 05757 ast_atomic_fetchadd_int(&pri->num_call_waiting_calls, -1); 05758 pri_hangup(pri->pri, e->answer.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION); 05759 pri->pvts[chanpos]->call = NULL; 05760 } 05761 sig_pri_unlock_private(pri->pvts[chanpos]); 05762 sig_pri_span_devstate_changed(pri); 05763 break; 05764 } 05765 chanpos = new_chanpos; 05766 } 05767 pri_connect_ack(pri->pri, e->answer.call, PVT_TO_CHANNEL(pri->pvts[chanpos])); 05768 sig_pri_span_devstate_changed(pri); 05769 } else { 05770 /* Call is normal so do normal CONNECT_ACKNOWLEDGE. */ 05771 pri_connect_ack(pri->pri, e->answer.call, 0); 05772 } 05773 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 05774 sig_pri_lock_private(pri->pvts[chanpos]); 05775 05776 #if defined(HAVE_PRI_CALL_WAITING) 05777 if (pri->pvts[chanpos]->is_call_waiting) { 05778 pri->pvts[chanpos]->is_call_waiting = 0; 05779 ast_atomic_fetchadd_int(&pri->num_call_waiting_calls, -1); 05780 } 05781 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 05782 sig_pri_handle_subcmds(pri, chanpos, e->e, e->answer.channel, 05783 e->answer.subcmds, e->answer.call); 05784 if (!ast_strlen_zero(pri->pvts[chanpos]->deferred_digits)) { 05785 /* We have some 'w' deferred digits to dial now. */ 05786 ast_verb(3, 05787 "Span %d: Channel %d/%d dialing deferred digit string: %s\n", 05788 pri->span, pri->pvts[chanpos]->logicalspan, 05789 pri->pvts[chanpos]->prioffset, 05790 pri->pvts[chanpos]->deferred_digits); 05791 if (pri->pvts[chanpos]->call_level < SIG_PRI_CALL_LEVEL_DEFER_DIAL) { 05792 pri->pvts[chanpos]->call_level = SIG_PRI_CALL_LEVEL_DEFER_DIAL; 05793 } 05794 sig_pri_dial_digits(pri->pvts[chanpos], 05795 pri->pvts[chanpos]->deferred_digits); 05796 } else { 05797 if (pri->pvts[chanpos]->call_level < SIG_PRI_CALL_LEVEL_CONNECT) { 05798 pri->pvts[chanpos]->call_level = SIG_PRI_CALL_LEVEL_CONNECT; 05799 } 05800 sig_pri_open_media(pri->pvts[chanpos]); 05801 pri_queue_control(pri, chanpos, AST_CONTROL_ANSWER); 05802 sig_pri_set_dialing(pri->pvts[chanpos], 0); 05803 /* Enable echo cancellation if it's not on already */ 05804 sig_pri_set_echocanceller(pri->pvts[chanpos], 1); 05805 } 05806 05807 #ifdef SUPPORT_USERUSER 05808 if (!ast_strlen_zero(e->answer.useruserinfo)) { 05809 struct ast_channel *owner; 05810 05811 sig_pri_lock_owner(pri, chanpos); 05812 owner = pri->pvts[chanpos]->owner; 05813 if (owner) { 05814 pbx_builtin_setvar_helper(owner, "USERUSERINFO", 05815 e->answer.useruserinfo); 05816 ast_channel_unlock(owner); 05817 } 05818 } 05819 #endif 05820 05821 sig_pri_unlock_private(pri->pvts[chanpos]); 05822 break; 05823 #if defined(HAVE_PRI_CALL_WAITING) 05824 case PRI_EVENT_CONNECT_ACK: 05825 if (sig_pri_is_cis_call(e->connect_ack.channel)) { 05826 sig_pri_handle_cis_subcmds(pri, e->e, e->connect_ack.subcmds, 05827 e->connect_ack.call); 05828 break; 05829 } 05830 chanpos = pri_find_fixup_principle(pri, e->connect_ack.channel, 05831 e->connect_ack.call); 05832 if (chanpos < 0) { 05833 break; 05834 } 05835 05836 sig_pri_lock_private(pri->pvts[chanpos]); 05837 sig_pri_handle_subcmds(pri, chanpos, e->e, e->connect_ack.channel, 05838 e->connect_ack.subcmds, e->connect_ack.call); 05839 sig_pri_open_media(pri->pvts[chanpos]); 05840 sig_pri_unlock_private(pri->pvts[chanpos]); 05841 sig_pri_span_devstate_changed(pri); 05842 break; 05843 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 05844 case PRI_EVENT_HANGUP: 05845 if (sig_pri_is_cis_call(e->hangup.channel)) { 05846 sig_pri_handle_cis_subcmds(pri, e->e, e->hangup.subcmds, 05847 e->hangup.call); 05848 pri_hangup(pri->pri, e->hangup.call, e->hangup.cause); 05849 break; 05850 } 05851 chanpos = pri_find_principle_by_call(pri, e->hangup.call); 05852 if (chanpos < 0) { 05853 /* 05854 * Continue hanging up the call even though 05855 * we do not remember it (if we ever did). 05856 */ 05857 pri_hangup(pri->pri, e->hangup.call, e->hangup.cause); 05858 break; 05859 } 05860 sig_pri_lock_private(pri->pvts[chanpos]); 05861 sig_pri_handle_subcmds(pri, chanpos, e->e, e->hangup.channel, 05862 e->hangup.subcmds, e->hangup.call); 05863 switch (e->hangup.cause) { 05864 case PRI_CAUSE_INVALID_CALL_REFERENCE: 05865 /* 05866 * The peer denies the existence of this call so we must 05867 * continue hanging it up and forget about it. 05868 */ 05869 pri_hangup(pri->pri, e->hangup.call, e->hangup.cause); 05870 pri->pvts[chanpos]->call = NULL; 05871 break; 05872 default: 05873 break; 05874 } 05875 if (!pri->pvts[chanpos]->alreadyhungup) { 05876 /* we're calling here dahdi_hangup so once we get there we need to clear p->call after calling pri_hangup */ 05877 pri->pvts[chanpos]->alreadyhungup = 1; 05878 switch (e->hangup.cause) { 05879 case PRI_CAUSE_USER_BUSY: 05880 case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION: 05881 sig_pri_cc_generic_check(pri, chanpos, AST_CC_CCBS); 05882 break; 05883 default: 05884 break; 05885 } 05886 if (pri->pvts[chanpos]->owner) { 05887 int do_hangup = 0; 05888 05889 /* Queue a BUSY instead of a hangup if our cause is appropriate */ 05890 pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause; 05891 switch (pri->pvts[chanpos]->owner->_state) { 05892 case AST_STATE_BUSY: 05893 case AST_STATE_UP: 05894 do_hangup = 1; 05895 break; 05896 default: 05897 if (!pri->pvts[chanpos]->outgoing) { 05898 /* 05899 * The incoming call leg hung up before getting 05900 * connected so just hangup the call. 05901 */ 05902 do_hangup = 1; 05903 break; 05904 } 05905 switch (e->hangup.cause) { 05906 case PRI_CAUSE_USER_BUSY: 05907 pri_queue_control(pri, chanpos, AST_CONTROL_BUSY); 05908 break; 05909 case PRI_CAUSE_CALL_REJECTED: 05910 case PRI_CAUSE_NETWORK_OUT_OF_ORDER: 05911 case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION: 05912 case PRI_CAUSE_SWITCH_CONGESTION: 05913 case PRI_CAUSE_DESTINATION_OUT_OF_ORDER: 05914 case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE: 05915 pri_queue_control(pri, chanpos, AST_CONTROL_CONGESTION); 05916 break; 05917 default: 05918 do_hangup = 1; 05919 break; 05920 } 05921 break; 05922 } 05923 05924 if (do_hangup) { 05925 #if defined(HAVE_PRI_AOC_EVENTS) 05926 if (detect_aoc_e_subcmd(e->hangup.subcmds)) { 05927 /* If a AOC-E msg was sent during the release, we must use a 05928 * AST_CONTROL_HANGUP frame to guarantee that frame gets read before hangup */ 05929 pri_queue_control(pri, chanpos, AST_CONTROL_HANGUP); 05930 } else { 05931 pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV; 05932 } 05933 #else 05934 pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV; 05935 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 05936 } 05937 } else { 05938 /* 05939 * Continue hanging up the call even though 05940 * we do not have an owner. 05941 */ 05942 pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause); 05943 pri->pvts[chanpos]->call = NULL; 05944 } 05945 ast_verb(3, "Span %d: Channel %d/%d got hangup, cause %d\n", 05946 pri->span, pri->pvts[chanpos]->logicalspan, 05947 pri->pvts[chanpos]->prioffset, e->hangup.cause); 05948 } else { 05949 /* Continue hanging up the call. */ 05950 pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause); 05951 pri->pvts[chanpos]->call = NULL; 05952 } 05953 #if defined(FORCE_RESTART_UNAVAIL_CHANS) 05954 if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL 05955 && pri->sig != SIG_BRI_PTMP && !pri->resetting 05956 && pri->pvts[chanpos]->resetting == SIG_PRI_RESET_IDLE) { 05957 ast_verb(3, 05958 "Span %d: Forcing restart of channel %d/%d since channel reported in use\n", 05959 pri->span, pri->pvts[chanpos]->logicalspan, 05960 pri->pvts[chanpos]->prioffset); 05961 pri->pvts[chanpos]->resetting = SIG_PRI_RESET_ACTIVE; 05962 pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos])); 05963 } 05964 #endif /* defined(FORCE_RESTART_UNAVAIL_CHANS) */ 05965 if (e->hangup.aoc_units > -1) 05966 ast_verb(3, "Channel %d/%d, span %d received AOC-E charging %d unit%s\n", 05967 pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s"); 05968 05969 #ifdef SUPPORT_USERUSER 05970 if (!ast_strlen_zero(e->hangup.useruserinfo)) { 05971 struct ast_channel *owner; 05972 05973 sig_pri_lock_owner(pri, chanpos); 05974 owner = pri->pvts[chanpos]->owner; 05975 if (owner) { 05976 pbx_builtin_setvar_helper(owner, "USERUSERINFO", 05977 e->hangup.useruserinfo); 05978 ast_channel_unlock(owner); 05979 } 05980 } 05981 #endif 05982 05983 sig_pri_unlock_private(pri->pvts[chanpos]); 05984 sig_pri_span_devstate_changed(pri); 05985 break; 05986 case PRI_EVENT_HANGUP_REQ: 05987 if (sig_pri_is_cis_call(e->hangup.channel)) { 05988 sig_pri_handle_cis_subcmds(pri, e->e, e->hangup.subcmds, 05989 e->hangup.call); 05990 pri_hangup(pri->pri, e->hangup.call, e->hangup.cause); 05991 break; 05992 } 05993 chanpos = pri_find_principle_by_call(pri, e->hangup.call); 05994 if (chanpos < 0) { 05995 /* 05996 * Continue hanging up the call even though 05997 * we do not remember it (if we ever did). 05998 */ 05999 pri_hangup(pri->pri, e->hangup.call, e->hangup.cause); 06000 break; 06001 } 06002 sig_pri_lock_private(pri->pvts[chanpos]); 06003 sig_pri_handle_subcmds(pri, chanpos, e->e, e->hangup.channel, 06004 e->hangup.subcmds, e->hangup.call); 06005 #if defined(HAVE_PRI_CALL_HOLD) 06006 if (e->hangup.call_active && e->hangup.call_held 06007 && pri->hold_disconnect_transfer) { 06008 /* We are to transfer the call instead of simply hanging up. */ 06009 sig_pri_unlock_private(pri->pvts[chanpos]); 06010 if (!sig_pri_attempt_transfer(pri, e->hangup.call_held, 1, 06011 e->hangup.call_active, 0, NULL, NULL)) { 06012 break; 06013 } 06014 sig_pri_lock_private(pri->pvts[chanpos]); 06015 } 06016 #endif /* defined(HAVE_PRI_CALL_HOLD) */ 06017 switch (e->hangup.cause) { 06018 case PRI_CAUSE_USER_BUSY: 06019 case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION: 06020 sig_pri_cc_generic_check(pri, chanpos, AST_CC_CCBS); 06021 break; 06022 case PRI_CAUSE_INVALID_CALL_REFERENCE: 06023 /* 06024 * The peer denies the existence of this call so we must 06025 * continue hanging it up and forget about it. We should not 06026 * get this cause here, but for completeness we will handle it 06027 * anyway. 06028 */ 06029 pri_hangup(pri->pri, e->hangup.call, e->hangup.cause); 06030 pri->pvts[chanpos]->call = NULL; 06031 break; 06032 default: 06033 break; 06034 } 06035 if (pri->pvts[chanpos]->owner) { 06036 int do_hangup = 0; 06037 06038 pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause; 06039 switch (pri->pvts[chanpos]->owner->_state) { 06040 case AST_STATE_BUSY: 06041 case AST_STATE_UP: 06042 do_hangup = 1; 06043 break; 06044 default: 06045 if (!pri->pvts[chanpos]->outgoing) { 06046 /* 06047 * The incoming call leg hung up before getting 06048 * connected so just hangup the call. 06049 */ 06050 do_hangup = 1; 06051 break; 06052 } 06053 switch (e->hangup.cause) { 06054 case PRI_CAUSE_USER_BUSY: 06055 pri_queue_control(pri, chanpos, AST_CONTROL_BUSY); 06056 break; 06057 case PRI_CAUSE_CALL_REJECTED: 06058 case PRI_CAUSE_NETWORK_OUT_OF_ORDER: 06059 case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION: 06060 case PRI_CAUSE_SWITCH_CONGESTION: 06061 case PRI_CAUSE_DESTINATION_OUT_OF_ORDER: 06062 case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE: 06063 pri_queue_control(pri, chanpos, AST_CONTROL_CONGESTION); 06064 break; 06065 default: 06066 do_hangup = 1; 06067 break; 06068 } 06069 break; 06070 } 06071 06072 if (do_hangup) { 06073 #if defined(HAVE_PRI_AOC_EVENTS) 06074 if (!pri->pvts[chanpos]->holding_aoce 06075 && pri->aoce_delayhangup 06076 && ast_bridged_channel(pri->pvts[chanpos]->owner)) { 06077 sig_pri_send_aoce_termination_request(pri, chanpos, 06078 pri_get_timer(pri->pri, PRI_TIMER_T305) / 2); 06079 } else if (detect_aoc_e_subcmd(e->hangup.subcmds)) { 06080 /* If a AOC-E msg was sent during the Disconnect, we must use a AST_CONTROL_HANGUP frame 06081 * to guarantee that frame gets read before hangup */ 06082 pri_queue_control(pri, chanpos, AST_CONTROL_HANGUP); 06083 } else { 06084 pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV; 06085 } 06086 #else 06087 pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV; 06088 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 06089 } 06090 ast_verb(3, "Span %d: Channel %d/%d got hangup request, cause %d\n", 06091 pri->span, pri->pvts[chanpos]->logicalspan, 06092 pri->pvts[chanpos]->prioffset, e->hangup.cause); 06093 } else { 06094 /* 06095 * Continue hanging up the call even though 06096 * we do not have an owner. 06097 */ 06098 pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause); 06099 pri->pvts[chanpos]->call = NULL; 06100 } 06101 #if defined(FORCE_RESTART_UNAVAIL_CHANS) 06102 if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL 06103 && pri->sig != SIG_BRI_PTMP && !pri->resetting 06104 && pri->pvts[chanpos]->resetting == SIG_PRI_RESET_IDLE) { 06105 ast_verb(3, 06106 "Span %d: Forcing restart of channel %d/%d since channel reported in use\n", 06107 pri->span, pri->pvts[chanpos]->logicalspan, 06108 pri->pvts[chanpos]->prioffset); 06109 pri->pvts[chanpos]->resetting = SIG_PRI_RESET_ACTIVE; 06110 pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos])); 06111 } 06112 #endif /* defined(FORCE_RESTART_UNAVAIL_CHANS) */ 06113 06114 #ifdef SUPPORT_USERUSER 06115 if (!ast_strlen_zero(e->hangup.useruserinfo)) { 06116 struct ast_channel *owner; 06117 06118 sig_pri_lock_owner(pri, chanpos); 06119 owner = pri->pvts[chanpos]->owner; 06120 if (owner) { 06121 pbx_builtin_setvar_helper(owner, "USERUSERINFO", 06122 e->hangup.useruserinfo); 06123 ast_channel_unlock(owner); 06124 } 06125 } 06126 #endif 06127 06128 sig_pri_unlock_private(pri->pvts[chanpos]); 06129 sig_pri_span_devstate_changed(pri); 06130 break; 06131 case PRI_EVENT_HANGUP_ACK: 06132 if (sig_pri_is_cis_call(e->hangup.channel)) { 06133 sig_pri_handle_cis_subcmds(pri, e->e, e->hangup.subcmds, 06134 e->hangup.call); 06135 break; 06136 } 06137 chanpos = pri_find_principle_by_call(pri, e->hangup.call); 06138 if (chanpos < 0) { 06139 break; 06140 } 06141 sig_pri_lock_private(pri->pvts[chanpos]); 06142 pri->pvts[chanpos]->call = NULL; 06143 if (pri->pvts[chanpos]->owner) { 06144 ast_verb(3, "Span %d: Channel %d/%d got hangup ACK\n", pri->span, 06145 pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset); 06146 } 06147 #ifdef SUPPORT_USERUSER 06148 if (!ast_strlen_zero(e->hangup.useruserinfo)) { 06149 struct ast_channel *owner; 06150 06151 sig_pri_lock_owner(pri, chanpos); 06152 owner = pri->pvts[chanpos]->owner; 06153 if (owner) { 06154 pbx_builtin_setvar_helper(owner, "USERUSERINFO", 06155 e->hangup.useruserinfo); 06156 ast_channel_unlock(owner); 06157 } 06158 } 06159 #endif 06160 sig_pri_unlock_private(pri->pvts[chanpos]); 06161 sig_pri_span_devstate_changed(pri); 06162 break; 06163 case PRI_EVENT_CONFIG_ERR: 06164 ast_log(LOG_WARNING, "PRI Error on span %d: %s\n", pri->span, e->err.err); 06165 break; 06166 case PRI_EVENT_RESTART_ACK: 06167 chanpos = pri_find_principle(pri, e->restartack.channel, NULL); 06168 if (chanpos < 0) { 06169 /* Sometime switches (e.g. I421 / British Telecom) don't give us the 06170 channel number, so we have to figure it out... This must be why 06171 everybody resets exactly a channel at a time. */ 06172 for (x = 0; x < pri->numchans; x++) { 06173 if (pri->pvts[x] 06174 && pri->pvts[x]->resetting != SIG_PRI_RESET_IDLE) { 06175 chanpos = x; 06176 sig_pri_lock_private(pri->pvts[chanpos]); 06177 ast_debug(1, 06178 "Span %d: Assuming restart ack is for channel %d/%d\n", 06179 pri->span, pri->pvts[chanpos]->logicalspan, 06180 pri->pvts[chanpos]->prioffset); 06181 if (pri->pvts[chanpos]->owner) { 06182 ast_log(LOG_WARNING, 06183 "Span %d: Got restart ack on channel %d/%d with owner\n", 06184 pri->span, pri->pvts[chanpos]->logicalspan, 06185 pri->pvts[chanpos]->prioffset); 06186 pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV; 06187 } 06188 pri->pvts[chanpos]->resetting = SIG_PRI_RESET_IDLE; 06189 ast_verb(3, 06190 "Span %d: Channel %d/%d successfully restarted\n", 06191 pri->span, pri->pvts[chanpos]->logicalspan, 06192 pri->pvts[chanpos]->prioffset); 06193 sig_pri_unlock_private(pri->pvts[chanpos]); 06194 if (pri->resetting) 06195 pri_check_restart(pri); 06196 break; 06197 } 06198 } 06199 if (chanpos < 0) { 06200 ast_log(LOG_WARNING, 06201 "Span %d: Restart ACK on strange channel %d/%d\n", 06202 pri->span, PRI_SPAN(e->restartack.channel), 06203 PRI_CHANNEL(e->restartack.channel)); 06204 } 06205 } else { 06206 sig_pri_lock_private(pri->pvts[chanpos]); 06207 if (pri->pvts[chanpos]->resetting == SIG_PRI_RESET_IDLE) { 06208 /* The channel is not in the resetting state. */ 06209 ast_debug(1, 06210 "Span %d: Unexpected or late restart ack on channel %d/%d (Ignoring)\n", 06211 pri->span, pri->pvts[chanpos]->logicalspan, 06212 pri->pvts[chanpos]->prioffset); 06213 sig_pri_unlock_private(pri->pvts[chanpos]); 06214 break; 06215 } 06216 if (pri->pvts[chanpos]->owner) { 06217 ast_log(LOG_WARNING, 06218 "Span %d: Got restart ack on channel %d/%d with owner\n", 06219 pri->span, pri->pvts[chanpos]->logicalspan, 06220 pri->pvts[chanpos]->prioffset); 06221 pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV; 06222 } 06223 pri->pvts[chanpos]->resetting = SIG_PRI_RESET_IDLE; 06224 ast_verb(3, 06225 "Span %d: Channel %d/%d successfully restarted\n", 06226 pri->span, pri->pvts[chanpos]->logicalspan, 06227 pri->pvts[chanpos]->prioffset); 06228 sig_pri_unlock_private(pri->pvts[chanpos]); 06229 if (pri->resetting) 06230 pri_check_restart(pri); 06231 } 06232 break; 06233 case PRI_EVENT_SETUP_ACK: 06234 if (sig_pri_is_cis_call(e->setup_ack.channel)) { 06235 sig_pri_handle_cis_subcmds(pri, e->e, e->setup_ack.subcmds, 06236 e->setup_ack.call); 06237 break; 06238 } 06239 chanpos = pri_find_fixup_principle(pri, e->setup_ack.channel, 06240 e->setup_ack.call); 06241 if (chanpos < 0) { 06242 break; 06243 } 06244 sig_pri_lock_private(pri->pvts[chanpos]); 06245 sig_pri_handle_subcmds(pri, chanpos, e->e, e->setup_ack.channel, 06246 e->setup_ack.subcmds, e->setup_ack.call); 06247 if (pri->pvts[chanpos]->call_level < SIG_PRI_CALL_LEVEL_OVERLAP) { 06248 pri->pvts[chanpos]->call_level = SIG_PRI_CALL_LEVEL_OVERLAP; 06249 } 06250 06251 /* Send any queued digits */ 06252 len = strlen(pri->pvts[chanpos]->dialdest); 06253 for (x = 0; x < len; ++x) { 06254 ast_debug(1, "Sending pending digit '%c'\n", pri->pvts[chanpos]->dialdest[x]); 06255 pri_information(pri->pri, pri->pvts[chanpos]->call, 06256 pri->pvts[chanpos]->dialdest[x]); 06257 } 06258 06259 if (!pri->pvts[chanpos]->progress 06260 && (pri->overlapdial & DAHDI_OVERLAPDIAL_OUTGOING) 06261 && !pri->pvts[chanpos]->digital 06262 && !pri->pvts[chanpos]->no_b_channel) { 06263 /* 06264 * Call has a channel. 06265 * Indicate for overlap dialing that dialtone may be present. 06266 */ 06267 pri_queue_control(pri, chanpos, AST_CONTROL_PROGRESS); 06268 pri->pvts[chanpos]->progress = 1;/* Claim to have seen inband-information */ 06269 sig_pri_set_dialing(pri->pvts[chanpos], 0); 06270 sig_pri_open_media(pri->pvts[chanpos]); 06271 } 06272 sig_pri_unlock_private(pri->pvts[chanpos]); 06273 break; 06274 case PRI_EVENT_NOTIFY: 06275 if (sig_pri_is_cis_call(e->notify.channel)) { 06276 #if defined(HAVE_PRI_CALL_HOLD) 06277 sig_pri_handle_cis_subcmds(pri, e->e, e->notify.subcmds, 06278 e->notify.call); 06279 #else 06280 sig_pri_handle_cis_subcmds(pri, e->e, e->notify.subcmds, NULL); 06281 #endif /* !defined(HAVE_PRI_CALL_HOLD) */ 06282 break; 06283 } 06284 #if defined(HAVE_PRI_CALL_HOLD) 06285 chanpos = pri_find_principle_by_call(pri, e->notify.call); 06286 if (chanpos < 0) { 06287 ast_log(LOG_WARNING, "Span %d: Received NOTIFY for unknown call.\n", 06288 pri->span); 06289 break; 06290 } 06291 #else 06292 /* 06293 * This version of libpri does not supply a call pointer for 06294 * this message. We are just going to have to trust that the 06295 * correct principle is found. 06296 */ 06297 chanpos = pri_find_principle(pri, e->notify.channel, NULL); 06298 if (chanpos < 0) { 06299 ast_log(LOG_WARNING, "Received NOTIFY on unconfigured channel %d/%d span %d\n", 06300 PRI_SPAN(e->notify.channel), PRI_CHANNEL(e->notify.channel), pri->span); 06301 break; 06302 } 06303 #endif /* !defined(HAVE_PRI_CALL_HOLD) */ 06304 sig_pri_lock_private(pri->pvts[chanpos]); 06305 #if defined(HAVE_PRI_CALL_HOLD) 06306 sig_pri_handle_subcmds(pri, chanpos, e->e, e->notify.channel, 06307 e->notify.subcmds, e->notify.call); 06308 #else 06309 sig_pri_handle_subcmds(pri, chanpos, e->e, e->notify.channel, 06310 e->notify.subcmds, NULL); 06311 #endif /* !defined(HAVE_PRI_CALL_HOLD) */ 06312 switch (e->notify.info) { 06313 case PRI_NOTIFY_REMOTE_HOLD: 06314 if (!pri->discardremoteholdretrieval) { 06315 pri_queue_control(pri, chanpos, AST_CONTROL_HOLD); 06316 } 06317 break; 06318 case PRI_NOTIFY_REMOTE_RETRIEVAL: 06319 if (!pri->discardremoteholdretrieval) { 06320 pri_queue_control(pri, chanpos, AST_CONTROL_UNHOLD); 06321 } 06322 break; 06323 } 06324 sig_pri_unlock_private(pri->pvts[chanpos]); 06325 break; 06326 #if defined(HAVE_PRI_CALL_HOLD) 06327 case PRI_EVENT_HOLD: 06328 /* We should not be getting any CIS calls with this message type. */ 06329 if (sig_pri_handle_hold(pri, e)) { 06330 pri_hold_rej(pri->pri, e->hold.call, 06331 PRI_CAUSE_RESOURCE_UNAVAIL_UNSPECIFIED); 06332 } else { 06333 pri_hold_ack(pri->pri, e->hold.call); 06334 } 06335 break; 06336 #endif /* defined(HAVE_PRI_CALL_HOLD) */ 06337 #if defined(HAVE_PRI_CALL_HOLD) 06338 case PRI_EVENT_HOLD_ACK: 06339 ast_debug(1, "Event: HOLD_ACK\n"); 06340 break; 06341 #endif /* defined(HAVE_PRI_CALL_HOLD) */ 06342 #if defined(HAVE_PRI_CALL_HOLD) 06343 case PRI_EVENT_HOLD_REJ: 06344 ast_debug(1, "Event: HOLD_REJ\n"); 06345 break; 06346 #endif /* defined(HAVE_PRI_CALL_HOLD) */ 06347 #if defined(HAVE_PRI_CALL_HOLD) 06348 case PRI_EVENT_RETRIEVE: 06349 /* We should not be getting any CIS calls with this message type. */ 06350 sig_pri_handle_retrieve(pri, e); 06351 break; 06352 #endif /* defined(HAVE_PRI_CALL_HOLD) */ 06353 #if defined(HAVE_PRI_CALL_HOLD) 06354 case PRI_EVENT_RETRIEVE_ACK: 06355 ast_debug(1, "Event: RETRIEVE_ACK\n"); 06356 break; 06357 #endif /* defined(HAVE_PRI_CALL_HOLD) */ 06358 #if defined(HAVE_PRI_CALL_HOLD) 06359 case PRI_EVENT_RETRIEVE_REJ: 06360 ast_debug(1, "Event: RETRIEVE_REJ\n"); 06361 break; 06362 #endif /* defined(HAVE_PRI_CALL_HOLD) */ 06363 default: 06364 ast_debug(1, "Event: %d\n", e->e); 06365 break; 06366 } 06367 } 06368 ast_mutex_unlock(&pri->lock); 06369 } 06370 /* Never reached */ 06371 return NULL; 06372 }
void pri_event_alarm | ( | struct sig_pri_span * | pri, | |
int | index, | |||
int | before_start_pri | |||
) |
Definition at line 2001 of file sig_pri.c.
References DCHAN_NOTINALARM, DCHAN_UP, sig_pri_span::dchanavail, and pri_find_dchan().
Referenced by my_handle_dchan_exception(), and prepare_pri().
02002 { 02003 pri->dchanavail[index] &= ~(DCHAN_NOTINALARM | DCHAN_UP); 02004 if (!before_start_pri) { 02005 pri_find_dchan(pri); 02006 } 02007 }
void pri_event_noalarm | ( | struct sig_pri_span * | pri, | |
int | index, | |||
int | before_start_pri | |||
) |
Definition at line 2009 of file sig_pri.c.
References DCHAN_NOTINALARM, sig_pri_span::dchanavail, and sig_pri_span::dchans.
Referenced by my_handle_dchan_exception(), and prepare_pri().
02010 { 02011 pri->dchanavail[index] |= DCHAN_NOTINALARM; 02012 if (!before_start_pri) 02013 pri_restart(pri->dchans[index]); 02014 }
static void pri_find_dchan | ( | struct sig_pri_span * | pri | ) | [static] |
Definition at line 1066 of file sig_pri.c.
References sig_pri_span::dchans, sig_pri_span::pri, and SIG_PRI_NUM_DCHANS.
Referenced by pri_event_alarm().
01067 { 01068 struct pri *old; 01069 int oldslot = -1; 01070 int newslot = -1; 01071 int idx; 01072 01073 old = pri->pri; 01074 for (idx = 0; idx < SIG_PRI_NUM_DCHANS; ++idx) { 01075 if (!pri->dchans[idx]) { 01076 /* No more D channels defined on the span. */ 01077 break; 01078 } 01079 if (pri->dchans[idx] == old) { 01080 oldslot = idx; 01081 } 01082 if (newslot < 0 && pri->dchanavail[idx] == DCHAN_AVAILABLE) { 01083 newslot = idx; 01084 } 01085 } 01086 /* At this point, idx is a count of how many D-channels are defined on the span. */ 01087 01088 if (1 < idx) { 01089 /* We have several D-channels defined on the span. (NFAS PRI setup) */ 01090 if (newslot < 0) { 01091 /* No D-channels available. Default to the primary D-channel. */ 01092 newslot = 0; 01093 01094 if (!pri->no_d_channels) { 01095 pri->no_d_channels = 1; 01096 if (old && oldslot != newslot) { 01097 ast_log(LOG_WARNING, 01098 "Span %d: No D-channels up! Switching selected D-channel from %s to %s.\n", 01099 pri->span, pri_order(oldslot), pri_order(newslot)); 01100 } else { 01101 ast_log(LOG_WARNING, "Span %d: No D-channels up!\n", pri->span); 01102 } 01103 } 01104 } else { 01105 pri->no_d_channels = 0; 01106 } 01107 if (old && oldslot != newslot) { 01108 ast_log(LOG_NOTICE, 01109 "Switching selected D-channel from %s (fd %d) to %s (fd %d)!\n", 01110 pri_order(oldslot), pri->fds[oldslot], 01111 pri_order(newslot), pri->fds[newslot]); 01112 } 01113 } else { 01114 if (newslot < 0) { 01115 /* The only D-channel is not up. */ 01116 newslot = 0; 01117 01118 if (!pri->no_d_channels) { 01119 pri->no_d_channels = 1; 01120 01121 /* 01122 * This is annoying to see on non-persistent layer 2 01123 * connections. Let's not complain in that case. 01124 */ 01125 if (pri->sig != SIG_BRI_PTMP) { 01126 ast_log(LOG_WARNING, "Span %d: D-channel is down!\n", pri->span); 01127 } 01128 } 01129 } else { 01130 pri->no_d_channels = 0; 01131 } 01132 } 01133 pri->pri = pri->dchans[newslot]; 01134 }
static int pri_find_empty_chan | ( | struct sig_pri_span * | pri, | |
int | backwards | |||
) | [static] |
Definition at line 1764 of file sig_pri.c.
References ast_debug, sig_pri_chan::logicalspan, sig_pri_chan::no_b_channel, sig_pri_span::numchans, sig_pri_chan::pri, sig_pri_chan::prioffset, sig_pri_span::pvts, and sig_pri_is_chan_available().
Referenced by sig_pri_handle_retrieve().
01765 { 01766 int x; 01767 if (backwards) 01768 x = pri->numchans; 01769 else 01770 x = 0; 01771 for (;;) { 01772 if (backwards && (x < 0)) 01773 break; 01774 if (!backwards && (x >= pri->numchans)) 01775 break; 01776 if (pri->pvts[x] 01777 && !pri->pvts[x]->no_b_channel 01778 && sig_pri_is_chan_available(pri->pvts[x])) { 01779 ast_debug(1, "Found empty available channel %d/%d\n", 01780 pri->pvts[x]->logicalspan, pri->pvts[x]->prioffset); 01781 return x; 01782 } 01783 if (backwards) 01784 x--; 01785 else 01786 x++; 01787 } 01788 return -1; 01789 }
static int pri_find_empty_nobch | ( | struct sig_pri_span * | pri | ) | [static] |
Definition at line 1804 of file sig_pri.c.
References ast_debug, sig_pri_chan::no_b_channel, sig_pri_span::numchans, sig_pri_chan::pri, sig_pri_span::pvts, and sig_pri_is_chan_available().
Referenced by sig_pri_cw_available(), and sig_pri_handle_hold().
01805 { 01806 int idx; 01807 01808 for (idx = 0; idx < pri->numchans; ++idx) { 01809 if (pri->pvts[idx] 01810 && pri->pvts[idx]->no_b_channel 01811 && sig_pri_is_chan_available(pri->pvts[idx])) { 01812 ast_debug(1, "Found empty available no B channel interface\n"); 01813 return idx; 01814 } 01815 } 01816 01817 /* Need to create a new interface. */ 01818 if (pri->calls->new_nobch_intf) { 01819 idx = pri->calls->new_nobch_intf(pri); 01820 } else { 01821 idx = -1; 01822 } 01823 return idx; 01824 }
static int pri_find_fixup_principle | ( | struct sig_pri_span * | pri, | |
int | channel, | |||
q931_call * | call | |||
) | [static] |
Definition at line 1563 of file sig_pri.c.
References ast_log(), LOG_WARNING, sig_pri_chan::pri, PRI_CHANNEL, pri_find_principle(), pri_fixup_principle(), PRI_SPAN, sig_pri_kill_call(), and sig_pri_span::span.
01564 { 01565 int chanpos; 01566 01567 chanpos = pri_find_principle(pri, channel, call); 01568 if (chanpos < 0) { 01569 ast_log(LOG_WARNING, "Span %d: PRI requested channel %d/%d is unconfigured.\n", 01570 pri->span, PRI_SPAN(channel), PRI_CHANNEL(channel)); 01571 sig_pri_kill_call(pri, call, PRI_CAUSE_IDENTIFIED_CHANNEL_NOTEXIST); 01572 return -1; 01573 } 01574 chanpos = pri_fixup_principle(pri, chanpos, call); 01575 if (chanpos < 0) { 01576 ast_log(LOG_WARNING, "Span %d: PRI requested channel %d/%d is not available.\n", 01577 pri->span, PRI_SPAN(channel), PRI_CHANNEL(channel)); 01578 /* 01579 * Using Q.931 section 5.2.3.1 b) as the reason for picking 01580 * PRI_CAUSE_CHANNEL_UNACCEPTABLE. Receiving a 01581 * PRI_CAUSE_REQUESTED_CHAN_UNAVAIL would cause us to restart 01582 * that channel (which is not specified by Q.931) and kill some 01583 * other call which would be bad. 01584 */ 01585 sig_pri_kill_call(pri, call, PRI_CAUSE_CHANNEL_UNACCEPTABLE); 01586 return -1; 01587 } 01588 return chanpos; 01589 }
static int pri_find_principle | ( | struct sig_pri_span * | pri, | |
int | channel, | |||
q931_call * | call | |||
) | [static] |
Definition at line 1329 of file sig_pri.c.
References sig_pri_chan::call, sig_pri_span::numchans, sig_pri_chan::pri, PRI_CHANNEL, PRI_HELD_CALL, sig_pri_chan::prioffset, and sig_pri_span::pvts.
Referenced by pri_find_fixup_principle(), and sig_pri_handle_retrieve().
01330 { 01331 int x; 01332 int span; 01333 int principle; 01334 int prioffset; 01335 01336 if (channel < 0) { 01337 /* Channel is not picked yet. */ 01338 return -1; 01339 } 01340 01341 prioffset = PRI_CHANNEL(channel); 01342 if (!prioffset || (channel & PRI_HELD_CALL)) { 01343 if (!call) { 01344 /* Cannot find a call waiting call or held call without a call. */ 01345 return -1; 01346 } 01347 principle = -1; 01348 for (x = 0; x < pri->numchans; ++x) { 01349 if (pri->pvts[x] 01350 && pri->pvts[x]->call == call) { 01351 principle = x; 01352 break; 01353 } 01354 } 01355 return principle; 01356 } 01357 01358 span = PRI_SPAN(channel); 01359 if (!(channel & PRI_EXPLICIT)) { 01360 int index; 01361 01362 index = pri_active_dchan_index(pri); 01363 if (index == -1) { 01364 return -1; 01365 } 01366 span = pri->dchan_logical_span[index]; 01367 } 01368 01369 principle = -1; 01370 for (x = 0; x < pri->numchans; x++) { 01371 if (pri->pvts[x] 01372 && pri->pvts[x]->prioffset == prioffset 01373 && pri->pvts[x]->logicalspan == span 01374 && !pri->pvts[x]->no_b_channel) { 01375 principle = x; 01376 break; 01377 } 01378 } 01379 01380 return principle; 01381 }
static int pri_find_principle_by_call | ( | struct sig_pri_span * | pri, | |
q931_call * | call | |||
) | [static] |
Definition at line 1264 of file sig_pri.c.
References sig_pri_chan::call, sig_pri_span::numchans, sig_pri_chan::pri, and sig_pri_span::pvts.
Referenced by sig_pri_attempt_transfer(), sig_pri_handle_hold(), sig_pri_handle_retrieve(), and sig_pri_kill_call().
01265 { 01266 int idx; 01267 01268 if (!call) { 01269 /* Cannot find a call without a call. */ 01270 return -1; 01271 } 01272 for (idx = 0; idx < pri->numchans; ++idx) { 01273 if (pri->pvts[idx] && pri->pvts[idx]->call == call) { 01274 /* Found the principle */ 01275 return idx; 01276 } 01277 } 01278 return -1; 01279 }
static int pri_fixup_principle | ( | struct sig_pri_span * | pri, | |
int | principle, | |||
q931_call * | call | |||
) | [static] |
Definition at line 1396 of file sig_pri.c.
References ast_channel_unlock, ast_log(), ast_verb, sig_pri_chan::call, LOG_WARNING, sig_pri_span::numchans, sig_pri_chan::pri, sig_pri_span::pvts, sig_pri_ami_channel_event(), SIG_PRI_CALL_LEVEL_IDLE, sig_pri_fixup_chans(), sig_pri_is_chan_available(), sig_pri_lock_owner(), sig_pri_lock_private(), sig_pri_open_media(), and sig_pri_unlock_private().
Referenced by pri_find_fixup_principle(), sig_pri_handle_hold(), and sig_pri_handle_retrieve().
01397 { 01398 int x; 01399 01400 if (principle < 0 || pri->numchans <= principle) { 01401 /* Out of rannge */ 01402 return -1; 01403 } 01404 if (!call) { 01405 /* No call */ 01406 return principle; 01407 } 01408 if (pri->pvts[principle] && pri->pvts[principle]->call == call) { 01409 /* Call is already on the specified principle. */ 01410 return principle; 01411 } 01412 01413 /* Find the old principle location. */ 01414 for (x = 0; x < pri->numchans; x++) { 01415 struct sig_pri_chan *new_chan; 01416 struct sig_pri_chan *old_chan; 01417 01418 if (!pri->pvts[x] || pri->pvts[x]->call != call) { 01419 continue; 01420 } 01421 01422 /* Found our call */ 01423 new_chan = pri->pvts[principle]; 01424 old_chan = pri->pvts[x]; 01425 01426 /* Get locks to safely move to the new private structure. */ 01427 sig_pri_lock_private(old_chan); 01428 sig_pri_lock_owner(pri, x); 01429 sig_pri_lock_private(new_chan); 01430 01431 ast_verb(3, "Moving call (%s) from channel %d to %d.\n", 01432 old_chan->owner ? old_chan->owner->name : "", 01433 old_chan->channel, new_chan->channel); 01434 if (!sig_pri_is_chan_available(new_chan)) { 01435 ast_log(LOG_WARNING, 01436 "Can't move call (%s) from channel %d to %d. It is already in use.\n", 01437 old_chan->owner ? old_chan->owner->name : "", 01438 old_chan->channel, new_chan->channel); 01439 sig_pri_unlock_private(new_chan); 01440 if (old_chan->owner) { 01441 ast_channel_unlock(old_chan->owner); 01442 } 01443 sig_pri_unlock_private(old_chan); 01444 return -1; 01445 } 01446 01447 sig_pri_fixup_chans(old_chan, new_chan); 01448 01449 /* Fix it all up now */ 01450 new_chan->owner = old_chan->owner; 01451 old_chan->owner = NULL; 01452 01453 new_chan->call = old_chan->call; 01454 old_chan->call = NULL; 01455 01456 /* Transfer flags from the old channel. */ 01457 #if defined(HAVE_PRI_AOC_EVENTS) 01458 new_chan->aoc_s_request_invoke_id_valid = old_chan->aoc_s_request_invoke_id_valid; 01459 new_chan->waiting_for_aoce = old_chan->waiting_for_aoce; 01460 new_chan->holding_aoce = old_chan->holding_aoce; 01461 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 01462 new_chan->alreadyhungup = old_chan->alreadyhungup; 01463 new_chan->isidlecall = old_chan->isidlecall; 01464 new_chan->progress = old_chan->progress; 01465 new_chan->allocated = old_chan->allocated; 01466 new_chan->outgoing = old_chan->outgoing; 01467 new_chan->digital = old_chan->digital; 01468 #if defined(HAVE_PRI_CALL_WAITING) 01469 new_chan->is_call_waiting = old_chan->is_call_waiting; 01470 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 01471 01472 #if defined(HAVE_PRI_AOC_EVENTS) 01473 old_chan->aoc_s_request_invoke_id_valid = 0; 01474 old_chan->waiting_for_aoce = 0; 01475 old_chan->holding_aoce = 0; 01476 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 01477 old_chan->alreadyhungup = 0; 01478 old_chan->isidlecall = 0; 01479 old_chan->progress = 0; 01480 old_chan->allocated = 0; 01481 old_chan->outgoing = 0; 01482 old_chan->digital = 0; 01483 #if defined(HAVE_PRI_CALL_WAITING) 01484 old_chan->is_call_waiting = 0; 01485 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 01486 01487 /* More stuff to transfer to the new channel. */ 01488 new_chan->call_level = old_chan->call_level; 01489 old_chan->call_level = SIG_PRI_CALL_LEVEL_IDLE; 01490 #if defined(HAVE_PRI_REVERSE_CHARGE) 01491 new_chan->reverse_charging_indication = old_chan->reverse_charging_indication; 01492 #endif /* defined(HAVE_PRI_REVERSE_CHARGE) */ 01493 #if defined(HAVE_PRI_SETUP_KEYPAD) 01494 strcpy(new_chan->keypad_digits, old_chan->keypad_digits); 01495 #endif /* defined(HAVE_PRI_SETUP_KEYPAD) */ 01496 strcpy(new_chan->deferred_digits, old_chan->deferred_digits); 01497 #if defined(HAVE_PRI_AOC_EVENTS) 01498 new_chan->aoc_s_request_invoke_id = old_chan->aoc_s_request_invoke_id; 01499 new_chan->aoc_e = old_chan->aoc_e; 01500 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 01501 strcpy(new_chan->user_tag, old_chan->user_tag); 01502 01503 if (new_chan->no_b_channel) { 01504 /* Copy the real channel configuration to the no B channel interface. */ 01505 new_chan->hidecallerid = old_chan->hidecallerid; 01506 new_chan->hidecalleridname = old_chan->hidecalleridname; 01507 new_chan->immediate = old_chan->immediate; 01508 new_chan->priexclusive = old_chan->priexclusive; 01509 new_chan->priindication_oob = old_chan->priindication_oob; 01510 new_chan->use_callerid = old_chan->use_callerid; 01511 new_chan->use_callingpres = old_chan->use_callingpres; 01512 new_chan->stripmsd = old_chan->stripmsd; 01513 strcpy(new_chan->context, old_chan->context); 01514 strcpy(new_chan->mohinterpret, old_chan->mohinterpret); 01515 01516 /* Become a member of the old channel span/trunk-group. */ 01517 new_chan->logicalspan = old_chan->logicalspan; 01518 new_chan->mastertrunkgroup = old_chan->mastertrunkgroup; 01519 } else if (old_chan->no_b_channel) { 01520 /* 01521 * We are transitioning from a held/call-waiting channel to a 01522 * real channel so we need to make sure that the media path is 01523 * open. (Needed especially if the channel is natively 01524 * bridged.) 01525 */ 01526 sig_pri_open_media(new_chan); 01527 } 01528 01529 if (new_chan->owner) { 01530 sig_pri_ami_channel_event(new_chan); 01531 } 01532 01533 sig_pri_unlock_private(old_chan); 01534 if (new_chan->owner) { 01535 ast_channel_unlock(new_chan->owner); 01536 } 01537 sig_pri_unlock_private(new_chan); 01538 01539 return principle; 01540 } 01541 ast_verb(3, "Call specified, but not found.\n"); 01542 return -1; 01543 }
static int pri_grab | ( | struct sig_pri_chan * | p, | |
struct sig_pri_span * | pri | |||
) | [inline, static] |
Definition at line 342 of file sig_pri.c.
References ast_mutex_trylock, AST_PTHREADT_NULL, sig_pri_span::lock, sig_pri_span::master, sig_pri_lock_private(), and sig_pri_unlock_private().
Referenced by pri_send_callrerouting_facility_exec(), pri_send_keypad_facility_exec(), pri_ss_thread(), sig_pri_answer(), sig_pri_call(), sig_pri_chan_alarm_notify(), sig_pri_digit_begin(), sig_pri_hangup(), and sig_pri_indicate().
00343 { 00344 /* Grab the lock first */ 00345 while (ast_mutex_trylock(&pri->lock)) { 00346 /* Avoid deadlock */ 00347 sig_pri_unlock_private(p); 00348 sched_yield(); 00349 sig_pri_lock_private(p); 00350 } 00351 /* Then break the poll */ 00352 if (pri->master != AST_PTHREADT_NULL) { 00353 pthread_kill(pri->master, SIGURG); 00354 } 00355 return 0; 00356 }
int pri_is_up | ( | struct sig_pri_span * | pri | ) |
Definition at line 1026 of file sig_pri.c.
References DCHAN_AVAILABLE, sig_pri_span::dchanavail, and SIG_PRI_NUM_DCHANS.
Referenced by pri_dchannel().
01027 { 01028 int x; 01029 for (x = 0; x < SIG_PRI_NUM_DCHANS; x++) { 01030 if (pri->dchanavail[x] == DCHAN_AVAILABLE) 01031 return 1; 01032 } 01033 return 0; 01034 }
int pri_maintenance_bservice | ( | struct pri * | pri, | |
struct sig_pri_chan * | p, | |||
int | changestatus | |||
) |
Definition at line 8031 of file sig_pri.c.
References sig_pri_chan::channel, PRI_SPAN, and PVT_TO_CHANNEL().
08032 { 08033 int channel = PVT_TO_CHANNEL(p); 08034 int span = PRI_SPAN(channel); 08035 08036 return pri_maintenance_service(pri, span, channel, changestatus); 08037 }
static const char* pri_order | ( | int | level | ) | [static] |
Definition at line 1036 of file sig_pri.c.
Referenced by pri_dchannel(), and sig_pri_cli_show_span().
01037 { 01038 switch (level) { 01039 case 0: 01040 return "Primary"; 01041 case 1: 01042 return "Secondary"; 01043 case 2: 01044 return "Tertiary"; 01045 case 3: 01046 return "Quaternary"; 01047 default: 01048 return "<Unknown>"; 01049 } 01050 }
static void pri_queue_control | ( | struct sig_pri_span * | pri, | |
int | chanpos, | |||
int | subclass | |||
) | [static] |
Definition at line 1238 of file sig_pri.c.
References AST_FRAME_CONTROL, sig_pri_chan::calls, sig_pri_chan::chan_pvt, f, sig_pri_chan::pri, pri_queue_frame(), sig_pri_span::pvts, and sig_pri_callback::queue_control.
Referenced by sig_pri_handle_retrieve(), and sig_pri_kill_call().
01239 { 01240 struct ast_frame f = {AST_FRAME_CONTROL, }; 01241 struct sig_pri_chan *p = pri->pvts[chanpos]; 01242 01243 if (p->calls->queue_control) { 01244 p->calls->queue_control(p->chan_pvt, subclass); 01245 } 01246 01247 f.subclass.integer = subclass; 01248 pri_queue_frame(pri, chanpos, &f); 01249 }
static void pri_queue_frame | ( | struct sig_pri_span * | pri, | |
int | chanpos, | |||
struct ast_frame * | frame | |||
) | [static] |
Definition at line 1215 of file sig_pri.c.
References ast_channel_unlock, ast_queue_frame(), sig_pri_chan::owner, sig_pri_span::pvts, and sig_pri_lock_owner().
Referenced by pri_queue_control().
01216 { 01217 sig_pri_lock_owner(pri, chanpos); 01218 if (pri->pvts[chanpos]->owner) { 01219 ast_queue_frame(pri->pvts[chanpos]->owner, frame); 01220 ast_channel_unlock(pri->pvts[chanpos]->owner); 01221 } 01222 }
static void pri_rel | ( | struct sig_pri_span * | pri | ) | [inline, static] |
Definition at line 144 of file sig_pri.c.
References ast_mutex_unlock, and sig_pri_span::lock.
Referenced by pri_send_callrerouting_facility_exec(), pri_send_keypad_facility_exec(), pri_ss_thread(), sig_pri_answer(), sig_pri_call(), sig_pri_chan_alarm_notify(), sig_pri_digit_begin(), sig_pri_hangup(), and sig_pri_indicate().
00145 { 00146 ast_mutex_unlock(&pri->lock); 00147 }
int pri_send_callrerouting_facility_exec | ( | struct sig_pri_chan * | p, | |
enum ast_channel_state | chanstate, | |||
const char * | destination, | |||
const char * | original, | |||
const char * | reason | |||
) |
Definition at line 8009 of file sig_pri.c.
References ast_log(), sig_pri_chan::call, LOG_DEBUG, sig_pri_chan::pri, sig_pri_span::pri, pri_grab(), pri_rel(), sig_pri_lock_private(), and sig_pri_unlock_private().
Referenced by dahdi_send_callrerouting_facility_exec().
08010 { 08011 int res; 08012 08013 sig_pri_lock_private(p); 08014 08015 if (!p->pri || !p->call) { 08016 ast_log(LOG_DEBUG, "Unable to find pri or call on channel!\n"); 08017 sig_pri_unlock_private(p); 08018 return -1; 08019 } 08020 08021 pri_grab(p, p->pri); 08022 res = pri_callrerouting_facility(p->pri->pri, p->call, destination, original, reason); 08023 pri_rel(p->pri); 08024 08025 sig_pri_unlock_private(p); 08026 08027 return res; 08028 }
int pri_send_keypad_facility_exec | ( | struct sig_pri_chan * | p, | |
const char * | digits | |||
) |
Definition at line 7990 of file sig_pri.c.
References ast_debug, sig_pri_chan::call, sig_pri_chan::pri, sig_pri_span::pri, pri_grab(), pri_rel(), sig_pri_lock_private(), and sig_pri_unlock_private().
Referenced by dahdi_send_keypad_facility_exec().
07991 { 07992 sig_pri_lock_private(p); 07993 07994 if (!p->pri || !p->call) { 07995 ast_debug(1, "Unable to find pri or call on channel!\n"); 07996 sig_pri_unlock_private(p); 07997 return -1; 07998 } 07999 08000 pri_grab(p, p->pri); 08001 pri_keypad_facility(p->pri->pri, p->call, digits); 08002 pri_rel(p->pri); 08003 08004 sig_pri_unlock_private(p); 08005 08006 return 0; 08007 }
static void* pri_ss_thread | ( | void * | data | ) | [static] |
Definition at line 1876 of file sig_pri.c.
References sig_pri_span::append_msn_to_user_tag, AST_CAUSE_UNALLOCATED, ast_copy_string(), ast_exists_extension(), ast_free, ast_hangup(), ast_ignore_pattern(), ast_log(), ast_matchmore_extension(), AST_MAX_EXTENSION, ast_mutex_lock, ast_mutex_unlock, ast_pbx_run(), ast_setstate(), AST_STATE_RING, ast_strdup, ast_strlen_zero(), ast_verb, ast_waitfordigit(), sig_pri_chan::call, sig_pri_chan::call_level, ast_channel::caller, sig_pri_chan::cid_num, ast_channel::context, DAHDI_OVERLAPDIAL_INCOMING, ast_channel::dialed, ast_channel::exten, sig_pri_chan::exten, exten, ast_channel::hangupcause, ast_party_caller::id, sig_pri_span::initial_user_tag, len(), sig_pri_span::lock, LOG_DEBUG, LOG_WARNING, ast_channel::name, sig_pri_span::nodetype, ast_party_dialed::number, sig_pri_span::overlapdial, sig_pri_chan::owner, sig_pri_span::pri, sig_pri_chan::pri, pri_gendigittimeout, pri_grab(), pri_matchdigittimeout, pri_rel(), PVT_TO_CHANNEL(), SIG_PRI_CALL_LEVEL_PROCEEDING, sig_pri_dsp_reset_and_flush_digits(), sig_pri_lock_private(), sig_pri_play_tone(), sig_pri_set_echocanceller(), sig_pri_span_devstate_changed(), SIG_PRI_TONE_DIALTONE, sig_pri_unlock_private(), ast_party_dialed::str, ast_party_id::tag, ast_channel::tech_pvt, and sig_pri_chan::user_tag.
01877 { 01878 struct sig_pri_chan *p = data; 01879 struct ast_channel *chan = p->owner; 01880 char exten[AST_MAX_EXTENSION]; 01881 int res; 01882 int len; 01883 int timeout; 01884 01885 if (!chan) { 01886 /* We lost the owner before we could get started. */ 01887 return NULL; 01888 } 01889 01890 /* 01891 * In the bizarre case where the channel has become a zombie before we 01892 * even get started here, abort safely. 01893 */ 01894 if (!chan->tech_pvt) { 01895 ast_log(LOG_WARNING, "Channel became a zombie before simple switch could be started (%s)\n", chan->name); 01896 ast_hangup(chan); 01897 return NULL; 01898 } 01899 01900 ast_verb(3, "Starting simple switch on '%s'\n", chan->name); 01901 01902 sig_pri_dsp_reset_and_flush_digits(p); 01903 01904 /* Now loop looking for an extension */ 01905 ast_copy_string(exten, p->exten, sizeof(exten)); 01906 len = strlen(exten); 01907 res = 0; 01908 while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) { 01909 if (len && !ast_ignore_pattern(chan->context, exten)) 01910 sig_pri_play_tone(p, -1); 01911 else 01912 sig_pri_play_tone(p, SIG_PRI_TONE_DIALTONE); 01913 if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num)) 01914 timeout = pri_matchdigittimeout; 01915 else 01916 timeout = pri_gendigittimeout; 01917 res = ast_waitfordigit(chan, timeout); 01918 if (res < 0) { 01919 ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n"); 01920 ast_hangup(chan); 01921 return NULL; 01922 } else if (res) { 01923 exten[len++] = res; 01924 exten[len] = '\0'; 01925 } else 01926 break; 01927 } 01928 /* if no extension was received ('unspecified') on overlap call, use the 's' extension */ 01929 if (ast_strlen_zero(exten)) { 01930 ast_verb(3, "Going to extension s|1 because of empty extension received on overlap call\n"); 01931 exten[0] = 's'; 01932 exten[1] = '\0'; 01933 } else { 01934 ast_free(chan->dialed.number.str); 01935 chan->dialed.number.str = ast_strdup(exten); 01936 01937 if (p->pri->append_msn_to_user_tag && p->pri->nodetype != PRI_NETWORK) { 01938 /* 01939 * Update the user tag for party id's from this device for this call 01940 * now that we have a complete MSN from the network. 01941 */ 01942 snprintf(p->user_tag, sizeof(p->user_tag), "%s_%s", p->pri->initial_user_tag, 01943 exten); 01944 ast_free(chan->caller.id.tag); 01945 chan->caller.id.tag = ast_strdup(p->user_tag); 01946 } 01947 } 01948 sig_pri_play_tone(p, -1); 01949 if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num)) { 01950 /* Start the real PBX */ 01951 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 01952 sig_pri_dsp_reset_and_flush_digits(p); 01953 #if defined(ISSUE_16789) 01954 /* 01955 * Conditionaled out this code to effectively revert the Mantis 01956 * issue 16789 change. It breaks overlap dialing through 01957 * Asterisk. There is not enough information available at this 01958 * point to know if dialing is complete. The 01959 * ast_exists_extension(), ast_matchmore_extension(), and 01960 * ast_canmatch_extension() calls are not adequate to detect a 01961 * dial through extension pattern of "_9!". 01962 * 01963 * Workaround is to use the dialplan Proceeding() application 01964 * early on non-dial through extensions. 01965 */ 01966 if ((p->pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING) 01967 && !ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) { 01968 sig_pri_lock_private(p); 01969 if (p->pri->pri) { 01970 pri_grab(p, p->pri); 01971 if (p->call_level < SIG_PRI_CALL_LEVEL_PROCEEDING) { 01972 p->call_level = SIG_PRI_CALL_LEVEL_PROCEEDING; 01973 } 01974 pri_proceeding(p->pri->pri, p->call, PVT_TO_CHANNEL(p), 0); 01975 pri_rel(p->pri); 01976 } 01977 sig_pri_unlock_private(p); 01978 } 01979 #endif /* defined(ISSUE_16789) */ 01980 01981 sig_pri_set_echocanceller(p, 1); 01982 ast_setstate(chan, AST_STATE_RING); 01983 res = ast_pbx_run(chan); 01984 if (res) { 01985 ast_log(LOG_WARNING, "PBX exited non-zero!\n"); 01986 } 01987 } else { 01988 ast_log(LOG_DEBUG, "No such possible extension '%s' in context '%s'\n", exten, chan->context); 01989 chan->hangupcause = AST_CAUSE_UNALLOCATED; 01990 ast_hangup(chan); 01991 p->exten[0] = '\0'; 01992 /* Since we send release complete here, we won't get one */ 01993 p->call = NULL; 01994 ast_mutex_lock(&p->pri->lock); 01995 sig_pri_span_devstate_changed(p->pri); 01996 ast_mutex_unlock(&p->pri->lock); 01997 } 01998 return NULL; 01999 }
static enum AST_PARTY_CHAR_SET pri_to_ast_char_set | ( | int | pri_char_set | ) | [static] |
Definition at line 547 of file sig_pri.c.
References AST_PARTY_CHAR_SET_ISO10646_BMPSTRING, AST_PARTY_CHAR_SET_ISO10646_UTF_8STRING, AST_PARTY_CHAR_SET_ISO8859_1, AST_PARTY_CHAR_SET_ISO8859_2, AST_PARTY_CHAR_SET_ISO8859_3, AST_PARTY_CHAR_SET_ISO8859_4, AST_PARTY_CHAR_SET_ISO8859_5, AST_PARTY_CHAR_SET_ISO8859_7, AST_PARTY_CHAR_SET_UNKNOWN, and AST_PARTY_CHAR_SET_WITHDRAWN.
Referenced by sig_pri_party_name_convert().
00548 { 00549 enum AST_PARTY_CHAR_SET ast_char_set; 00550 00551 switch (pri_char_set) { 00552 default: 00553 case PRI_CHAR_SET_UNKNOWN: 00554 ast_char_set = AST_PARTY_CHAR_SET_UNKNOWN; 00555 break; 00556 case PRI_CHAR_SET_ISO8859_1: 00557 ast_char_set = AST_PARTY_CHAR_SET_ISO8859_1; 00558 break; 00559 case PRI_CHAR_SET_WITHDRAWN: 00560 ast_char_set = AST_PARTY_CHAR_SET_WITHDRAWN; 00561 break; 00562 case PRI_CHAR_SET_ISO8859_2: 00563 ast_char_set = AST_PARTY_CHAR_SET_ISO8859_2; 00564 break; 00565 case PRI_CHAR_SET_ISO8859_3: 00566 ast_char_set = AST_PARTY_CHAR_SET_ISO8859_3; 00567 break; 00568 case PRI_CHAR_SET_ISO8859_4: 00569 ast_char_set = AST_PARTY_CHAR_SET_ISO8859_4; 00570 break; 00571 case PRI_CHAR_SET_ISO8859_5: 00572 ast_char_set = AST_PARTY_CHAR_SET_ISO8859_5; 00573 break; 00574 case PRI_CHAR_SET_ISO8859_7: 00575 ast_char_set = AST_PARTY_CHAR_SET_ISO8859_7; 00576 break; 00577 case PRI_CHAR_SET_ISO10646_BMPSTRING: 00578 ast_char_set = AST_PARTY_CHAR_SET_ISO10646_BMPSTRING; 00579 break; 00580 case PRI_CHAR_SET_ISO10646_UTF_8STRING: 00581 ast_char_set = AST_PARTY_CHAR_SET_ISO10646_UTF_8STRING; 00582 break; 00583 } 00584 00585 return ast_char_set; 00586 }
static int pri_to_ast_presentation | ( | int | pri_presentation | ) | [static] |
Definition at line 437 of file sig_pri.c.
References AST_PRES_ALLOWED, AST_PRES_NETWORK_NUMBER, AST_PRES_NUMBER_NOT_AVAILABLE, AST_PRES_RESTRICTED, AST_PRES_USER_NUMBER_FAILED_SCREEN, AST_PRES_USER_NUMBER_PASSED_SCREEN, and AST_PRES_USER_NUMBER_UNSCREENED.
Referenced by sig_pri_party_name_convert(), and sig_pri_party_number_convert().
00438 { 00439 int ast_presentation; 00440 00441 switch (pri_presentation) { 00442 case PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_UNSCREENED: 00443 ast_presentation = AST_PRES_ALLOWED | AST_PRES_USER_NUMBER_UNSCREENED; 00444 break; 00445 case PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_PASSED_SCREEN: 00446 ast_presentation = AST_PRES_ALLOWED | AST_PRES_USER_NUMBER_PASSED_SCREEN; 00447 break; 00448 case PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_FAILED_SCREEN: 00449 ast_presentation = AST_PRES_ALLOWED | AST_PRES_USER_NUMBER_FAILED_SCREEN; 00450 break; 00451 case PRI_PRES_ALLOWED | PRI_PRES_NETWORK_NUMBER: 00452 ast_presentation = AST_PRES_ALLOWED | AST_PRES_NETWORK_NUMBER; 00453 break; 00454 00455 case PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_UNSCREENED: 00456 ast_presentation = AST_PRES_RESTRICTED | AST_PRES_USER_NUMBER_UNSCREENED; 00457 break; 00458 case PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_PASSED_SCREEN: 00459 ast_presentation = AST_PRES_RESTRICTED | AST_PRES_USER_NUMBER_PASSED_SCREEN; 00460 break; 00461 case PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_FAILED_SCREEN: 00462 ast_presentation = AST_PRES_RESTRICTED | AST_PRES_USER_NUMBER_FAILED_SCREEN; 00463 break; 00464 case PRI_PRES_RESTRICTED | PRI_PRES_NETWORK_NUMBER: 00465 ast_presentation = AST_PRES_RESTRICTED | AST_PRES_NETWORK_NUMBER; 00466 break; 00467 00468 case PRI_PRES_UNAVAILABLE | PRI_PRES_USER_NUMBER_UNSCREENED: 00469 case PRI_PRES_UNAVAILABLE | PRI_PRES_USER_NUMBER_PASSED_SCREEN: 00470 case PRI_PRES_UNAVAILABLE | PRI_PRES_USER_NUMBER_FAILED_SCREEN: 00471 case PRI_PRES_UNAVAILABLE | PRI_PRES_NETWORK_NUMBER: 00472 ast_presentation = AST_PRES_NUMBER_NOT_AVAILABLE; 00473 break; 00474 00475 default: 00476 ast_presentation = AST_PRES_RESTRICTED | AST_PRES_USER_NUMBER_UNSCREENED; 00477 break; 00478 } 00479 00480 return ast_presentation; 00481 }
static enum AST_REDIRECTING_REASON pri_to_ast_reason | ( | int | pri_reason | ) | [static] |
Definition at line 367 of file sig_pri.c.
References AST_REDIRECTING_REASON_DEFLECTION, AST_REDIRECTING_REASON_NO_ANSWER, AST_REDIRECTING_REASON_UNCONDITIONAL, AST_REDIRECTING_REASON_UNKNOWN, and AST_REDIRECTING_REASON_USER_BUSY.
Referenced by sig_pri_redirecting_convert().
00368 { 00369 enum AST_REDIRECTING_REASON ast_reason; 00370 00371 switch (pri_reason) { 00372 case PRI_REDIR_FORWARD_ON_BUSY: 00373 ast_reason = AST_REDIRECTING_REASON_USER_BUSY; 00374 break; 00375 case PRI_REDIR_FORWARD_ON_NO_REPLY: 00376 ast_reason = AST_REDIRECTING_REASON_NO_ANSWER; 00377 break; 00378 case PRI_REDIR_DEFLECTION: 00379 ast_reason = AST_REDIRECTING_REASON_DEFLECTION; 00380 break; 00381 case PRI_REDIR_UNCONDITIONAL: 00382 ast_reason = AST_REDIRECTING_REASON_UNCONDITIONAL; 00383 break; 00384 case PRI_REDIR_UNKNOWN: 00385 default: 00386 ast_reason = AST_REDIRECTING_REASON_UNKNOWN; 00387 break; 00388 } 00389 00390 return ast_reason; 00391 }
static unsigned int PVT_TO_CHANNEL | ( | struct sig_pri_chan * | p | ) | [static] |
Definition at line 149 of file sig_pri.c.
References ast_debug, sig_pri_chan::logicalspan, sig_pri_chan::mastertrunkgroup, PRI_EXPLICIT, and sig_pri_chan::prioffset.
Referenced by pri_check_restart(), pri_maintenance_bservice(), pri_ss_thread(), sig_pri_call(), sig_pri_handle_retrieve(), and sig_pri_indicate().
00150 { 00151 int res = (((p)->prioffset) | ((p)->logicalspan << 8) | (p->mastertrunkgroup ? PRI_EXPLICIT : 0)); 00152 ast_debug(5, "prioffset: %d mastertrunkgroup: %d logicalspan: %d result: %d\n", 00153 p->prioffset, p->mastertrunkgroup, p->logicalspan, res); 00154 00155 return res; 00156 }
static char* redirectingreason2str | ( | int | redirectingreason | ) | [static] |
Definition at line 1591 of file sig_pri.c.
01592 { 01593 switch (redirectingreason) { 01594 case 0: 01595 return "UNKNOWN"; 01596 case 1: 01597 return "BUSY"; 01598 case 2: 01599 return "NO_REPLY"; 01600 case 0xF: 01601 return "UNCONDITIONAL"; 01602 default: 01603 return "NOREDIRECT"; 01604 } 01605 }
static void sig_pri_ami_channel_event | ( | struct sig_pri_chan * | p | ) | [static] |
Definition at line 1005 of file sig_pri.c.
References sig_pri_callback::ami_channel_event, sig_pri_chan::calls, sig_pri_chan::chan_pvt, and sig_pri_chan::owner.
Referenced by pri_fixup_principle().
01006 { 01007 if (p->calls->ami_channel_event) { 01008 p->calls->ami_channel_event(p->chan_pvt, p->owner); 01009 } 01010 }
int sig_pri_answer | ( | struct sig_pri_chan * | p, | |
struct ast_channel * | ast | |||
) |
Definition at line 7239 of file sig_pri.c.
References sig_pri_chan::aoc_s_request_invoke_id, sig_pri_chan::aoc_s_request_invoke_id_valid, ast_setstate(), AST_STATE_UP, sig_pri_chan::call, sig_pri_chan::call_level, sig_pri_chan::digital, sig_pri_chan::pri, sig_pri_span::pri, pri_grab(), pri_rel(), SIG_PRI_CALL_LEVEL_CONNECT, sig_pri_open_media(), and sig_pri_set_dialing().
Referenced by dahdi_answer().
07240 { 07241 int res; 07242 07243 /* Send a pri acknowledge */ 07244 pri_grab(p, p->pri); 07245 #if defined(HAVE_PRI_AOC_EVENTS) 07246 if (p->aoc_s_request_invoke_id_valid) { 07247 /* if AOC-S was requested and the invoke id is still present on answer. That means 07248 * no AOC-S rate list was provided, so send a NULL response which will indicate that 07249 * AOC-S is not available */ 07250 pri_aoc_s_request_response_send(p->pri->pri, p->call, 07251 p->aoc_s_request_invoke_id, NULL); 07252 p->aoc_s_request_invoke_id_valid = 0; 07253 } 07254 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 07255 if (p->call_level < SIG_PRI_CALL_LEVEL_CONNECT) { 07256 p->call_level = SIG_PRI_CALL_LEVEL_CONNECT; 07257 } 07258 sig_pri_set_dialing(p, 0); 07259 sig_pri_open_media(p); 07260 res = pri_answer(p->pri->pri, p->call, 0, !p->digital); 07261 pri_rel(p->pri); 07262 ast_setstate(ast, AST_STATE_UP); 07263 return res; 07264 }
static enum ast_aoc_s_charged_item sig_pri_aoc_charged_item_to_ast | ( | enum PRI_AOC_CHARGED_ITEM | value | ) | [static] |
Definition at line 2905 of file sig_pri.c.
References AST_AOC_CHARGED_ITEM_BASIC_COMMUNICATION, AST_AOC_CHARGED_ITEM_CALL_ATTEMPT, AST_AOC_CHARGED_ITEM_CALL_SETUP, AST_AOC_CHARGED_ITEM_NA, AST_AOC_CHARGED_ITEM_SPECIAL_ARRANGEMENT, AST_AOC_CHARGED_ITEM_SUPPLEMENTARY_SERVICE, and AST_AOC_CHARGED_ITEM_USER_USER_INFO.
Referenced by sig_pri_aoc_s_from_pri().
02906 { 02907 switch (value) { 02908 case PRI_AOC_CHARGED_ITEM_NOT_AVAILABLE: 02909 return AST_AOC_CHARGED_ITEM_NA; 02910 case PRI_AOC_CHARGED_ITEM_SPECIAL_ARRANGEMENT: 02911 return AST_AOC_CHARGED_ITEM_SPECIAL_ARRANGEMENT; 02912 case PRI_AOC_CHARGED_ITEM_BASIC_COMMUNICATION: 02913 return AST_AOC_CHARGED_ITEM_BASIC_COMMUNICATION; 02914 case PRI_AOC_CHARGED_ITEM_CALL_ATTEMPT: 02915 return AST_AOC_CHARGED_ITEM_CALL_ATTEMPT; 02916 case PRI_AOC_CHARGED_ITEM_CALL_SETUP: 02917 return AST_AOC_CHARGED_ITEM_CALL_SETUP; 02918 case PRI_AOC_CHARGED_ITEM_USER_USER_INFO: 02919 return AST_AOC_CHARGED_ITEM_USER_USER_INFO; 02920 case PRI_AOC_CHARGED_ITEM_SUPPLEMENTARY_SERVICE: 02921 return AST_AOC_CHARGED_ITEM_SUPPLEMENTARY_SERVICE; 02922 } 02923 return AST_AOC_CHARGED_ITEM_NA; 02924 }
static enum PRI_AOC_CHARGED_ITEM sig_pri_aoc_charged_item_to_pri | ( | enum PRI_AOC_CHARGED_ITEM | value | ) | [static] |
Definition at line 2873 of file sig_pri.c.
References AST_AOC_CHARGED_ITEM_BASIC_COMMUNICATION, AST_AOC_CHARGED_ITEM_CALL_ATTEMPT, AST_AOC_CHARGED_ITEM_CALL_SETUP, AST_AOC_CHARGED_ITEM_NA, AST_AOC_CHARGED_ITEM_SPECIAL_ARRANGEMENT, AST_AOC_CHARGED_ITEM_SUPPLEMENTARY_SERVICE, and AST_AOC_CHARGED_ITEM_USER_USER_INFO.
Referenced by sig_pri_aoc_s_from_ast().
02874 { 02875 switch (value) { 02876 case AST_AOC_CHARGED_ITEM_NA: 02877 return PRI_AOC_CHARGED_ITEM_NOT_AVAILABLE; 02878 case AST_AOC_CHARGED_ITEM_SPECIAL_ARRANGEMENT: 02879 return PRI_AOC_CHARGED_ITEM_SPECIAL_ARRANGEMENT; 02880 case AST_AOC_CHARGED_ITEM_BASIC_COMMUNICATION: 02881 return PRI_AOC_CHARGED_ITEM_BASIC_COMMUNICATION; 02882 case AST_AOC_CHARGED_ITEM_CALL_ATTEMPT: 02883 return PRI_AOC_CHARGED_ITEM_CALL_ATTEMPT; 02884 case AST_AOC_CHARGED_ITEM_CALL_SETUP: 02885 return PRI_AOC_CHARGED_ITEM_CALL_SETUP; 02886 case AST_AOC_CHARGED_ITEM_USER_USER_INFO: 02887 return PRI_AOC_CHARGED_ITEM_USER_USER_INFO; 02888 case AST_AOC_CHARGED_ITEM_SUPPLEMENTARY_SERVICE: 02889 return PRI_AOC_CHARGED_ITEM_SUPPLEMENTARY_SERVICE; 02890 } 02891 return PRI_AOC_CHARGED_ITEM_NOT_AVAILABLE; 02892 }
static void sig_pri_aoc_d_from_ast | ( | struct sig_pri_chan * | pvt, | |
struct ast_aoc_decoded * | decoded | |||
) | [static] |
Definition at line 3561 of file sig_pri.c.
References ast_aoc_unit_entry::amount, ARRAY_LEN, AST_AOC_BILLING_CREDIT_CARD, AST_AOC_BILLING_NA, AST_AOC_BILLING_NORMAL, AST_AOC_BILLING_REVERSE_CHARGE, AST_AOC_CHARGE_CURRENCY, AST_AOC_CHARGE_FREE, AST_AOC_CHARGE_NA, AST_AOC_CHARGE_UNIT, ast_aoc_get_billing_id(), ast_aoc_get_charge_type(), ast_aoc_get_currency_amount(), ast_aoc_get_currency_multiplier(), ast_aoc_get_currency_name(), ast_aoc_get_total_type(), ast_aoc_get_unit_count(), ast_aoc_get_unit_info(), AST_AOC_TOTAL, ast_copy_string(), ast_strlen_zero(), sig_pri_chan::call, sig_pri_span::pri, sig_pri_chan::pri, sig_pri_aoc_multiplier_from_ast(), ast_aoc_unit_entry::type, ast_aoc_unit_entry::valid_amount, and ast_aoc_unit_entry::valid_type.
Referenced by sig_pri_indicate().
03562 { 03563 struct pri_subcmd_aoc_d aoc_d = { 0, }; 03564 03565 aoc_d.billing_accumulation = (ast_aoc_get_total_type(decoded) == AST_AOC_TOTAL) ? 1 : 0; 03566 03567 switch (ast_aoc_get_billing_id(decoded)) { 03568 case AST_AOC_BILLING_NORMAL: 03569 aoc_d.billing_id = PRI_AOC_D_BILLING_ID_NORMAL; 03570 break; 03571 case AST_AOC_BILLING_REVERSE_CHARGE: 03572 aoc_d.billing_id = PRI_AOC_D_BILLING_ID_REVERSE; 03573 break; 03574 case AST_AOC_BILLING_CREDIT_CARD: 03575 aoc_d.billing_id = PRI_AOC_D_BILLING_ID_CREDIT_CARD; 03576 break; 03577 case AST_AOC_BILLING_NA: 03578 default: 03579 aoc_d.billing_id = PRI_AOC_D_BILLING_ID_NOT_AVAILABLE; 03580 break; 03581 } 03582 03583 switch (ast_aoc_get_charge_type(decoded)) { 03584 case AST_AOC_CHARGE_FREE: 03585 aoc_d.charge = PRI_AOC_DE_CHARGE_FREE; 03586 break; 03587 case AST_AOC_CHARGE_CURRENCY: 03588 { 03589 const char *currency_name = ast_aoc_get_currency_name(decoded); 03590 aoc_d.charge = PRI_AOC_DE_CHARGE_CURRENCY; 03591 aoc_d.recorded.money.amount.cost = ast_aoc_get_currency_amount(decoded); 03592 aoc_d.recorded.money.amount.multiplier = sig_pri_aoc_multiplier_from_ast(ast_aoc_get_currency_multiplier(decoded)); 03593 if (!ast_strlen_zero(currency_name)) { 03594 ast_copy_string(aoc_d.recorded.money.currency, currency_name, sizeof(aoc_d.recorded.money.currency)); 03595 } 03596 } 03597 break; 03598 case AST_AOC_CHARGE_UNIT: 03599 { 03600 const struct ast_aoc_unit_entry *entry; 03601 int i; 03602 aoc_d.charge = PRI_AOC_DE_CHARGE_UNITS; 03603 for (i = 0; i < ast_aoc_get_unit_count(decoded); i++) { 03604 if ((entry = ast_aoc_get_unit_info(decoded, i)) && i < ARRAY_LEN(aoc_d.recorded.unit.item)) { 03605 if (entry->valid_amount) { 03606 aoc_d.recorded.unit.item[i].number = entry->amount; 03607 } else { 03608 aoc_d.recorded.unit.item[i].number = -1; 03609 } 03610 if (entry->valid_type) { 03611 aoc_d.recorded.unit.item[i].type = entry->type; 03612 } else { 03613 aoc_d.recorded.unit.item[i].type = -1; 03614 } 03615 aoc_d.recorded.unit.num_items++; 03616 } else { 03617 break; 03618 } 03619 } 03620 } 03621 break; 03622 case AST_AOC_CHARGE_NA: 03623 default: 03624 aoc_d.charge = PRI_AOC_DE_CHARGE_NOT_AVAILABLE; 03625 break; 03626 } 03627 03628 pri_aoc_d_send(pvt->pri->pri, pvt->call, &aoc_d); 03629 }
static void sig_pri_aoc_d_from_pri | ( | const struct pri_subcmd_aoc_d * | aoc_d, | |
struct ast_channel * | owner, | |||
int | passthrough | |||
) | [static] |
Definition at line 3234 of file sig_pri.c.
References ast_aoc_add_unit_entry(), AST_AOC_BILLING_CREDIT_CARD, AST_AOC_BILLING_NA, AST_AOC_BILLING_NORMAL, AST_AOC_BILLING_REVERSE_CHARGE, AST_AOC_CHARGE_CURRENCY, AST_AOC_CHARGE_FREE, AST_AOC_CHARGE_NA, AST_AOC_CHARGE_UNIT, ast_aoc_create(), AST_AOC_D, ast_aoc_destroy_decoded(), ast_aoc_destroy_encoded(), ast_aoc_encode(), ast_aoc_manager_event(), ast_aoc_set_billing_id(), ast_aoc_set_currency_info(), ast_aoc_set_total_type(), AST_AOC_SUBTOTAL, AST_AOC_TOTAL, AST_CONTROL_AOC, ast_debug, ast_queue_control_data(), sig_pri_aoc_multiplier_from_pri(), and type.
Referenced by sig_pri_handle_subcmds().
03235 { 03236 struct ast_aoc_decoded *decoded = NULL; 03237 struct ast_aoc_encoded *encoded = NULL; 03238 size_t encoded_size = 0; 03239 enum ast_aoc_charge_type type; 03240 03241 if (!owner || !aoc_d) { 03242 return; 03243 } 03244 03245 switch (aoc_d->charge) { 03246 case PRI_AOC_DE_CHARGE_CURRENCY: 03247 type = AST_AOC_CHARGE_CURRENCY; 03248 break; 03249 case PRI_AOC_DE_CHARGE_UNITS: 03250 type = AST_AOC_CHARGE_UNIT; 03251 break; 03252 case PRI_AOC_DE_CHARGE_FREE: 03253 type = AST_AOC_CHARGE_FREE; 03254 break; 03255 default: 03256 type = AST_AOC_CHARGE_NA; 03257 break; 03258 } 03259 03260 if (!(decoded = ast_aoc_create(AST_AOC_D, type, 0))) { 03261 return; 03262 } 03263 03264 switch (aoc_d->billing_accumulation) { 03265 default: 03266 ast_debug(1, "AOC-D billing accumulation has unknown value: %d\n", 03267 aoc_d->billing_accumulation); 03268 /* Fall through */ 03269 case 0:/* subTotal */ 03270 ast_aoc_set_total_type(decoded, AST_AOC_SUBTOTAL); 03271 break; 03272 case 1:/* total */ 03273 ast_aoc_set_total_type(decoded, AST_AOC_TOTAL); 03274 break; 03275 } 03276 03277 switch (aoc_d->billing_id) { 03278 case PRI_AOC_D_BILLING_ID_NORMAL: 03279 ast_aoc_set_billing_id(decoded, AST_AOC_BILLING_NORMAL); 03280 break; 03281 case PRI_AOC_D_BILLING_ID_REVERSE: 03282 ast_aoc_set_billing_id(decoded, AST_AOC_BILLING_REVERSE_CHARGE); 03283 break; 03284 case PRI_AOC_D_BILLING_ID_CREDIT_CARD: 03285 ast_aoc_set_billing_id(decoded, AST_AOC_BILLING_CREDIT_CARD); 03286 break; 03287 case PRI_AOC_D_BILLING_ID_NOT_AVAILABLE: 03288 default: 03289 ast_aoc_set_billing_id(decoded, AST_AOC_BILLING_NA); 03290 break; 03291 } 03292 03293 switch (aoc_d->charge) { 03294 case PRI_AOC_DE_CHARGE_CURRENCY: 03295 ast_aoc_set_currency_info(decoded, 03296 aoc_d->recorded.money.amount.cost, 03297 sig_pri_aoc_multiplier_from_pri(aoc_d->recorded.money.amount.multiplier), 03298 aoc_d->recorded.money.currency); 03299 break; 03300 case PRI_AOC_DE_CHARGE_UNITS: 03301 { 03302 int i; 03303 for (i = 0; i < aoc_d->recorded.unit.num_items; ++i) { 03304 /* if type or number are negative, then they are not present */ 03305 ast_aoc_add_unit_entry(decoded, 03306 (aoc_d->recorded.unit.item[i].number >= 0 ? 1 : 0), 03307 aoc_d->recorded.unit.item[i].number, 03308 (aoc_d->recorded.unit.item[i].type >= 0 ? 1 : 0), 03309 aoc_d->recorded.unit.item[i].type); 03310 } 03311 } 03312 break; 03313 } 03314 03315 if (passthrough && (encoded = ast_aoc_encode(decoded, &encoded_size, owner))) { 03316 ast_queue_control_data(owner, AST_CONTROL_AOC, encoded, encoded_size); 03317 } 03318 03319 ast_aoc_manager_event(decoded, owner); 03320 03321 ast_aoc_destroy_decoded(decoded); 03322 ast_aoc_destroy_encoded(encoded); 03323 }
static void sig_pri_aoc_e_from_ast | ( | struct sig_pri_chan * | pvt, | |
struct ast_aoc_decoded * | decoded | |||
) | [static] |
Definition at line 3644 of file sig_pri.c.
References ast_aoc_unit_entry::amount, sig_pri_chan::aoc_e, ARRAY_LEN, AST_AOC_BILLING_CALL_DEFLECTION, AST_AOC_BILLING_CALL_FWD_BUSY, AST_AOC_BILLING_CALL_FWD_NO_REPLY, AST_AOC_BILLING_CALL_FWD_UNCONDITIONAL, AST_AOC_BILLING_CALL_TRANSFER, AST_AOC_BILLING_CREDIT_CARD, AST_AOC_BILLING_NA, AST_AOC_BILLING_NORMAL, AST_AOC_BILLING_REVERSE_CHARGE, AST_AOC_CHARGE_CURRENCY, AST_AOC_CHARGE_FREE, AST_AOC_CHARGE_NA, AST_AOC_CHARGE_UNIT, AST_AOC_CHARGING_ASSOCIATION_ID, AST_AOC_CHARGING_ASSOCIATION_NA, AST_AOC_CHARGING_ASSOCIATION_NUMBER, ast_aoc_get_association_info(), ast_aoc_get_billing_id(), ast_aoc_get_charge_type(), ast_aoc_get_currency_amount(), ast_aoc_get_currency_multiplier(), ast_aoc_get_currency_name(), ast_aoc_get_unit_count(), ast_aoc_get_unit_info(), ast_copy_string(), ast_strlen_zero(), ast_aoc_charging_association::charge, ast_aoc_charging_association::charging_type, sig_pri_chan::holding_aoce, ast_aoc_charging_association::id, ast_aoc_charging_association_number::number, ast_aoc_charging_association::number, ast_aoc_charging_association_number::plan, sig_pri_aoc_multiplier_from_ast(), ast_aoc_unit_entry::type, ast_aoc_unit_entry::valid_amount, and ast_aoc_unit_entry::valid_type.
Referenced by sig_pri_indicate().
03645 { 03646 struct pri_subcmd_aoc_e *aoc_e = &pvt->aoc_e; 03647 const struct ast_aoc_charging_association *ca = ast_aoc_get_association_info(decoded); 03648 03649 memset(aoc_e, 0, sizeof(*aoc_e)); 03650 pvt->holding_aoce = 1; 03651 03652 switch (ca->charging_type) { 03653 case AST_AOC_CHARGING_ASSOCIATION_NUMBER: 03654 aoc_e->associated.charge.number.valid = 1; 03655 ast_copy_string(aoc_e->associated.charge.number.str, 03656 ca->charge.number.number, 03657 sizeof(aoc_e->associated.charge.number.str)); 03658 aoc_e->associated.charge.number.plan = ca->charge.number.plan; 03659 aoc_e->associated.charging_type = PRI_AOC_E_CHARGING_ASSOCIATION_NUMBER; 03660 break; 03661 case AST_AOC_CHARGING_ASSOCIATION_ID: 03662 aoc_e->associated.charge.id = ca->charge.id; 03663 aoc_e->associated.charging_type = PRI_AOC_E_CHARGING_ASSOCIATION_ID; 03664 break; 03665 case AST_AOC_CHARGING_ASSOCIATION_NA: 03666 default: 03667 break; 03668 } 03669 03670 switch (ast_aoc_get_billing_id(decoded)) { 03671 case AST_AOC_BILLING_NORMAL: 03672 aoc_e->billing_id = PRI_AOC_E_BILLING_ID_NORMAL; 03673 break; 03674 case AST_AOC_BILLING_REVERSE_CHARGE: 03675 aoc_e->billing_id = PRI_AOC_E_BILLING_ID_REVERSE; 03676 break; 03677 case AST_AOC_BILLING_CREDIT_CARD: 03678 aoc_e->billing_id = PRI_AOC_E_BILLING_ID_CREDIT_CARD; 03679 break; 03680 case AST_AOC_BILLING_CALL_FWD_UNCONDITIONAL: 03681 aoc_e->billing_id = PRI_AOC_E_BILLING_ID_CALL_FORWARDING_UNCONDITIONAL; 03682 break; 03683 case AST_AOC_BILLING_CALL_FWD_BUSY: 03684 aoc_e->billing_id = PRI_AOC_E_BILLING_ID_CALL_FORWARDING_BUSY; 03685 break; 03686 case AST_AOC_BILLING_CALL_FWD_NO_REPLY: 03687 aoc_e->billing_id = PRI_AOC_E_BILLING_ID_CALL_FORWARDING_NO_REPLY; 03688 break; 03689 case AST_AOC_BILLING_CALL_DEFLECTION: 03690 aoc_e->billing_id = PRI_AOC_E_BILLING_ID_CALL_DEFLECTION; 03691 break; 03692 case AST_AOC_BILLING_CALL_TRANSFER: 03693 aoc_e->billing_id = PRI_AOC_E_BILLING_ID_CALL_TRANSFER; 03694 break; 03695 case AST_AOC_BILLING_NA: 03696 default: 03697 aoc_e->billing_id = PRI_AOC_E_BILLING_ID_NOT_AVAILABLE; 03698 break; 03699 } 03700 03701 switch (ast_aoc_get_charge_type(decoded)) { 03702 case AST_AOC_CHARGE_FREE: 03703 aoc_e->charge = PRI_AOC_DE_CHARGE_FREE; 03704 break; 03705 case AST_AOC_CHARGE_CURRENCY: 03706 { 03707 const char *currency_name = ast_aoc_get_currency_name(decoded); 03708 aoc_e->charge = PRI_AOC_DE_CHARGE_CURRENCY; 03709 aoc_e->recorded.money.amount.cost = ast_aoc_get_currency_amount(decoded); 03710 aoc_e->recorded.money.amount.multiplier = sig_pri_aoc_multiplier_from_ast(ast_aoc_get_currency_multiplier(decoded)); 03711 if (!ast_strlen_zero(currency_name)) { 03712 ast_copy_string(aoc_e->recorded.money.currency, currency_name, sizeof(aoc_e->recorded.money.currency)); 03713 } 03714 } 03715 break; 03716 case AST_AOC_CHARGE_UNIT: 03717 { 03718 const struct ast_aoc_unit_entry *entry; 03719 int i; 03720 aoc_e->charge = PRI_AOC_DE_CHARGE_UNITS; 03721 for (i = 0; i < ast_aoc_get_unit_count(decoded); i++) { 03722 if ((entry = ast_aoc_get_unit_info(decoded, i)) && i < ARRAY_LEN(aoc_e->recorded.unit.item)) { 03723 if (entry->valid_amount) { 03724 aoc_e->recorded.unit.item[i].number = entry->amount; 03725 } else { 03726 aoc_e->recorded.unit.item[i].number = -1; 03727 } 03728 if (entry->valid_type) { 03729 aoc_e->recorded.unit.item[i].type = entry->type; 03730 } else { 03731 aoc_e->recorded.unit.item[i].type = -1; 03732 } 03733 aoc_e->recorded.unit.num_items++; 03734 } 03735 } 03736 } 03737 break; 03738 case AST_AOC_CHARGE_NA: 03739 default: 03740 aoc_e->charge = PRI_AOC_DE_CHARGE_NOT_AVAILABLE; 03741 break; 03742 } 03743 }
static void sig_pri_aoc_e_from_pri | ( | const struct pri_subcmd_aoc_e * | aoc_e, | |
struct ast_channel * | owner, | |||
int | passthrough | |||
) | [static] |
Definition at line 3343 of file sig_pri.c.
References ast_aoc_add_unit_entry(), AST_AOC_BILLING_CALL_DEFLECTION, AST_AOC_BILLING_CALL_FWD_BUSY, AST_AOC_BILLING_CALL_FWD_NO_REPLY, AST_AOC_BILLING_CALL_FWD_UNCONDITIONAL, AST_AOC_BILLING_CALL_TRANSFER, AST_AOC_BILLING_CREDIT_CARD, AST_AOC_BILLING_NA, AST_AOC_BILLING_NORMAL, AST_AOC_BILLING_REVERSE_CHARGE, AST_AOC_CHARGE_CURRENCY, AST_AOC_CHARGE_FREE, AST_AOC_CHARGE_NA, AST_AOC_CHARGE_UNIT, ast_aoc_create(), ast_aoc_destroy_decoded(), ast_aoc_destroy_encoded(), AST_AOC_E, ast_aoc_encode(), ast_aoc_manager_event(), ast_aoc_set_association_id(), ast_aoc_set_association_number(), ast_aoc_set_billing_id(), ast_aoc_set_currency_info(), AST_CONTROL_AOC, ast_queue_control_data(), sig_pri_aoc_multiplier_from_pri(), and type.
Referenced by sig_pri_handle_cis_subcmds(), and sig_pri_handle_subcmds().
03344 { 03345 struct ast_aoc_decoded *decoded = NULL; 03346 struct ast_aoc_encoded *encoded = NULL; 03347 size_t encoded_size = 0; 03348 enum ast_aoc_charge_type type; 03349 03350 if (!aoc_e) { 03351 return; 03352 } 03353 03354 switch (aoc_e->charge) { 03355 case PRI_AOC_DE_CHARGE_CURRENCY: 03356 type = AST_AOC_CHARGE_CURRENCY; 03357 break; 03358 case PRI_AOC_DE_CHARGE_UNITS: 03359 type = AST_AOC_CHARGE_UNIT; 03360 break; 03361 case PRI_AOC_DE_CHARGE_FREE: 03362 type = AST_AOC_CHARGE_FREE; 03363 break; 03364 default: 03365 type = AST_AOC_CHARGE_NA; 03366 break; 03367 } 03368 03369 if (!(decoded = ast_aoc_create(AST_AOC_E, type, 0))) { 03370 return; 03371 } 03372 03373 switch (aoc_e->associated.charging_type) { 03374 case PRI_AOC_E_CHARGING_ASSOCIATION_NUMBER: 03375 if (!aoc_e->associated.charge.number.valid) { 03376 break; 03377 } 03378 ast_aoc_set_association_number(decoded, aoc_e->associated.charge.number.str, aoc_e->associated.charge.number.plan); 03379 break; 03380 case PRI_AOC_E_CHARGING_ASSOCIATION_ID: 03381 ast_aoc_set_association_id(decoded, aoc_e->associated.charge.id); 03382 break; 03383 default: 03384 break; 03385 } 03386 03387 switch (aoc_e->billing_id) { 03388 case PRI_AOC_E_BILLING_ID_NORMAL: 03389 ast_aoc_set_billing_id(decoded, AST_AOC_BILLING_NORMAL); 03390 break; 03391 case PRI_AOC_E_BILLING_ID_REVERSE: 03392 ast_aoc_set_billing_id(decoded, AST_AOC_BILLING_REVERSE_CHARGE); 03393 break; 03394 case PRI_AOC_E_BILLING_ID_CREDIT_CARD: 03395 ast_aoc_set_billing_id(decoded, AST_AOC_BILLING_CREDIT_CARD); 03396 break; 03397 case PRI_AOC_E_BILLING_ID_CALL_FORWARDING_UNCONDITIONAL: 03398 ast_aoc_set_billing_id(decoded, AST_AOC_BILLING_CALL_FWD_UNCONDITIONAL); 03399 break; 03400 case PRI_AOC_E_BILLING_ID_CALL_FORWARDING_BUSY: 03401 ast_aoc_set_billing_id(decoded, AST_AOC_BILLING_CALL_FWD_BUSY); 03402 break; 03403 case PRI_AOC_E_BILLING_ID_CALL_FORWARDING_NO_REPLY: 03404 ast_aoc_set_billing_id(decoded, AST_AOC_BILLING_CALL_FWD_NO_REPLY); 03405 break; 03406 case PRI_AOC_E_BILLING_ID_CALL_DEFLECTION: 03407 ast_aoc_set_billing_id(decoded, AST_AOC_BILLING_CALL_DEFLECTION); 03408 break; 03409 case PRI_AOC_E_BILLING_ID_CALL_TRANSFER: 03410 ast_aoc_set_billing_id(decoded, AST_AOC_BILLING_CALL_TRANSFER); 03411 break; 03412 case PRI_AOC_E_BILLING_ID_NOT_AVAILABLE: 03413 default: 03414 ast_aoc_set_billing_id(decoded, AST_AOC_BILLING_NA); 03415 break; 03416 } 03417 03418 switch (aoc_e->charge) { 03419 case PRI_AOC_DE_CHARGE_CURRENCY: 03420 ast_aoc_set_currency_info(decoded, 03421 aoc_e->recorded.money.amount.cost, 03422 sig_pri_aoc_multiplier_from_pri(aoc_e->recorded.money.amount.multiplier), 03423 aoc_e->recorded.money.currency); 03424 break; 03425 case PRI_AOC_DE_CHARGE_UNITS: 03426 { 03427 int i; 03428 for (i = 0; i < aoc_e->recorded.unit.num_items; ++i) { 03429 /* if type or number are negative, then they are not present */ 03430 ast_aoc_add_unit_entry(decoded, 03431 (aoc_e->recorded.unit.item[i].number >= 0 ? 1 : 0), 03432 aoc_e->recorded.unit.item[i].number, 03433 (aoc_e->recorded.unit.item[i].type >= 0 ? 1 : 0), 03434 aoc_e->recorded.unit.item[i].type); 03435 } 03436 } 03437 } 03438 03439 if (passthrough && owner && (encoded = ast_aoc_encode(decoded, &encoded_size, owner))) { 03440 ast_queue_control_data(owner, AST_CONTROL_AOC, encoded, encoded_size); 03441 } 03442 03443 ast_aoc_manager_event(decoded, owner); 03444 03445 ast_aoc_destroy_decoded(decoded); 03446 ast_aoc_destroy_encoded(encoded); 03447 }
static int sig_pri_aoc_multiplier_from_ast | ( | enum ast_aoc_currency_multiplier | mult | ) | [static] |
Definition at line 2935 of file sig_pri.c.
References AST_AOC_MULT_HUNDRED, AST_AOC_MULT_ONE, AST_AOC_MULT_ONEHUNDREDTH, AST_AOC_MULT_ONETENTH, AST_AOC_MULT_ONETHOUSANDTH, AST_AOC_MULT_TEN, and AST_AOC_MULT_THOUSAND.
Referenced by sig_pri_aoc_d_from_ast(), sig_pri_aoc_e_from_ast(), and sig_pri_aoc_s_from_ast().
02936 { 02937 switch (mult) { 02938 case AST_AOC_MULT_ONETHOUSANDTH: 02939 return PRI_AOC_MULTIPLIER_THOUSANDTH; 02940 case AST_AOC_MULT_ONEHUNDREDTH: 02941 return PRI_AOC_MULTIPLIER_HUNDREDTH; 02942 case AST_AOC_MULT_ONETENTH: 02943 return PRI_AOC_MULTIPLIER_TENTH; 02944 case AST_AOC_MULT_ONE: 02945 return PRI_AOC_MULTIPLIER_ONE; 02946 case AST_AOC_MULT_TEN: 02947 return PRI_AOC_MULTIPLIER_TEN; 02948 case AST_AOC_MULT_HUNDRED: 02949 return PRI_AOC_MULTIPLIER_HUNDRED; 02950 case AST_AOC_MULT_THOUSAND: 02951 return PRI_AOC_MULTIPLIER_THOUSAND; 02952 default: 02953 return PRI_AOC_MULTIPLIER_ONE; 02954 } 02955 }
static int sig_pri_aoc_multiplier_from_pri | ( | const int | mult | ) | [static] |
Definition at line 2966 of file sig_pri.c.
References AST_AOC_MULT_HUNDRED, AST_AOC_MULT_ONE, AST_AOC_MULT_ONEHUNDREDTH, AST_AOC_MULT_ONETENTH, AST_AOC_MULT_ONETHOUSANDTH, AST_AOC_MULT_TEN, and AST_AOC_MULT_THOUSAND.
Referenced by sig_pri_aoc_d_from_pri(), sig_pri_aoc_e_from_pri(), and sig_pri_aoc_s_from_pri().
02967 { 02968 switch (mult) { 02969 case PRI_AOC_MULTIPLIER_THOUSANDTH: 02970 return AST_AOC_MULT_ONETHOUSANDTH; 02971 case PRI_AOC_MULTIPLIER_HUNDREDTH: 02972 return AST_AOC_MULT_ONEHUNDREDTH; 02973 case PRI_AOC_MULTIPLIER_TENTH: 02974 return AST_AOC_MULT_ONETENTH; 02975 case PRI_AOC_MULTIPLIER_ONE: 02976 return AST_AOC_MULT_ONE; 02977 case PRI_AOC_MULTIPLIER_TEN: 02978 return AST_AOC_MULT_TEN; 02979 case PRI_AOC_MULTIPLIER_HUNDRED: 02980 return AST_AOC_MULT_HUNDRED; 02981 case PRI_AOC_MULTIPLIER_THOUSAND: 02982 return AST_AOC_MULT_THOUSAND; 02983 default: 02984 return AST_AOC_MULT_ONE; 02985 } 02986 }
static void sig_pri_aoc_request_from_pri | ( | const struct pri_subcmd_aoc_request * | aoc_request, | |
struct sig_pri_chan * | pvt, | |||
q931_call * | call | |||
) | [static] |
Definition at line 3163 of file sig_pri.c.
References sig_pri_span::aoc_passthrough_flag, sig_pri_chan::aoc_s_request_invoke_id, sig_pri_chan::aoc_s_request_invoke_id_valid, sig_pri_span::pri, sig_pri_chan::pri, SIG_PRI_AOC_GRANT_D, SIG_PRI_AOC_GRANT_E, and SIG_PRI_AOC_GRANT_S.
Referenced by sig_pri_handle_subcmds().
03164 { 03165 int request; 03166 03167 if (!aoc_request) { 03168 return; 03169 } 03170 03171 request = aoc_request->charging_request; 03172 03173 if (request & PRI_AOC_REQUEST_S) { 03174 if (pvt->pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_S) { 03175 /* An AOC-S response must come from the other side, so save off this invoke_id 03176 * and see if an AOC-S message comes in before the call is answered. */ 03177 pvt->aoc_s_request_invoke_id = aoc_request->invoke_id; 03178 pvt->aoc_s_request_invoke_id_valid = 1; 03179 03180 } else { 03181 pri_aoc_s_request_response_send(pvt->pri->pri, 03182 call, 03183 aoc_request->invoke_id, 03184 NULL); 03185 } 03186 } 03187 03188 if (request & PRI_AOC_REQUEST_D) { 03189 if (pvt->pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_D) { 03190 pri_aoc_de_request_response_send(pvt->pri->pri, 03191 call, 03192 PRI_AOC_REQ_RSP_CHARGING_INFO_FOLLOWS, 03193 aoc_request->invoke_id); 03194 } else { 03195 pri_aoc_de_request_response_send(pvt->pri->pri, 03196 call, 03197 PRI_AOC_REQ_RSP_ERROR_NOT_AVAILABLE, 03198 aoc_request->invoke_id); 03199 } 03200 } 03201 03202 if (request & PRI_AOC_REQUEST_E) { 03203 if (pvt->pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_E) { 03204 pri_aoc_de_request_response_send(pvt->pri->pri, 03205 call, 03206 PRI_AOC_REQ_RSP_CHARGING_INFO_FOLLOWS, 03207 aoc_request->invoke_id); 03208 } else { 03209 pri_aoc_de_request_response_send(pvt->pri->pri, 03210 call, 03211 PRI_AOC_REQ_RSP_ERROR_NOT_AVAILABLE, 03212 aoc_request->invoke_id); 03213 } 03214 } 03215 }
static void sig_pri_aoc_s_from_ast | ( | struct sig_pri_chan * | pvt, | |
struct ast_aoc_decoded * | decoded | |||
) | [static] |
Definition at line 3462 of file sig_pri.c.
References ast_aoc_volume_rate::amount, ast_aoc_flat_rate::amount, ast_aoc_duration_rate::amount, sig_pri_chan::aoc_s_request_invoke_id, sig_pri_chan::aoc_s_request_invoke_id_valid, AST_AOC_RATE_TYPE_DURATION, AST_AOC_RATE_TYPE_FLAT, AST_AOC_RATE_TYPE_FREE, AST_AOC_RATE_TYPE_FREE_FROM_BEGINNING, AST_AOC_RATE_TYPE_NA, AST_AOC_RATE_TYPE_SPECIAL_CODE, AST_AOC_RATE_TYPE_VOLUME, ast_aoc_s_get_count(), ast_aoc_s_get_rate_info(), ast_copy_string(), ast_strlen_zero(), sig_pri_chan::call, ast_aoc_s_entry::charged_item, ast_aoc_duration_rate::charging_type, ast_aoc_volume_rate::currency_name, ast_aoc_flat_rate::currency_name, ast_aoc_duration_rate::currency_name, ast_aoc_s_entry::duration, ast_aoc_s_entry::flat, ast_aoc_duration_rate::granularity_time, ast_aoc_duration_rate::granularity_time_scale, ast_aoc_volume_rate::multiplier, ast_aoc_flat_rate::multiplier, ast_aoc_duration_rate::multiplier, sig_pri_span::pri, sig_pri_chan::pri, ast_aoc_s_entry::rate, ast_aoc_s_entry::rate_type, sig_pri_aoc_charged_item_to_pri(), sig_pri_aoc_multiplier_from_ast(), sig_pri_aoc_scale_to_pri(), ast_aoc_s_entry::special_code, ast_aoc_duration_rate::time, ast_aoc_duration_rate::time_scale, ast_aoc_s_entry::volume, and ast_aoc_volume_rate::volume_unit.
Referenced by sig_pri_indicate().
03463 { 03464 struct pri_subcmd_aoc_s aoc_s = { 0, }; 03465 const struct ast_aoc_s_entry *entry; 03466 int idx; 03467 03468 for (idx = 0; idx < ast_aoc_s_get_count(decoded); idx++) { 03469 if (!(entry = ast_aoc_s_get_rate_info(decoded, idx))) { 03470 break; 03471 } 03472 03473 aoc_s.item[idx].chargeable = sig_pri_aoc_charged_item_to_pri(entry->charged_item); 03474 03475 switch (entry->rate_type) { 03476 case AST_AOC_RATE_TYPE_DURATION: 03477 aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_DURATION; 03478 aoc_s.item[idx].rate.duration.amount.cost = entry->rate.duration.amount; 03479 aoc_s.item[idx].rate.duration.amount.multiplier = 03480 sig_pri_aoc_multiplier_from_ast(entry->rate.duration.multiplier); 03481 aoc_s.item[idx].rate.duration.time.length = entry->rate.duration.time; 03482 aoc_s.item[idx].rate.duration.time.scale = 03483 sig_pri_aoc_scale_to_pri(entry->rate.duration.time_scale); 03484 aoc_s.item[idx].rate.duration.granularity.length = entry->rate.duration.granularity_time; 03485 aoc_s.item[idx].rate.duration.granularity.scale = 03486 sig_pri_aoc_scale_to_pri(entry->rate.duration.granularity_time_scale); 03487 aoc_s.item[idx].rate.duration.charging_type = entry->rate.duration.charging_type; 03488 03489 if (!ast_strlen_zero(entry->rate.duration.currency_name)) { 03490 ast_copy_string(aoc_s.item[idx].rate.duration.currency, 03491 entry->rate.duration.currency_name, 03492 sizeof(aoc_s.item[idx].rate.duration.currency)); 03493 } 03494 break; 03495 case AST_AOC_RATE_TYPE_FLAT: 03496 aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_FLAT; 03497 aoc_s.item[idx].rate.flat.amount.cost = entry->rate.flat.amount; 03498 aoc_s.item[idx].rate.flat.amount.multiplier = 03499 sig_pri_aoc_multiplier_from_ast(entry->rate.flat.multiplier); 03500 03501 if (!ast_strlen_zero(entry->rate.flat.currency_name)) { 03502 ast_copy_string(aoc_s.item[idx].rate.flat.currency, 03503 entry->rate.flat.currency_name, 03504 sizeof(aoc_s.item[idx].rate.flat.currency)); 03505 } 03506 break; 03507 case AST_AOC_RATE_TYPE_VOLUME: 03508 aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_VOLUME; 03509 aoc_s.item[idx].rate.volume.unit = entry->rate.volume.volume_unit; 03510 aoc_s.item[idx].rate.volume.amount.cost = entry->rate.volume.amount; 03511 aoc_s.item[idx].rate.volume.amount.multiplier = 03512 sig_pri_aoc_multiplier_from_ast(entry->rate.volume.multiplier); 03513 03514 if (!ast_strlen_zero(entry->rate.volume.currency_name)) { 03515 ast_copy_string(aoc_s.item[idx].rate.volume.currency, 03516 entry->rate.volume.currency_name, 03517 sizeof(aoc_s.item[idx].rate.volume.currency)); 03518 } 03519 break; 03520 case AST_AOC_RATE_TYPE_SPECIAL_CODE: 03521 aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_SPECIAL_CODE; 03522 aoc_s.item[idx].rate.special = entry->rate.special_code; 03523 break; 03524 case AST_AOC_RATE_TYPE_FREE: 03525 aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_FREE; 03526 break; 03527 case AST_AOC_RATE_TYPE_FREE_FROM_BEGINNING: 03528 aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_FREE_FROM_BEGINNING; 03529 break; 03530 default: 03531 case AST_AOC_RATE_TYPE_NA: 03532 aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_NOT_AVAILABLE; 03533 break; 03534 } 03535 } 03536 aoc_s.num_items = idx; 03537 03538 /* if this rate should be sent as a response to an AOC-S request we will 03539 * have an aoc_s_request_invoke_id associated with this pvt */ 03540 if (pvt->aoc_s_request_invoke_id_valid) { 03541 pri_aoc_s_request_response_send(pvt->pri->pri, pvt->call, pvt->aoc_s_request_invoke_id, &aoc_s); 03542 pvt->aoc_s_request_invoke_id_valid = 0; 03543 } else { 03544 pri_aoc_s_send(pvt->pri->pri, pvt->call, &aoc_s); 03545 } 03546 }
static void sig_pri_aoc_s_from_pri | ( | const struct pri_subcmd_aoc_s * | aoc_s, | |
struct ast_channel * | owner, | |||
int | passthrough | |||
) | [static] |
Definition at line 3070 of file sig_pri.c.
References AST_AOC_CHARGED_ITEM_NA, ast_aoc_create(), ast_aoc_destroy_decoded(), ast_aoc_destroy_encoded(), ast_aoc_encode(), ast_aoc_manager_event(), AST_AOC_S, ast_aoc_s_add_rate_duration(), ast_aoc_s_add_rate_flat(), ast_aoc_s_add_rate_free(), ast_aoc_s_add_rate_na(), ast_aoc_s_add_rate_special_charge_code(), ast_aoc_s_add_rate_volume(), AST_CONTROL_AOC, ast_queue_control_data(), sig_pri_aoc_charged_item_to_ast(), sig_pri_aoc_multiplier_from_pri(), and sig_pri_aoc_scale_to_ast().
Referenced by sig_pri_handle_subcmds().
03071 { 03072 struct ast_aoc_decoded *decoded = NULL; 03073 struct ast_aoc_encoded *encoded = NULL; 03074 size_t encoded_size = 0; 03075 int idx; 03076 03077 if (!owner || !aoc_s) { 03078 return; 03079 } 03080 03081 if (!(decoded = ast_aoc_create(AST_AOC_S, 0, 0))) { 03082 return; 03083 } 03084 03085 for (idx = 0; idx < aoc_s->num_items; ++idx) { 03086 enum ast_aoc_s_charged_item charged_item; 03087 03088 charged_item = sig_pri_aoc_charged_item_to_ast(aoc_s->item[idx].chargeable); 03089 if (charged_item == AST_AOC_CHARGED_ITEM_NA) { 03090 /* Delete the unknown charged item from the list. */ 03091 continue; 03092 } 03093 switch (aoc_s->item[idx].rate_type) { 03094 case PRI_AOC_RATE_TYPE_DURATION: 03095 ast_aoc_s_add_rate_duration(decoded, 03096 charged_item, 03097 aoc_s->item[idx].rate.duration.amount.cost, 03098 sig_pri_aoc_multiplier_from_pri(aoc_s->item[idx].rate.duration.amount.multiplier), 03099 aoc_s->item[idx].rate.duration.currency, 03100 aoc_s->item[idx].rate.duration.time.length, 03101 sig_pri_aoc_scale_to_ast(aoc_s->item[idx].rate.duration.time.scale), 03102 aoc_s->item[idx].rate.duration.granularity.length, 03103 sig_pri_aoc_scale_to_ast(aoc_s->item[idx].rate.duration.granularity.scale), 03104 aoc_s->item[idx].rate.duration.charging_type); 03105 break; 03106 case PRI_AOC_RATE_TYPE_FLAT: 03107 ast_aoc_s_add_rate_flat(decoded, 03108 charged_item, 03109 aoc_s->item[idx].rate.flat.amount.cost, 03110 sig_pri_aoc_multiplier_from_pri(aoc_s->item[idx].rate.flat.amount.multiplier), 03111 aoc_s->item[idx].rate.flat.currency); 03112 break; 03113 case PRI_AOC_RATE_TYPE_VOLUME: 03114 ast_aoc_s_add_rate_volume(decoded, 03115 charged_item, 03116 aoc_s->item[idx].rate.volume.unit, 03117 aoc_s->item[idx].rate.volume.amount.cost, 03118 sig_pri_aoc_multiplier_from_pri(aoc_s->item[idx].rate.volume.amount.multiplier), 03119 aoc_s->item[idx].rate.volume.currency); 03120 break; 03121 case PRI_AOC_RATE_TYPE_SPECIAL_CODE: 03122 ast_aoc_s_add_rate_special_charge_code(decoded, 03123 charged_item, 03124 aoc_s->item[idx].rate.special); 03125 break; 03126 case PRI_AOC_RATE_TYPE_FREE: 03127 ast_aoc_s_add_rate_free(decoded, charged_item, 0); 03128 break; 03129 case PRI_AOC_RATE_TYPE_FREE_FROM_BEGINNING: 03130 ast_aoc_s_add_rate_free(decoded, charged_item, 1); 03131 break; 03132 default: 03133 ast_aoc_s_add_rate_na(decoded, charged_item); 03134 break; 03135 } 03136 } 03137 03138 if (passthrough && (encoded = ast_aoc_encode(decoded, &encoded_size, owner))) { 03139 ast_queue_control_data(owner, AST_CONTROL_AOC, encoded, encoded_size); 03140 } 03141 03142 ast_aoc_manager_event(decoded, owner); 03143 03144 ast_aoc_destroy_decoded(decoded); 03145 ast_aoc_destroy_encoded(encoded); 03146 }
static enum ast_aoc_time_scale sig_pri_aoc_scale_to_ast | ( | enum PRI_AOC_TIME_SCALE | value | ) | [static] |
Definition at line 3031 of file sig_pri.c.
References AST_AOC_TIME_SCALE_DAY, AST_AOC_TIME_SCALE_HOUR, AST_AOC_TIME_SCALE_HUNDREDTH_SECOND, AST_AOC_TIME_SCALE_MINUTE, AST_AOC_TIME_SCALE_SECOND, AST_AOC_TIME_SCALE_TEN_SECOND, and AST_AOC_TIME_SCALE_TENTH_SECOND.
Referenced by sig_pri_aoc_s_from_pri().
03032 { 03033 switch (value) { 03034 default: 03035 case PRI_AOC_TIME_SCALE_HUNDREDTH_SECOND: 03036 return AST_AOC_TIME_SCALE_HUNDREDTH_SECOND; 03037 case PRI_AOC_TIME_SCALE_TENTH_SECOND: 03038 return AST_AOC_TIME_SCALE_TENTH_SECOND; 03039 case PRI_AOC_TIME_SCALE_SECOND: 03040 return AST_AOC_TIME_SCALE_SECOND; 03041 case PRI_AOC_TIME_SCALE_TEN_SECOND: 03042 return AST_AOC_TIME_SCALE_TEN_SECOND; 03043 case PRI_AOC_TIME_SCALE_MINUTE: 03044 return AST_AOC_TIME_SCALE_MINUTE; 03045 case PRI_AOC_TIME_SCALE_HOUR: 03046 return AST_AOC_TIME_SCALE_HOUR; 03047 case PRI_AOC_TIME_SCALE_DAY: 03048 return AST_AOC_TIME_SCALE_DAY; 03049 } 03050 return AST_AOC_TIME_SCALE_HUNDREDTH_SECOND; 03051 }
static enum PRI_AOC_TIME_SCALE sig_pri_aoc_scale_to_pri | ( | enum ast_aoc_time_scale | value | ) | [static] |
Definition at line 2999 of file sig_pri.c.
References AST_AOC_TIME_SCALE_DAY, AST_AOC_TIME_SCALE_HOUR, AST_AOC_TIME_SCALE_HUNDREDTH_SECOND, AST_AOC_TIME_SCALE_MINUTE, AST_AOC_TIME_SCALE_SECOND, AST_AOC_TIME_SCALE_TEN_SECOND, and AST_AOC_TIME_SCALE_TENTH_SECOND.
Referenced by sig_pri_aoc_s_from_ast().
03000 { 03001 switch (value) { 03002 default: 03003 case AST_AOC_TIME_SCALE_HUNDREDTH_SECOND: 03004 return PRI_AOC_TIME_SCALE_HUNDREDTH_SECOND; 03005 case AST_AOC_TIME_SCALE_TENTH_SECOND: 03006 return PRI_AOC_TIME_SCALE_TENTH_SECOND; 03007 case AST_AOC_TIME_SCALE_SECOND: 03008 return PRI_AOC_TIME_SCALE_SECOND; 03009 case AST_AOC_TIME_SCALE_TEN_SECOND: 03010 return PRI_AOC_TIME_SCALE_TEN_SECOND; 03011 case AST_AOC_TIME_SCALE_MINUTE: 03012 return PRI_AOC_TIME_SCALE_MINUTE; 03013 case AST_AOC_TIME_SCALE_HOUR: 03014 return PRI_AOC_TIME_SCALE_HOUR; 03015 case AST_AOC_TIME_SCALE_DAY: 03016 return PRI_AOC_TIME_SCALE_DAY; 03017 } 03018 }
static int sig_pri_attempt_transfer | ( | struct sig_pri_span * | pri, | |
q931_call * | call_1_pri, | |||
int | call_1_held, | |||
q931_call * | call_2_pri, | |||
int | call_2_held, | |||
xfer_rsp_callback | rsp_callback, | |||
void * | data | |||
) | [static] |
Definition at line 2334 of file sig_pri.c.
References ast_bridged_channel(), ast_channel_transfer_masquerade(), ast_channel_unlock, ast_mutex_lock, ast_mutex_unlock, ast_verb, sig_pri_span::lock, sig_pri_chan::owner, pri_find_principle_by_call(), sig_pri_span::pvts, sig_pri_lock_owner(), sig_pri_lock_private(), and sig_pri_unlock_private().
Referenced by sig_pri_handle_subcmds().
02335 { 02336 struct attempt_xfer_call { 02337 q931_call *pri; 02338 struct ast_channel *ast; 02339 int held; 02340 int chanpos; 02341 }; 02342 int retval; 02343 struct ast_channel *transferee; 02344 struct attempt_xfer_call *call_1; 02345 struct attempt_xfer_call *call_2; 02346 struct attempt_xfer_call *swap_call; 02347 struct attempt_xfer_call c1; 02348 struct attempt_xfer_call c2; 02349 02350 c1.pri = call_1_pri; 02351 c1.held = call_1_held; 02352 call_1 = &c1; 02353 02354 c2.pri = call_2_pri; 02355 c2.held = call_2_held; 02356 call_2 = &c2; 02357 02358 call_1->chanpos = pri_find_principle_by_call(pri, call_1->pri); 02359 call_2->chanpos = pri_find_principle_by_call(pri, call_2->pri); 02360 if (call_1->chanpos < 0 || call_2->chanpos < 0) { 02361 /* Calls not found in span control. */ 02362 if (rsp_callback) { 02363 /* Transfer failed. */ 02364 rsp_callback(data, 0); 02365 } 02366 return -1; 02367 } 02368 02369 /* Attempt to make transferee and target consistent. */ 02370 if (!call_1->held && call_2->held) { 02371 /* 02372 * Swap call_1 and call_2 to make call_1 the transferee(held call) 02373 * and call_2 the target(active call). 02374 */ 02375 swap_call = call_1; 02376 call_1 = call_2; 02377 call_2 = swap_call; 02378 } 02379 02380 /* Deadlock avoidance is attempted. */ 02381 sig_pri_lock_private(pri->pvts[call_1->chanpos]); 02382 sig_pri_lock_owner(pri, call_1->chanpos); 02383 sig_pri_lock_private(pri->pvts[call_2->chanpos]); 02384 sig_pri_lock_owner(pri, call_2->chanpos); 02385 02386 call_1->ast = pri->pvts[call_1->chanpos]->owner; 02387 call_2->ast = pri->pvts[call_2->chanpos]->owner; 02388 if (!call_1->ast || !call_2->ast) { 02389 /* At least one owner is not present. */ 02390 if (call_1->ast) { 02391 ast_channel_unlock(call_1->ast); 02392 } 02393 if (call_2->ast) { 02394 ast_channel_unlock(call_2->ast); 02395 } 02396 sig_pri_unlock_private(pri->pvts[call_1->chanpos]); 02397 sig_pri_unlock_private(pri->pvts[call_2->chanpos]); 02398 if (rsp_callback) { 02399 /* Transfer failed. */ 02400 rsp_callback(data, 0); 02401 } 02402 return -1; 02403 } 02404 02405 for (;;) { 02406 transferee = ast_bridged_channel(call_1->ast); 02407 if (transferee) { 02408 break; 02409 } 02410 02411 /* Try masquerading the other way. */ 02412 swap_call = call_1; 02413 call_1 = call_2; 02414 call_2 = swap_call; 02415 02416 transferee = ast_bridged_channel(call_1->ast); 02417 if (transferee) { 02418 break; 02419 } 02420 02421 /* Could not transfer. Neither call is bridged. */ 02422 ast_channel_unlock(call_1->ast); 02423 ast_channel_unlock(call_2->ast); 02424 sig_pri_unlock_private(pri->pvts[call_1->chanpos]); 02425 sig_pri_unlock_private(pri->pvts[call_2->chanpos]); 02426 02427 if (rsp_callback) { 02428 /* Transfer failed. */ 02429 rsp_callback(data, 0); 02430 } 02431 return -1; 02432 } 02433 02434 ast_verb(3, "TRANSFERRING %s to %s\n", call_1->ast->name, call_2->ast->name); 02435 02436 /* 02437 * Setup transfer masquerade. 02438 * 02439 * Note: There is an extremely nasty deadlock avoidance issue 02440 * with ast_channel_transfer_masquerade(). Deadlock may be possible if 02441 * the channels involved are proxies (chan_agent channels) and 02442 * it is called with locks. Unfortunately, there is no simple 02443 * or even merely difficult way to guarantee deadlock avoidance 02444 * and still be able to send an ECT success response without the 02445 * possibility of the bridged channel hanging up on us. 02446 */ 02447 ast_mutex_unlock(&pri->lock); 02448 retval = ast_channel_transfer_masquerade( 02449 call_2->ast, 02450 &call_2->ast->connected, 02451 call_2->held, 02452 transferee, 02453 &call_1->ast->connected, 02454 call_1->held); 02455 02456 /* Reacquire the pri->lock to hold off completion of the transfer masquerade. */ 02457 ast_mutex_lock(&pri->lock); 02458 02459 ast_channel_unlock(call_1->ast); 02460 ast_channel_unlock(call_2->ast); 02461 sig_pri_unlock_private(pri->pvts[call_1->chanpos]); 02462 sig_pri_unlock_private(pri->pvts[call_2->chanpos]); 02463 02464 if (rsp_callback) { 02465 /* 02466 * Report transfer status. 02467 * 02468 * Must do the callback before the masquerade completes to ensure 02469 * that the protocol message goes out before the call leg is 02470 * disconnected. 02471 */ 02472 rsp_callback(data, retval ? 0 : 1); 02473 } 02474 return retval; 02475 }
int sig_pri_available | ( | struct sig_pri_chan ** | pvt, | |
int | is_specific_channel | |||
) |
Definition at line 7334 of file sig_pri.c.
References sig_pri_chan::allocated, ast_mutex_lock, ast_mutex_unlock, HAVE_PRI_CALL_WAITING, sig_pri_span::lock, sig_pri_span::pri, sig_pri_chan::pri, sig_pri_available_check(), and sig_pri_cw_available().
Referenced by available().
07335 { 07336 struct sig_pri_chan *p = *pvt; 07337 struct sig_pri_span *pri; 07338 07339 if (!p->pri) { 07340 /* Something is wrong here. A PRI channel without the pri pointer? */ 07341 return 0; 07342 } 07343 pri = p->pri; 07344 07345 ast_mutex_lock(&pri->lock); 07346 if ( 07347 #if defined(HAVE_PRI_CALL_WAITING) 07348 /* 07349 * Only do call waiting calls if we have any 07350 * call waiting call outstanding. We do not 07351 * want new calls to steal a B channel 07352 * freed for an earlier call waiting call. 07353 */ 07354 !pri->num_call_waiting_calls && 07355 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 07356 sig_pri_available_check(p)) { 07357 p->allocated = 1; 07358 ast_mutex_unlock(&pri->lock); 07359 return 1; 07360 } 07361 07362 #if defined(HAVE_PRI_CALL_WAITING) 07363 if (!is_specific_channel) { 07364 struct sig_pri_chan *cw; 07365 07366 cw = sig_pri_cw_available(pri); 07367 if (cw) { 07368 /* We have a call waiting interface to use instead. */ 07369 cw->allocated = 1; 07370 *pvt = cw; 07371 ast_mutex_unlock(&pri->lock); 07372 return 1; 07373 } 07374 } 07375 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 07376 ast_mutex_unlock(&pri->lock); 07377 return 0; 07378 }
static int sig_pri_available_check | ( | struct sig_pri_chan * | pvt | ) | [static] |
Definition at line 7276 of file sig_pri.c.
References sig_pri_chan::no_b_channel, and sig_pri_is_chan_available().
Referenced by sig_pri_available(), and sig_pri_cw_available().
07277 { 07278 /* 07279 * If interface has a B channel and is available for use 07280 * then the channel is available. 07281 */ 07282 if (!pvt->no_b_channel && sig_pri_is_chan_available(pvt)) { 07283 return 1; 07284 } 07285 return 0; 07286 }
int sig_pri_call | ( | struct sig_pri_chan * | p, | |
struct ast_channel * | ast, | |||
char * | rdest, | |||
int | timeout, | |||
int | layer1 | |||
) |
Definition at line 6564 of file sig_pri.c.
References ast_channel::_state, ao2_ref, sig_pri_span::append_msn_to_user_tag, args, AST_APP_ARG, ast_app_parse_options(), ast_assert, ast_cc_get_monitor_by_recall_core_id(), ast_cc_is_recall(), ast_channel_get_device_name(), AST_CHANNEL_NAME, ast_copy_string(), AST_DECLARE_APP_ARGS, ast_free, ast_log(), AST_NONSTANDARD_APP_ARGS, ast_party_subaddress_init(), ast_setstate(), AST_STATE_DIALING, AST_STATE_DOWN, AST_STATE_RESERVED, ast_strdup, ast_strlen_zero(), ast_test_flag, ast_transfercapability2str(), ast_verb, sig_pri_chan::call, sig_pri_chan::call_level, ast_channel::caller, sig_pri_cc_monitor_instance::cc_id, sig_pri_chan::channel, ast_channel::connected, sig_pri_chan::deferred_digits, sig_pri_chan::dialdest, sig_pri_span::dialplan, dialplan2str(), sig_pri_chan::digital, ext, sig_pri_span::facilityenable, sig_pri_chan::hidecallerid, sig_pri_chan::hidecalleridname, ast_party_connected_line::id, ast_party_caller::id, sig_pri_span::initial_user_tag, sig_pri_span::internationalprefix, sig_pri_chan::is_call_waiting, IS_DIGITAL, sig_pri_span::localdialplan, LOG_DEBUG, LOG_ERROR, LOG_WARNING, monitor, ast_party_id::name, ast_channel::name, sig_pri_span::nationalprefix, sig_pri_span::nodetype, ast_party_id::number, OPT_AOC_REQUEST, OPT_ARG_AOC_REQUEST, OPT_ARG_ARRAY_SIZE, OPT_ARG_KEYPAD, OPT_KEYPAD, OPT_REVERSE_CHARGE, sig_pri_chan::owner, pbx_builtin_getvar_helper(), ast_party_number::presentation, sig_pri_chan::pri, sig_pri_span::pri, sig_pri_cc_monitor_instance::pri, pri_grab(), pri_rel(), PRI_TRANS_CAP_DIGITAL, sig_pri_chan::priexclusive, PVT_TO_CHANNEL(), S_COR, SIG_PRI_CALL_LEVEL_SETUP, sig_pri_call_opts, sig_pri_cc_type_name, sig_pri_party_subaddress_from_ast(), sig_pri_redirecting_update(), sig_pri_set_dialing(), sig_pri_set_digital(), sig_pri_set_outgoing(), ast_party_name::str, ast_party_number::str, ast_party_subaddress::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_name::valid, ast_party_number::valid, and ast_party_subaddress::valid.
Referenced by dahdi_call().
06565 { 06566 char dest[256]; /* must be same length as p->dialdest */ 06567 struct ast_party_subaddress dialed_subaddress; /* Called subaddress */ 06568 struct pri_sr *sr; 06569 char *c, *l, *n, *s; 06570 #ifdef SUPPORT_USERUSER 06571 const char *useruser; 06572 #endif 06573 int core_id; 06574 int pridialplan; 06575 int dp_strip; 06576 int prilocaldialplan; 06577 int ldp_strip; 06578 int exclusive; 06579 #if defined(HAVE_PRI_SETUP_KEYPAD) 06580 const char *keypad; 06581 #endif /* defined(HAVE_PRI_SETUP_KEYPAD) */ 06582 AST_DECLARE_APP_ARGS(args, 06583 AST_APP_ARG(group); /* channel/group token */ 06584 AST_APP_ARG(ext); /* extension token */ 06585 AST_APP_ARG(opts); /* options token */ 06586 AST_APP_ARG(other); /* Any remining unused arguments */ 06587 ); 06588 struct ast_flags opts; 06589 char *opt_args[OPT_ARG_ARRAY_SIZE]; 06590 06591 ast_log(LOG_DEBUG, "CALLER NAME: %s NUM: %s\n", 06592 S_COR(ast->connected.id.name.valid, ast->connected.id.name.str, ""), 06593 S_COR(ast->connected.id.number.valid, ast->connected.id.number.str, "")); 06594 06595 if (!p->pri) { 06596 ast_log(LOG_ERROR, "Could not find pri on channel %d\n", p->channel); 06597 return -1; 06598 } 06599 06600 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { 06601 ast_log(LOG_WARNING, "sig_pri_call called on %s, neither down nor reserved\n", ast->name); 06602 return -1; 06603 } 06604 06605 p->dialdest[0] = '\0'; 06606 sig_pri_set_outgoing(p, 1); 06607 06608 ast_copy_string(dest, rdest, sizeof(dest)); 06609 AST_NONSTANDARD_APP_ARGS(args, dest, '/'); 06610 if (ast_app_parse_options(sig_pri_call_opts, &opts, opt_args, args.opts)) { 06611 /* General invalid option syntax. */ 06612 return -1; 06613 } 06614 06615 c = args.ext; 06616 if (!c) { 06617 c = ""; 06618 } 06619 06620 /* setup dialed_subaddress if found */ 06621 ast_party_subaddress_init(&dialed_subaddress); 06622 s = strchr(c, ':'); 06623 if (s) { 06624 *s = '\0'; 06625 s++; 06626 /* prefix */ 06627 /* 'n' = NSAP */ 06628 /* 'u' = User Specified */ 06629 /* Default = NSAP */ 06630 switch (*s) { 06631 case 'U': 06632 case 'u': 06633 s++; 06634 dialed_subaddress.type = 2; 06635 break; 06636 case 'N': 06637 case 'n': 06638 s++; 06639 /* default already covered with ast_party_subaddress_init */ 06640 break; 06641 } 06642 dialed_subaddress.str = s; 06643 dialed_subaddress.valid = 1; 06644 } 06645 06646 l = NULL; 06647 n = NULL; 06648 if (!p->hidecallerid) { 06649 if (ast->connected.id.number.valid) { 06650 /* If we get to the end of this loop without breaking, there's no 06651 * calleridnum. This is done instead of testing for "unknown" or 06652 * the thousands of other ways that the calleridnum could be 06653 * invalid. */ 06654 for (l = ast->connected.id.number.str; l && *l; l++) { 06655 if (strchr("0123456789", *l)) { 06656 l = ast->connected.id.number.str; 06657 break; 06658 } 06659 } 06660 } else { 06661 l = NULL; 06662 } 06663 if (!p->hidecalleridname) { 06664 n = ast->connected.id.name.valid ? ast->connected.id.name.str : NULL; 06665 } 06666 } 06667 06668 if (strlen(c) < p->stripmsd) { 06669 ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd); 06670 return -1; 06671 } 06672 06673 /* Extract any 'w' deferred digits. */ 06674 s = strchr(c + p->stripmsd, 'w'); 06675 if (s) { 06676 *s++ = '\0'; 06677 ast_copy_string(p->deferred_digits, s, sizeof(p->deferred_digits)); 06678 /* 06679 * Since we have a 'w', this means that there will not be any 06680 * more normal dialed digits. Therefore, the sending complete 06681 * ie needs to be sent with any normal digits. 06682 */ 06683 } else { 06684 p->deferred_digits[0] = '\0'; 06685 } 06686 06687 pri_grab(p, p->pri); 06688 if (!(p->call = pri_new_call(p->pri->pri))) { 06689 ast_log(LOG_WARNING, "Unable to create call on channel %d\n", p->channel); 06690 pri_rel(p->pri); 06691 return -1; 06692 } 06693 if (!(sr = pri_sr_new())) { 06694 ast_log(LOG_WARNING, "Failed to allocate setup request on channel %d\n", 06695 p->channel); 06696 pri_destroycall(p->pri->pri, p->call); 06697 p->call = NULL; 06698 pri_rel(p->pri); 06699 return -1; 06700 } 06701 06702 sig_pri_set_digital(p, IS_DIGITAL(ast->transfercapability)); /* push up to parent for EC */ 06703 06704 #if defined(HAVE_PRI_CALL_WAITING) 06705 if (p->is_call_waiting) { 06706 /* 06707 * Indicate that this is a call waiting call. 06708 * i.e., Normal call but with no B channel. 06709 */ 06710 pri_sr_set_channel(sr, 0, 0, 1); 06711 } else 06712 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 06713 { 06714 /* Should the picked channel be used exclusively? */ 06715 if (p->priexclusive || p->pri->nodetype == PRI_NETWORK) { 06716 exclusive = 1; 06717 } else { 06718 exclusive = 0; 06719 } 06720 pri_sr_set_channel(sr, PVT_TO_CHANNEL(p), exclusive, 1); 06721 } 06722 06723 pri_sr_set_bearer(sr, p->digital ? PRI_TRANS_CAP_DIGITAL : ast->transfercapability, 06724 (p->digital ? -1 : layer1)); 06725 06726 if (p->pri->facilityenable) 06727 pri_facility_enable(p->pri->pri); 06728 06729 ast_verb(3, "Requested transfer capability: 0x%.2x - %s\n", ast->transfercapability, ast_transfercapability2str(ast->transfercapability)); 06730 dp_strip = 0; 06731 pridialplan = p->pri->dialplan - 1; 06732 if (pridialplan == -2 || pridialplan == -3) { /* compute dynamically */ 06733 if (strncmp(c + p->stripmsd, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) { 06734 if (pridialplan == -2) { 06735 dp_strip = strlen(p->pri->internationalprefix); 06736 } 06737 pridialplan = PRI_INTERNATIONAL_ISDN; 06738 } else if (strncmp(c + p->stripmsd, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) { 06739 if (pridialplan == -2) { 06740 dp_strip = strlen(p->pri->nationalprefix); 06741 } 06742 pridialplan = PRI_NATIONAL_ISDN; 06743 } else { 06744 pridialplan = PRI_LOCAL_ISDN; 06745 } 06746 } 06747 while (c[p->stripmsd] > '9' && c[p->stripmsd] != '*' && c[p->stripmsd] != '#') { 06748 switch (c[p->stripmsd]) { 06749 case 'U': 06750 pridialplan = (PRI_TON_UNKNOWN << 4) | (pridialplan & 0xf); 06751 break; 06752 case 'I': 06753 pridialplan = (PRI_TON_INTERNATIONAL << 4) | (pridialplan & 0xf); 06754 break; 06755 case 'N': 06756 pridialplan = (PRI_TON_NATIONAL << 4) | (pridialplan & 0xf); 06757 break; 06758 case 'L': 06759 pridialplan = (PRI_TON_NET_SPECIFIC << 4) | (pridialplan & 0xf); 06760 break; 06761 case 'S': 06762 pridialplan = (PRI_TON_SUBSCRIBER << 4) | (pridialplan & 0xf); 06763 break; 06764 case 'V': 06765 pridialplan = (PRI_TON_ABBREVIATED << 4) | (pridialplan & 0xf); 06766 break; 06767 case 'R': 06768 pridialplan = (PRI_TON_RESERVED << 4) | (pridialplan & 0xf); 06769 break; 06770 case 'u': 06771 pridialplan = PRI_NPI_UNKNOWN | (pridialplan & 0xf0); 06772 break; 06773 case 'e': 06774 pridialplan = PRI_NPI_E163_E164 | (pridialplan & 0xf0); 06775 break; 06776 case 'x': 06777 pridialplan = PRI_NPI_X121 | (pridialplan & 0xf0); 06778 break; 06779 case 'f': 06780 pridialplan = PRI_NPI_F69 | (pridialplan & 0xf0); 06781 break; 06782 case 'n': 06783 pridialplan = PRI_NPI_NATIONAL | (pridialplan & 0xf0); 06784 break; 06785 case 'p': 06786 pridialplan = PRI_NPI_PRIVATE | (pridialplan & 0xf0); 06787 break; 06788 case 'r': 06789 pridialplan = PRI_NPI_RESERVED | (pridialplan & 0xf0); 06790 break; 06791 default: 06792 if (isalpha(c[p->stripmsd])) { 06793 ast_log(LOG_WARNING, "Unrecognized pridialplan %s modifier: %c\n", 06794 c[p->stripmsd] > 'Z' ? "NPI" : "TON", c[p->stripmsd]); 06795 } 06796 break; 06797 } 06798 c++; 06799 } 06800 #if defined(HAVE_PRI_SETUP_KEYPAD) 06801 if (ast_test_flag(&opts, OPT_KEYPAD) 06802 && !ast_strlen_zero(opt_args[OPT_ARG_KEYPAD])) { 06803 /* We have a keypad facility digits option with digits. */ 06804 keypad = opt_args[OPT_ARG_KEYPAD]; 06805 pri_sr_set_keypad_digits(sr, keypad); 06806 } else { 06807 keypad = NULL; 06808 } 06809 if (!keypad || !ast_strlen_zero(c + p->stripmsd + dp_strip)) 06810 #endif /* defined(HAVE_PRI_SETUP_KEYPAD) */ 06811 { 06812 pri_sr_set_called(sr, c + p->stripmsd + dp_strip, pridialplan, s ? 1 : 0); 06813 } 06814 06815 #if defined(HAVE_PRI_SUBADDR) 06816 if (dialed_subaddress.valid) { 06817 struct pri_party_subaddress subaddress; 06818 06819 memset(&subaddress, 0, sizeof(subaddress)); 06820 sig_pri_party_subaddress_from_ast(&subaddress, &dialed_subaddress); 06821 pri_sr_set_called_subaddress(sr, &subaddress); 06822 } 06823 #endif /* defined(HAVE_PRI_SUBADDR) */ 06824 #if defined(HAVE_PRI_REVERSE_CHARGE) 06825 if (ast_test_flag(&opts, OPT_REVERSE_CHARGE)) { 06826 pri_sr_set_reversecharge(sr, PRI_REVERSECHARGE_REQUESTED); 06827 } 06828 #endif /* defined(HAVE_PRI_REVERSE_CHARGE) */ 06829 #if defined(HAVE_PRI_AOC_EVENTS) 06830 if (ast_test_flag(&opts, OPT_AOC_REQUEST) 06831 && !ast_strlen_zero(opt_args[OPT_ARG_AOC_REQUEST])) { 06832 if (strchr(opt_args[OPT_ARG_AOC_REQUEST], 's')) { 06833 pri_sr_set_aoc_charging_request(sr, PRI_AOC_REQUEST_S); 06834 } 06835 if (strchr(opt_args[OPT_ARG_AOC_REQUEST], 'd')) { 06836 pri_sr_set_aoc_charging_request(sr, PRI_AOC_REQUEST_D); 06837 } 06838 if (strchr(opt_args[OPT_ARG_AOC_REQUEST], 'e')) { 06839 pri_sr_set_aoc_charging_request(sr, PRI_AOC_REQUEST_E); 06840 } 06841 } 06842 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 06843 06844 /* Setup the user tag for party id's from this device for this call. */ 06845 if (p->pri->append_msn_to_user_tag) { 06846 snprintf(p->user_tag, sizeof(p->user_tag), "%s_%s", p->pri->initial_user_tag, 06847 p->pri->nodetype == PRI_NETWORK 06848 ? c + p->stripmsd + dp_strip 06849 : S_COR(ast->connected.id.number.valid, 06850 ast->connected.id.number.str, "")); 06851 } else { 06852 ast_copy_string(p->user_tag, p->pri->initial_user_tag, sizeof(p->user_tag)); 06853 } 06854 06855 /* 06856 * Replace the caller id tag from the channel creation 06857 * with the actual tag value. 06858 */ 06859 ast_free(ast->caller.id.tag); 06860 ast->caller.id.tag = ast_strdup(p->user_tag); 06861 06862 ldp_strip = 0; 06863 prilocaldialplan = p->pri->localdialplan - 1; 06864 if ((l != NULL) && (prilocaldialplan == -2 || prilocaldialplan == -3)) { /* compute dynamically */ 06865 if (strncmp(l, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) { 06866 if (prilocaldialplan == -2) { 06867 ldp_strip = strlen(p->pri->internationalprefix); 06868 } 06869 prilocaldialplan = PRI_INTERNATIONAL_ISDN; 06870 } else if (strncmp(l, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) { 06871 if (prilocaldialplan == -2) { 06872 ldp_strip = strlen(p->pri->nationalprefix); 06873 } 06874 prilocaldialplan = PRI_NATIONAL_ISDN; 06875 } else { 06876 prilocaldialplan = PRI_LOCAL_ISDN; 06877 } 06878 } 06879 if (l != NULL) { 06880 while (*l > '9' && *l != '*' && *l != '#') { 06881 switch (*l) { 06882 case 'U': 06883 prilocaldialplan = (PRI_TON_UNKNOWN << 4) | (prilocaldialplan & 0xf); 06884 break; 06885 case 'I': 06886 prilocaldialplan = (PRI_TON_INTERNATIONAL << 4) | (prilocaldialplan & 0xf); 06887 break; 06888 case 'N': 06889 prilocaldialplan = (PRI_TON_NATIONAL << 4) | (prilocaldialplan & 0xf); 06890 break; 06891 case 'L': 06892 prilocaldialplan = (PRI_TON_NET_SPECIFIC << 4) | (prilocaldialplan & 0xf); 06893 break; 06894 case 'S': 06895 prilocaldialplan = (PRI_TON_SUBSCRIBER << 4) | (prilocaldialplan & 0xf); 06896 break; 06897 case 'V': 06898 prilocaldialplan = (PRI_TON_ABBREVIATED << 4) | (prilocaldialplan & 0xf); 06899 break; 06900 case 'R': 06901 prilocaldialplan = (PRI_TON_RESERVED << 4) | (prilocaldialplan & 0xf); 06902 break; 06903 case 'u': 06904 prilocaldialplan = PRI_NPI_UNKNOWN | (prilocaldialplan & 0xf0); 06905 break; 06906 case 'e': 06907 prilocaldialplan = PRI_NPI_E163_E164 | (prilocaldialplan & 0xf0); 06908 break; 06909 case 'x': 06910 prilocaldialplan = PRI_NPI_X121 | (prilocaldialplan & 0xf0); 06911 break; 06912 case 'f': 06913 prilocaldialplan = PRI_NPI_F69 | (prilocaldialplan & 0xf0); 06914 break; 06915 case 'n': 06916 prilocaldialplan = PRI_NPI_NATIONAL | (prilocaldialplan & 0xf0); 06917 break; 06918 case 'p': 06919 prilocaldialplan = PRI_NPI_PRIVATE | (prilocaldialplan & 0xf0); 06920 break; 06921 case 'r': 06922 prilocaldialplan = PRI_NPI_RESERVED | (prilocaldialplan & 0xf0); 06923 break; 06924 default: 06925 if (isalpha(*l)) { 06926 ast_log(LOG_WARNING, 06927 "Unrecognized prilocaldialplan %s modifier: %c\n", 06928 *l > 'Z' ? "NPI" : "TON", *l); 06929 } 06930 break; 06931 } 06932 l++; 06933 } 06934 } 06935 pri_sr_set_caller(sr, l ? (l + ldp_strip) : NULL, n, prilocaldialplan, 06936 p->use_callingpres ? ast->connected.id.number.presentation : (l ? PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN : PRES_NUMBER_NOT_AVAILABLE)); 06937 06938 #if defined(HAVE_PRI_SUBADDR) 06939 if (ast->connected.id.subaddress.valid) { 06940 struct pri_party_subaddress subaddress; 06941 06942 memset(&subaddress, 0, sizeof(subaddress)); 06943 sig_pri_party_subaddress_from_ast(&subaddress, &ast->connected.id.subaddress); 06944 pri_sr_set_caller_subaddress(sr, &subaddress); 06945 } 06946 #endif /* defined(HAVE_PRI_SUBADDR) */ 06947 06948 sig_pri_redirecting_update(p, ast); 06949 06950 #ifdef SUPPORT_USERUSER 06951 /* User-user info */ 06952 useruser = pbx_builtin_getvar_helper(p->owner, "USERUSERINFO"); 06953 if (useruser) 06954 pri_sr_set_useruser(sr, useruser); 06955 #endif 06956 06957 #if defined(HAVE_PRI_CCSS) 06958 if (ast_cc_is_recall(ast, &core_id, sig_pri_cc_type_name)) { 06959 struct ast_cc_monitor *monitor; 06960 char device_name[AST_CHANNEL_NAME]; 06961 06962 /* This is a CC recall call. */ 06963 ast_channel_get_device_name(ast, device_name, sizeof(device_name)); 06964 monitor = ast_cc_get_monitor_by_recall_core_id(core_id, device_name); 06965 if (monitor) { 06966 struct sig_pri_cc_monitor_instance *instance; 06967 06968 instance = monitor->private_data; 06969 06970 /* If this fails then we have monitor instance ambiguity. */ 06971 ast_assert(p->pri == instance->pri); 06972 06973 if (pri_cc_call(p->pri->pri, instance->cc_id, p->call, sr)) { 06974 /* The CC recall call failed for some reason. */ 06975 ast_log(LOG_WARNING, "Unable to setup CC recall call to device %s\n", 06976 device_name); 06977 ao2_ref(monitor, -1); 06978 pri_destroycall(p->pri->pri, p->call); 06979 p->call = NULL; 06980 pri_rel(p->pri); 06981 pri_sr_free(sr); 06982 return -1; 06983 } 06984 ao2_ref(monitor, -1); 06985 } else { 06986 core_id = -1; 06987 } 06988 } else 06989 #endif /* defined(HAVE_PRI_CCSS) */ 06990 { 06991 core_id = -1; 06992 } 06993 if (core_id == -1 && pri_setup(p->pri->pri, p->call, sr)) { 06994 ast_log(LOG_WARNING, "Unable to setup call to %s (using %s)\n", 06995 c + p->stripmsd + dp_strip, dialplan2str(p->pri->dialplan)); 06996 pri_destroycall(p->pri->pri, p->call); 06997 p->call = NULL; 06998 pri_rel(p->pri); 06999 pri_sr_free(sr); 07000 return -1; 07001 } 07002 p->call_level = SIG_PRI_CALL_LEVEL_SETUP; 07003 pri_sr_free(sr); 07004 ast_setstate(ast, AST_STATE_DIALING); 07005 sig_pri_set_dialing(p, 1); 07006 pri_rel(p->pri); 07007 return 0; 07008 }
static const char* sig_pri_call_level2str | ( | enum sig_pri_call_level | level | ) | [static] |
Definition at line 123 of file sig_pri.c.
References SIG_PRI_CALL_LEVEL_ALERTING, SIG_PRI_CALL_LEVEL_CONNECT, SIG_PRI_CALL_LEVEL_DEFER_DIAL, SIG_PRI_CALL_LEVEL_IDLE, SIG_PRI_CALL_LEVEL_OVERLAP, SIG_PRI_CALL_LEVEL_PROCEEDING, and SIG_PRI_CALL_LEVEL_SETUP.
Referenced by sig_pri_cli_show_channels(), and sig_pri_digit_begin().
00124 { 00125 switch (level) { 00126 case SIG_PRI_CALL_LEVEL_IDLE: 00127 return "Idle"; 00128 case SIG_PRI_CALL_LEVEL_SETUP: 00129 return "Setup"; 00130 case SIG_PRI_CALL_LEVEL_OVERLAP: 00131 return "Overlap"; 00132 case SIG_PRI_CALL_LEVEL_PROCEEDING: 00133 return "Proceeding"; 00134 case SIG_PRI_CALL_LEVEL_ALERTING: 00135 return "Alerting"; 00136 case SIG_PRI_CALL_LEVEL_DEFER_DIAL: 00137 return "DeferDial"; 00138 case SIG_PRI_CALL_LEVEL_CONNECT: 00139 return "Connect"; 00140 } 00141 return "Unknown"; 00142 }
int sig_pri_cc_agent_callee_available | ( | struct ast_cc_agent * | agent | ) |
Alert the caller that it is time to try recalling.
agent | CC core agent control. |
The agent's job is to send a message to the caller to notify it of such a change. If the agent is able to discern that the caller is currently unavailable, then the agent should react by calling the ast_cc_caller_unavailable function.
0 | on success. | |
-1 | on error. |
Definition at line 8352 of file sig_pri.c.
References ast_mutex_lock, ast_mutex_unlock, sig_pri_cc_agent_prv::cc_id, sig_pri_span::lock, sig_pri_cc_agent_prv::pri, sig_pri_span::pri, and ast_cc_agent::private_data.
08353 { 08354 struct sig_pri_cc_agent_prv *cc_pvt; 08355 08356 cc_pvt = agent->private_data; 08357 ast_mutex_lock(&cc_pvt->pri->lock); 08358 pri_cc_remote_user_free(cc_pvt->pri->pri, cc_pvt->cc_id); 08359 ast_mutex_unlock(&cc_pvt->pri->lock); 08360 return 0; 08361 }
static int sig_pri_cc_agent_cmp_cc_id | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 2490 of file sig_pri.c.
References sig_pri_cc_agent_prv::cc_id, CMP_MATCH, CMP_STOP, sig_pri_cc_agent_prv::pri, and ast_cc_agent::private_data.
Referenced by sig_pri_find_cc_agent_by_cc_id().
02491 { 02492 struct ast_cc_agent *agent_1 = obj; 02493 struct sig_pri_cc_agent_prv *agent_prv_1 = agent_1->private_data; 02494 struct sig_pri_cc_agent_prv *agent_prv_2 = arg; 02495 02496 return (agent_prv_1 && agent_prv_1->pri == agent_prv_2->pri 02497 && agent_prv_1->cc_id == agent_prv_2->cc_id) ? CMP_MATCH | CMP_STOP : 0; 02498 }
void sig_pri_cc_agent_destructor | ( | struct ast_cc_agent * | agent | ) |
Destroy private data on the agent.
agent | CC core agent control. |
Definition at line 8381 of file sig_pri.c.
References ast_free, ast_mutex_lock, ast_mutex_unlock, sig_pri_cc_agent_prv::cc_id, sig_pri_cc_agent_prv::cc_request_response_pending, sig_pri_span::lock, sig_pri_cc_agent_prv::pri, sig_pri_span::pri, and ast_cc_agent::private_data.
Referenced by dahdi_pri_cc_agent_destructor().
08382 { 08383 struct sig_pri_cc_agent_prv *cc_pvt; 08384 int res; 08385 08386 cc_pvt = agent->private_data; 08387 if (!cc_pvt) { 08388 /* The agent constructor probably failed. */ 08389 return; 08390 } 08391 ast_mutex_lock(&cc_pvt->pri->lock); 08392 res = -1; 08393 if (cc_pvt->cc_request_response_pending) { 08394 res = pri_cc_req_rsp(cc_pvt->pri->pri, cc_pvt->cc_id, 2/* short_term_denial */); 08395 } 08396 if (res) { 08397 pri_cc_cancel(cc_pvt->pri->pri, cc_pvt->cc_id); 08398 } 08399 ast_mutex_unlock(&cc_pvt->pri->lock); 08400 ast_free(cc_pvt); 08401 }
int sig_pri_cc_agent_init | ( | struct ast_cc_agent * | agent, | |
struct sig_pri_chan * | pvt_chan | |||
) |
PRI CC agent initialization.
agent | CC core agent control. | |
pvt_chan | Original channel the agent will attempt to recall. |
0 | on success. | |
-1 | on error. |
Definition at line 8064 of file sig_pri.c.
References ast_calloc, ast_free, ast_mutex_lock, ast_mutex_unlock, sig_pri_chan::call, sig_pri_span::lock, sig_pri_chan::pri, sig_pri_span::pri, and ast_cc_agent::private_data.
Referenced by dahdi_pri_cc_agent_init().
08065 { 08066 struct sig_pri_cc_agent_prv *cc_pvt; 08067 08068 cc_pvt = ast_calloc(1, sizeof(*cc_pvt)); 08069 if (!cc_pvt) { 08070 return -1; 08071 } 08072 08073 ast_mutex_lock(&pvt_chan->pri->lock); 08074 cc_pvt->pri = pvt_chan->pri; 08075 cc_pvt->cc_id = pri_cc_available(pvt_chan->pri->pri, pvt_chan->call); 08076 ast_mutex_unlock(&pvt_chan->pri->lock); 08077 if (cc_pvt->cc_id == -1) { 08078 ast_free(cc_pvt); 08079 return -1; 08080 } 08081 agent->private_data = cc_pvt; 08082 return 0; 08083 }
int sig_pri_cc_agent_party_b_free | ( | struct ast_cc_agent * | agent | ) |
Let the caller know that the callee has become free but that the caller cannot attempt to call back because he is either busy or there is congestion on his line.
agent | CC core agent control. |
0 | on success. | |
-1 | on error. |
Definition at line 8296 of file sig_pri.c.
References ast_mutex_lock, ast_mutex_unlock, sig_pri_cc_agent_prv::cc_id, sig_pri_span::lock, sig_pri_cc_agent_prv::pri, sig_pri_span::pri, and ast_cc_agent::private_data.
08297 { 08298 struct sig_pri_cc_agent_prv *cc_pvt; 08299 08300 cc_pvt = agent->private_data; 08301 ast_mutex_lock(&cc_pvt->pri->lock); 08302 pri_cc_b_free(cc_pvt->pri->pri, cc_pvt->cc_id); 08303 ast_mutex_unlock(&cc_pvt->pri->lock); 08304 return 0; 08305 }
void sig_pri_cc_agent_req_rsp | ( | struct ast_cc_agent * | agent, | |
enum ast_cc_agent_response_reason | reason | |||
) |
Response to a CC request.
agent | CC core agent control. | |
reason | CC request response status. |
The duty of this is to issue a propper response to a CC request from the caller by acknowledging receipt of that request or rejecting it.
Definition at line 8157 of file sig_pri.c.
References AST_CC_AGENT_RESPONSE_FAILURE_INVALID, AST_CC_AGENT_RESPONSE_FAILURE_TOO_MANY, AST_CC_AGENT_RESPONSE_SUCCESS, ast_cc_failed(), ast_mutex_lock, ast_mutex_unlock, sig_pri_cc_agent_prv::cc_id, sig_pri_cc_agent_prv::cc_request_response_pending, ast_cc_agent::core_id, sig_pri_span::lock, sig_pri_cc_agent_prv::pri, sig_pri_span::pri, ast_cc_agent::private_data, sig_pri_cc_type_name, and status.
08158 { 08159 struct sig_pri_cc_agent_prv *cc_pvt; 08160 int res; 08161 int status; 08162 const char *failed_msg; 08163 static const char *failed_to_send = "Failed to send the CC request response."; 08164 static const char *not_accepted = "The core declined the CC request."; 08165 08166 cc_pvt = agent->private_data; 08167 ast_mutex_lock(&cc_pvt->pri->lock); 08168 if (cc_pvt->cc_request_response_pending) { 08169 cc_pvt->cc_request_response_pending = 0; 08170 08171 /* Convert core response reason to ISDN response status. */ 08172 status = 2;/* short_term_denial */ 08173 switch (reason) { 08174 case AST_CC_AGENT_RESPONSE_SUCCESS: 08175 status = 0;/* success */ 08176 break; 08177 case AST_CC_AGENT_RESPONSE_FAILURE_INVALID: 08178 status = 2;/* short_term_denial */ 08179 break; 08180 case AST_CC_AGENT_RESPONSE_FAILURE_TOO_MANY: 08181 status = 5;/* queue_full */ 08182 break; 08183 } 08184 08185 res = pri_cc_req_rsp(cc_pvt->pri->pri, cc_pvt->cc_id, status); 08186 if (!status) { 08187 /* CC core request was accepted. */ 08188 if (res) { 08189 failed_msg = failed_to_send; 08190 } else { 08191 failed_msg = NULL; 08192 } 08193 } else { 08194 /* CC core request was declined. */ 08195 if (res) { 08196 failed_msg = failed_to_send; 08197 } else { 08198 failed_msg = not_accepted; 08199 } 08200 } 08201 } else { 08202 failed_msg = NULL; 08203 } 08204 ast_mutex_unlock(&cc_pvt->pri->lock); 08205 if (failed_msg) { 08206 ast_cc_failed(agent->core_id, "%s agent: %s", sig_pri_cc_type_name, failed_msg); 08207 } 08208 }
int sig_pri_cc_agent_start_monitoring | ( | struct ast_cc_agent * | agent | ) |
Begin monitoring a busy device.
agent | CC core agent control. |
0 | on success. | |
-1 | on error. |
Definition at line 8325 of file sig_pri.c.
08326 { 08327 /* libpri already knows when and how it needs to monitor Party A. */ 08328 return 0; 08329 }
int sig_pri_cc_agent_start_offer_timer | ( | struct ast_cc_agent * | agent | ) |
Start the offer timer.
agent | CC core agent control. |
The primary reason why this functionality is left to the specific agent implementations is due to the differing use of schedulers throughout the code. Some channel drivers may already have a scheduler context they wish to use, and amongst those, some may use the ast_sched API while others may use the ast_sched_thread API, which are incompatible.
0 | on success. | |
-1 | on error. |
Definition at line 8108 of file sig_pri.c.
08109 { 08110 /* libpri maintains it's own offer timer in the form of T_RETENTION. */ 08111 return 0; 08112 }
int sig_pri_cc_agent_status_req | ( | struct ast_cc_agent * | agent | ) |
Request the status of the agent's device.
agent | CC core agent control. |
0 | on success. | |
-1 | on error. |
Definition at line 8227 of file sig_pri.c.
References ast_mutex_lock, ast_mutex_unlock, sig_pri_cc_agent_prv::cc_id, sig_pri_span::lock, sig_pri_cc_agent_prv::pri, sig_pri_span::pri, and ast_cc_agent::private_data.
08228 { 08229 struct sig_pri_cc_agent_prv *cc_pvt; 08230 08231 cc_pvt = agent->private_data; 08232 ast_mutex_lock(&cc_pvt->pri->lock); 08233 pri_cc_status_req(cc_pvt->pri->pri, cc_pvt->cc_id); 08234 ast_mutex_unlock(&cc_pvt->pri->lock); 08235 return 0; 08236 }
int sig_pri_cc_agent_stop_offer_timer | ( | struct ast_cc_agent * | agent | ) |
Stop the offer timer.
agent | CC core agent control. |
0 | on success. | |
-1 | on error. |
Definition at line 8129 of file sig_pri.c.
08130 { 08131 /* libpri maintains it's own offer timer in the form of T_RETENTION. */ 08132 return 0; 08133 }
int sig_pri_cc_agent_stop_ringing | ( | struct ast_cc_agent * | agent | ) |
Request for an agent's phone to stop ringing.
agent | CC core agent control. |
0 | on success. | |
-1 | on error. |
Definition at line 8262 of file sig_pri.c.
References ast_mutex_lock, ast_mutex_unlock, sig_pri_cc_agent_prv::cc_id, sig_pri_span::lock, sig_pri_cc_agent_prv::pri, sig_pri_span::pri, and ast_cc_agent::private_data.
08263 { 08264 struct sig_pri_cc_agent_prv *cc_pvt; 08265 08266 cc_pvt = agent->private_data; 08267 ast_mutex_lock(&cc_pvt->pri->lock); 08268 pri_cc_stop_alerting(cc_pvt->pri->pri, cc_pvt->cc_id); 08269 ast_mutex_unlock(&cc_pvt->pri->lock); 08270 return 0; 08271 }
static int sig_pri_cc_available | ( | struct sig_pri_span * | pri, | |
int | chanpos, | |||
long | cc_id, | |||
enum ast_cc_service_type | service | |||
) | [static] |
Definition at line 2666 of file sig_pri.c.
References ao2_ref, ao2_unlink, AST_CC_GENERIC_MONITOR_TYPE, ast_cc_get_current_core_id(), AST_CC_MONITOR_ALWAYS, AST_CC_MONITOR_GENERIC, AST_CC_MONITOR_NATIVE, AST_CC_MONITOR_NEVER, ast_channel_get_cc_config_params(), ast_channel_get_device_name(), AST_CHANNEL_NAME, ast_get_cc_monitor_policy(), ast_queue_cc_frame(), sig_pri_cc_monitor_instance::core_id, monitor, sig_pri_chan::owner, sig_pri_cc_monitor_instance::pri, sig_pri_span::pvts, sig_pri_cc_monitor_instance_init(), sig_pri_cc_monitors, sig_pri_cc_type_name, sig_pri_get_orig_dialstring(), and sig_pri_make_cc_dialstring().
Referenced by sig_pri_handle_subcmds().
02667 { 02668 struct sig_pri_chan *pvt; 02669 struct ast_cc_config_params *cc_params; 02670 struct sig_pri_cc_monitor_instance *monitor; 02671 enum ast_cc_monitor_policies monitor_policy; 02672 int core_id; 02673 int res; 02674 char device_name[AST_CHANNEL_NAME]; 02675 char dialstring[AST_CHANNEL_NAME]; 02676 02677 pvt = pri->pvts[chanpos]; 02678 02679 core_id = ast_cc_get_current_core_id(pvt->owner); 02680 if (core_id == -1) { 02681 return -1; 02682 } 02683 02684 cc_params = ast_channel_get_cc_config_params(pvt->owner); 02685 if (!cc_params) { 02686 return -1; 02687 } 02688 02689 res = -1; 02690 monitor_policy = ast_get_cc_monitor_policy(cc_params); 02691 switch (monitor_policy) { 02692 case AST_CC_MONITOR_NEVER: 02693 /* CCSS is not enabled. */ 02694 break; 02695 case AST_CC_MONITOR_NATIVE: 02696 case AST_CC_MONITOR_ALWAYS: 02697 /* 02698 * If it is AST_CC_MONITOR_ALWAYS and native fails we will attempt the fallback 02699 * later in the call to sig_pri_cc_generic_check(). 02700 */ 02701 ast_channel_get_device_name(pvt->owner, device_name, sizeof(device_name)); 02702 sig_pri_make_cc_dialstring(pvt, dialstring, sizeof(dialstring)); 02703 monitor = sig_pri_cc_monitor_instance_init(core_id, pri, cc_id, device_name); 02704 if (!monitor) { 02705 break; 02706 } 02707 res = ast_queue_cc_frame(pvt->owner, sig_pri_cc_type_name, dialstring, service, 02708 monitor); 02709 if (res) { 02710 monitor->cc_id = -1; 02711 ao2_unlink(sig_pri_cc_monitors, monitor); 02712 ao2_ref(monitor, -1); 02713 } 02714 break; 02715 case AST_CC_MONITOR_GENERIC: 02716 ast_queue_cc_frame(pvt->owner, AST_CC_GENERIC_MONITOR_TYPE, 02717 sig_pri_get_orig_dialstring(pvt), service, NULL); 02718 /* Say it failed to force caller to cancel native CC. */ 02719 break; 02720 } 02721 return res; 02722 }
static void sig_pri_cc_generic_check | ( | struct sig_pri_span * | pri, | |
int | chanpos, | |||
enum ast_cc_service_type | service | |||
) | [static] |
Definition at line 2739 of file sig_pri.c.
References ao2_ref, AST_CC_GENERIC_MONITOR_TYPE, ast_cc_get_current_core_id(), ast_cc_get_monitor_by_recall_core_id(), AST_CC_MONITOR_ALWAYS, AST_CC_MONITOR_GENERIC, AST_CC_MONITOR_NATIVE, AST_CC_MONITOR_NEVER, ast_channel_get_cc_config_params(), ast_channel_get_device_name(), AST_CHANNEL_NAME, ast_channel_unlock, ast_get_cc_monitor_policy(), ast_queue_cc_frame(), ast_cc_monitor::core_id, monitor, sig_pri_span::nodetype, sig_pri_chan::outgoing, sig_pri_chan::owner, sig_pri_span::pvts, sig_pri_span::sig, SIG_BRI_PTMP, sig_pri_get_orig_dialstring(), and sig_pri_lock_owner().
02740 { 02741 struct ast_channel *owner; 02742 struct ast_cc_config_params *cc_params; 02743 #if defined(HAVE_PRI_CCSS) 02744 struct ast_cc_monitor *monitor; 02745 char device_name[AST_CHANNEL_NAME]; 02746 #endif /* defined(HAVE_PRI_CCSS) */ 02747 enum ast_cc_monitor_policies monitor_policy; 02748 int core_id; 02749 02750 if (!pri->pvts[chanpos]->outgoing) { 02751 /* This is not an outgoing call so it cannot be CC monitor. */ 02752 return; 02753 } 02754 02755 sig_pri_lock_owner(pri, chanpos); 02756 owner = pri->pvts[chanpos]->owner; 02757 if (!owner) { 02758 return; 02759 } 02760 core_id = ast_cc_get_current_core_id(owner); 02761 if (core_id == -1) { 02762 /* No CC core setup */ 02763 goto done; 02764 } 02765 02766 cc_params = ast_channel_get_cc_config_params(owner); 02767 if (!cc_params) { 02768 /* Could not get CC config parameters. */ 02769 goto done; 02770 } 02771 02772 #if defined(HAVE_PRI_CCSS) 02773 ast_channel_get_device_name(owner, device_name, sizeof(device_name)); 02774 monitor = ast_cc_get_monitor_by_recall_core_id(core_id, device_name); 02775 if (monitor) { 02776 /* CC monitor is already present so no need for generic CC. */ 02777 ao2_ref(monitor, -1); 02778 goto done; 02779 } 02780 #endif /* defined(HAVE_PRI_CCSS) */ 02781 02782 monitor_policy = ast_get_cc_monitor_policy(cc_params); 02783 switch (monitor_policy) { 02784 case AST_CC_MONITOR_NEVER: 02785 /* CCSS is not enabled. */ 02786 break; 02787 case AST_CC_MONITOR_NATIVE: 02788 if (pri->sig == SIG_BRI_PTMP && pri->nodetype == PRI_NETWORK) { 02789 /* Request generic CC monitor. */ 02790 ast_queue_cc_frame(owner, AST_CC_GENERIC_MONITOR_TYPE, 02791 sig_pri_get_orig_dialstring(pri->pvts[chanpos]), service, NULL); 02792 } 02793 break; 02794 case AST_CC_MONITOR_ALWAYS: 02795 if (pri->sig == SIG_BRI_PTMP && pri->nodetype != PRI_NETWORK) { 02796 /* 02797 * Cannot monitor PTMP TE side since this is not defined. 02798 * We are playing the roll of a phone in this case and 02799 * a phone cannot monitor a party over the network without 02800 * protocol help. 02801 */ 02802 break; 02803 } 02804 /* 02805 * We are either falling back or this is a PTMP NT span. 02806 * Request generic CC monitor. 02807 */ 02808 ast_queue_cc_frame(owner, AST_CC_GENERIC_MONITOR_TYPE, 02809 sig_pri_get_orig_dialstring(pri->pvts[chanpos]), service, NULL); 02810 break; 02811 case AST_CC_MONITOR_GENERIC: 02812 if (pri->sig == SIG_BRI_PTMP && pri->nodetype == PRI_NETWORK) { 02813 /* Request generic CC monitor. */ 02814 ast_queue_cc_frame(owner, AST_CC_GENERIC_MONITOR_TYPE, 02815 sig_pri_get_orig_dialstring(pri->pvts[chanpos]), service, NULL); 02816 } 02817 break; 02818 } 02819 02820 done: 02821 ast_channel_unlock(owner); 02822 }
static void sig_pri_cc_link_canceled | ( | struct sig_pri_span * | pri, | |
long | cc_id, | |||
int | is_agent | |||
) | [static] |
Definition at line 2836 of file sig_pri.c.
References ao2_ref, ast_cc_failed(), ast_cc_monitor_failed(), ast_cc_agent::core_id, monitor, sig_pri_cc_monitor_instance::pri, sig_pri_cc_type_name, sig_pri_find_cc_agent_by_cc_id(), and sig_pri_find_cc_monitor_by_cc_id().
Referenced by sig_pri_handle_cis_subcmds(), and sig_pri_handle_subcmds().
02837 { 02838 if (is_agent) { 02839 struct ast_cc_agent *agent; 02840 02841 agent = sig_pri_find_cc_agent_by_cc_id(pri, cc_id); 02842 if (!agent) { 02843 return; 02844 } 02845 ast_cc_failed(agent->core_id, "%s agent got canceled by link", 02846 sig_pri_cc_type_name); 02847 ao2_ref(agent, -1); 02848 } else { 02849 struct sig_pri_cc_monitor_instance *monitor; 02850 02851 monitor = sig_pri_find_cc_monitor_by_cc_id(pri, cc_id); 02852 if (!monitor) { 02853 return; 02854 } 02855 monitor->cc_id = -1; 02856 ast_cc_monitor_failed(monitor->core_id, monitor->name, 02857 "%s monitor got canceled by link", sig_pri_cc_type_name); 02858 ao2_ref(monitor, -1); 02859 } 02860 }
int sig_pri_cc_monitor_cancel_available_timer | ( | struct ast_cc_monitor * | monitor, | |
int * | sched_id | |||
) |
Cancel the running available timer.
monitor | CC core monitor control. | |
sched_id | Available timer scheduler id to cancel. Will never be NULL for a device monitor. |
0 | on success | |
-1 | on failure. |
Definition at line 8607 of file sig_pri.c.
08608 { 08609 /* 08610 * libpri maintains it's own available timer as one of: 08611 * T_CCBS2/T_CCBS5/T_CCBS6/QSIG_CCBS_T2 08612 * T_CCNR2/T_CCNR5/T_CCNR6/QSIG_CCNR_T2 08613 */ 08614 return 0; 08615 }
static int sig_pri_cc_monitor_cmp_cc_id | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 2542 of file sig_pri.c.
References sig_pri_cc_monitor_instance::cc_id, CMP_MATCH, CMP_STOP, and sig_pri_cc_monitor_instance::pri.
Referenced by sig_pri_find_cc_monitor_by_cc_id().
02543 { 02544 struct sig_pri_cc_monitor_instance *monitor_1 = obj; 02545 struct sig_pri_cc_monitor_instance *monitor_2 = arg; 02546 02547 return (monitor_1->pri == monitor_2->pri 02548 && monitor_1->cc_id == monitor_2->cc_id) ? CMP_MATCH | CMP_STOP : 0; 02549 }
void sig_pri_cc_monitor_destructor | ( | void * | monitor_pvt | ) |
Destroy PRI private data on the monitor.
monitor_pvt | CC device monitor private data pointer. |
Definition at line 8630 of file sig_pri.c.
References ao2_ref, ao2_unlink, and sig_pri_cc_monitors.
08631 { 08632 struct sig_pri_cc_monitor_instance *instance; 08633 08634 instance = monitor_pvt; 08635 if (!instance) { 08636 return; 08637 } 08638 ao2_unlink(sig_pri_cc_monitors, instance); 08639 ao2_ref(instance, -1); 08640 }
static int sig_pri_cc_monitor_instance_cmp_fn | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 8435 of file sig_pri.c.
References CMP_MATCH, CMP_STOP, and sig_pri_cc_monitor_instance::core_id.
Referenced by sig_pri_load().
08436 { 08437 struct sig_pri_cc_monitor_instance *monitor_1 = obj; 08438 struct sig_pri_cc_monitor_instance *monitor_2 = arg; 08439 08440 return monitor_1->core_id == monitor_2->core_id ? CMP_MATCH | CMP_STOP : 0; 08441 }
static void sig_pri_cc_monitor_instance_destroy | ( | void * | data | ) | [static] |
Definition at line 2590 of file sig_pri.c.
References ast_mutex_lock, ast_mutex_unlock, sig_pri_span::calls, sig_pri_cc_monitor_instance::cc_id, sig_pri_span::lock, sig_pri_callback::module_unref, sig_pri_span::pri, and sig_pri_cc_monitor_instance::pri.
Referenced by sig_pri_cc_monitor_instance_init().
02591 { 02592 struct sig_pri_cc_monitor_instance *monitor_instance = data; 02593 02594 if (monitor_instance->cc_id != -1) { 02595 ast_mutex_lock(&monitor_instance->pri->lock); 02596 pri_cc_cancel(monitor_instance->pri->pri, monitor_instance->cc_id); 02597 ast_mutex_unlock(&monitor_instance->pri->lock); 02598 } 02599 monitor_instance->pri->calls->module_unref(); 02600 }
static int sig_pri_cc_monitor_instance_hash_fn | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 8415 of file sig_pri.c.
References sig_pri_cc_monitor_instance::core_id.
Referenced by sig_pri_load().
08416 { 08417 const struct sig_pri_cc_monitor_instance *monitor_instance = obj; 08418 08419 return monitor_instance->core_id; 08420 }
static struct sig_pri_cc_monitor_instance* sig_pri_cc_monitor_instance_init | ( | int | core_id, | |
struct sig_pri_span * | pri, | |||
long | cc_id, | |||
const char * | device_name | |||
) | [static] |
Definition at line 2622 of file sig_pri.c.
References ao2_alloc, ao2_link, sig_pri_span::calls, sig_pri_callback::module_ref, sig_pri_callback::module_unref, sig_pri_cc_monitor_instance::pri, sig_pri_cc_monitor_instance_destroy(), and sig_pri_cc_monitors.
Referenced by sig_pri_cc_available().
02623 { 02624 struct sig_pri_cc_monitor_instance *monitor_instance; 02625 02626 if (!pri->calls->module_ref || !pri->calls->module_unref) { 02627 return NULL; 02628 } 02629 02630 monitor_instance = ao2_alloc(sizeof(*monitor_instance) + strlen(device_name), 02631 sig_pri_cc_monitor_instance_destroy); 02632 if (!monitor_instance) { 02633 return NULL; 02634 } 02635 02636 monitor_instance->cc_id = cc_id; 02637 monitor_instance->pri = pri; 02638 monitor_instance->core_id = core_id; 02639 strcpy(monitor_instance->name, device_name); 02640 02641 pri->calls->module_ref(); 02642 02643 ao2_link(sig_pri_cc_monitors, monitor_instance); 02644 return monitor_instance; 02645 }
int sig_pri_cc_monitor_req_cc | ( | struct ast_cc_monitor * | monitor, | |
int * | available_timer_id | |||
) |
Request CCSS.
monitor | CC core monitor control. | |
available_timer_id | Where to put the available timer scheduler id. Will never be NULL for a device monitor. |
0 | on success | |
-1 | on failure. |
Definition at line 8463 of file sig_pri.c.
References AST_CC_CCBS, AST_CC_CCNR, ast_mutex_lock, ast_mutex_unlock, sig_pri_cc_monitor_instance::cc_id, sig_pri_span::lock, monitor, sig_pri_cc_monitor_instance::pri, and sig_pri_span::pri.
08464 { 08465 struct sig_pri_cc_monitor_instance *instance; 08466 int cc_mode; 08467 int res; 08468 08469 switch (monitor->service_offered) { 08470 case AST_CC_CCBS: 08471 cc_mode = 0;/* CCBS */ 08472 break; 08473 case AST_CC_CCNR: 08474 cc_mode = 1;/* CCNR */ 08475 break; 08476 default: 08477 /* CC service not supported by ISDN. */ 08478 return -1; 08479 } 08480 08481 instance = monitor->private_data; 08482 08483 /* libpri handles it's own available timer. */ 08484 ast_mutex_lock(&instance->pri->lock); 08485 res = pri_cc_req(instance->pri->pri, instance->cc_id, cc_mode); 08486 ast_mutex_unlock(&instance->pri->lock); 08487 08488 return res; 08489 }
int sig_pri_cc_monitor_status_rsp | ( | struct ast_cc_monitor * | monitor, | |
enum ast_device_state | devstate | |||
) |
Status response to an ast_cc_monitor_status_request().
monitor | CC core monitor control. | |
devstate | Current status of a Party A device. |
0 | on success | |
-1 | on failure. |
Definition at line 8562 of file sig_pri.c.
References AST_DEVICE_BUSY, AST_DEVICE_INUSE, AST_DEVICE_NOT_INUSE, AST_DEVICE_UNKNOWN, ast_mutex_lock, ast_mutex_unlock, sig_pri_cc_monitor_instance::cc_id, sig_pri_span::lock, monitor, sig_pri_cc_monitor_instance::pri, and sig_pri_span::pri.
08563 { 08564 struct sig_pri_cc_monitor_instance *instance; 08565 int cc_status; 08566 08567 switch (devstate) { 08568 case AST_DEVICE_UNKNOWN: 08569 case AST_DEVICE_NOT_INUSE: 08570 cc_status = 0;/* free */ 08571 break; 08572 case AST_DEVICE_BUSY: 08573 case AST_DEVICE_INUSE: 08574 cc_status = 1;/* busy */ 08575 break; 08576 default: 08577 /* Don't know how to interpret this device state into free/busy status. */ 08578 return 0; 08579 } 08580 instance = monitor->private_data; 08581 ast_mutex_lock(&instance->pri->lock); 08582 pri_cc_status_req_rsp(instance->pri->pri, instance->cc_id, cc_status); 08583 ast_mutex_unlock(&instance->pri->lock); 08584 08585 return 0; 08586 }
int sig_pri_cc_monitor_suspend | ( | struct ast_cc_monitor * | monitor | ) |
Suspend monitoring.
monitor | CC core monitor control. |
0 | on success | |
-1 | on failure. |
Definition at line 8506 of file sig_pri.c.
References ast_mutex_lock, ast_mutex_unlock, sig_pri_cc_monitor_instance::cc_id, sig_pri_span::lock, monitor, sig_pri_cc_monitor_instance::pri, and sig_pri_span::pri.
08507 { 08508 struct sig_pri_cc_monitor_instance *instance; 08509 08510 instance = monitor->private_data; 08511 ast_mutex_lock(&instance->pri->lock); 08512 pri_cc_status(instance->pri->pri, instance->cc_id, 1/* busy */); 08513 ast_mutex_unlock(&instance->pri->lock); 08514 08515 return 0; 08516 }
int sig_pri_cc_monitor_unsuspend | ( | struct ast_cc_monitor * | monitor | ) |
Unsuspend monitoring.
monitor | CC core monitor control. |
0 | on success | |
-1 | on failure. |
Definition at line 8532 of file sig_pri.c.
References ast_mutex_lock, ast_mutex_unlock, sig_pri_cc_monitor_instance::cc_id, sig_pri_span::lock, monitor, sig_pri_cc_monitor_instance::pri, and sig_pri_span::pri.
08533 { 08534 struct sig_pri_cc_monitor_instance *instance; 08535 08536 instance = monitor->private_data; 08537 ast_mutex_lock(&instance->pri->lock); 08538 pri_cc_status(instance->pri->pri, instance->cc_id, 0/* free */); 08539 ast_mutex_unlock(&instance->pri->lock); 08540 08541 return 0; 08542 }
void sig_pri_chan_alarm_notify | ( | struct sig_pri_chan * | p, | |
int | noalarm | |||
) |
Notify new alarm status.
p | Channel private pointer. | |
noalarm | Non-zero if not in alarm mode. |
Definition at line 7816 of file sig_pri.c.
References ast_channel::_softhangup, AST_SOFTHANGUP_DEV, sig_pri_chan::call, sig_pri_chan::owner, sig_pri_chan::pri, sig_pri_span::pri, pri_grab(), pri_rel(), sig_pri_set_alarm(), and sig_pri_span_devstate_changed().
Referenced by dahdi_handle_event(), and handle_init_event().
07817 { 07818 pri_grab(p, p->pri); 07819 sig_pri_set_alarm(p, !noalarm); 07820 if (!noalarm) { 07821 if (pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0) { 07822 /* T309 is not enabled : destroy calls when alarm occurs */ 07823 if (p->call) { 07824 pri_destroycall(p->pri->pri, p->call); 07825 p->call = NULL; 07826 } 07827 if (p->owner) 07828 p->owner->_softhangup |= AST_SOFTHANGUP_DEV; 07829 } 07830 } 07831 sig_pri_span_devstate_changed(p->pri); 07832 pri_rel(p->pri); 07833 }
void sig_pri_chan_delete | ( | struct sig_pri_chan * | doomed | ) |
Delete the sig_pri private channel structure.
doomed | sig_pri private channel structure to delete. |
Definition at line 7875 of file sig_pri.c.
References ast_free.
Referenced by destroy_dahdi_pvt().
07876 { 07877 ast_free(doomed); 07878 }
struct sig_pri_chan* sig_pri_chan_new | ( | void * | pvt_data, | |
struct sig_pri_callback * | callback, | |||
struct sig_pri_span * | pri, | |||
int | logicalspan, | |||
int | channo, | |||
int | trunkgroup | |||
) |
Definition at line 7847 of file sig_pri.c.
References ast_calloc, and sig_pri_chan::pri.
07848 { 07849 struct sig_pri_chan *p; 07850 07851 p = ast_calloc(1, sizeof(*p)); 07852 if (!p) 07853 return p; 07854 07855 p->logicalspan = logicalspan; 07856 p->prioffset = channo; 07857 p->mastertrunkgroup = trunkgroup; 07858 07859 p->calls = callback; 07860 p->chan_pvt = pvt_data; 07861 07862 p->pri = pri; 07863 07864 return p; 07865 }
void sig_pri_cli_show_channels | ( | int | fd, | |
struct sig_pri_span * | pri | |||
) |
Definition at line 7888 of file sig_pri.c.
References ast_channel_unlock, ast_cli(), ast_mutex_lock, ast_mutex_unlock, sig_pri_chan::call, sig_pri_chan::call_level, sig_pri_chan::channel, sig_pri_span::lock, ast_channel::name, sig_pri_chan::no_b_channel, sig_pri_span::numchans, sig_pri_chan::owner, sig_pri_chan::pri, sig_pri_span::pvts, sig_pri_call_level2str(), sig_pri_is_chan_available(), sig_pri_lock_owner(), sig_pri_lock_private(), SIG_PRI_SC_LINE, sig_pri_unlock_private(), and sig_pri_span::span.
Referenced by handle_pri_show_channels().
07889 { 07890 char line[256]; 07891 int idx; 07892 struct sig_pri_chan *pvt; 07893 07894 ast_mutex_lock(&pri->lock); 07895 for (idx = 0; idx < pri->numchans; ++idx) { 07896 if (!pri->pvts[idx]) { 07897 continue; 07898 } 07899 pvt = pri->pvts[idx]; 07900 sig_pri_lock_private(pvt); 07901 sig_pri_lock_owner(pri, idx); 07902 if (pvt->no_b_channel && sig_pri_is_chan_available(pvt)) { 07903 /* Don't show held/call-waiting channels if they are not in use. */ 07904 sig_pri_unlock_private(pvt); 07905 continue; 07906 } 07907 07908 snprintf(line, sizeof(line), SIG_PRI_SC_LINE, 07909 pri->span, 07910 pvt->channel, 07911 pvt->no_b_channel ? "No" : "Yes",/* Has media */ 07912 sig_pri_is_chan_available(pvt) ? "Yes" : "No", 07913 sig_pri_call_level2str(pvt->call_level), 07914 pvt->call ? "Yes" : "No", 07915 pvt->owner ? pvt->owner->name : ""); 07916 07917 if (pvt->owner) { 07918 ast_channel_unlock(pvt->owner); 07919 } 07920 sig_pri_unlock_private(pvt); 07921 07922 ast_mutex_unlock(&pri->lock); 07923 ast_cli(fd, "%s\n", line); 07924 ast_mutex_lock(&pri->lock); 07925 } 07926 ast_mutex_unlock(&pri->lock); 07927 }
void sig_pri_cli_show_channels_header | ( | int | fd | ) |
Definition at line 7882 of file sig_pri.c.
References ast_cli(), and SIG_PRI_SC_HEADER.
Referenced by handle_pri_show_channels().
07883 { 07884 ast_cli(fd, SIG_PRI_SC_HEADER, "PRI", "", "B", "Chan", "Call", "PRI", "Channel"); 07885 ast_cli(fd, SIG_PRI_SC_HEADER, "Span", "Chan", "Chan", "Idle", "Level", "Call", "Name"); 07886 }
void sig_pri_cli_show_span | ( | int | fd, | |
int * | dchannels, | |||
struct sig_pri_span * | pri | |||
) |
Definition at line 7960 of file sig_pri.c.
References ast_cli(), ast_mutex_lock, ast_mutex_unlock, build_status(), DAHDI_OVERLAPDIAL_INCOMING, sig_pri_span::dchanavail, sig_pri_span::dchans, free, sig_pri_span::lock, sig_pri_span::overlapdial, sig_pri_chan::pri, sig_pri_span::pri, pri_order(), and status.
Referenced by handle_pri_show_span().
07961 { 07962 int x; 07963 char status[256]; 07964 07965 for (x = 0; x < SIG_PRI_NUM_DCHANS; x++) { 07966 if (pri->dchans[x]) { 07967 #ifdef PRI_DUMP_INFO_STR 07968 char *info_str = NULL; 07969 #endif 07970 ast_cli(fd, "%s D-channel: %d\n", pri_order(x), dchannels[x]); 07971 build_status(status, sizeof(status), pri->dchanavail[x], pri->dchans[x] == pri->pri); 07972 ast_cli(fd, "Status: %s\n", status); 07973 ast_mutex_lock(&pri->lock); 07974 #ifdef PRI_DUMP_INFO_STR 07975 info_str = pri_dump_info_str(pri->pri); 07976 if (info_str) { 07977 ast_cli(fd, "%s", info_str); 07978 free(info_str); 07979 } 07980 #else 07981 pri_dump_info(pri->pri); 07982 #endif 07983 ast_mutex_unlock(&pri->lock); 07984 ast_cli(fd, "Overlap Recv: %s\n\n", (pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)?"Yes":"No"); 07985 ast_cli(fd, "\n"); 07986 } 07987 } 07988 }
void sig_pri_cli_show_spans | ( | int | fd, | |
int | span, | |||
struct sig_pri_span * | pri | |||
) |
Definition at line 7948 of file sig_pri.c.
References ast_cli(), build_status(), sig_pri_span::dchanavail, sig_pri_span::dchans, sig_pri_chan::pri, sig_pri_span::pri, and status.
Referenced by handle_pri_show_spans().
07949 { 07950 char status[256]; 07951 int x; 07952 for (x = 0; x < SIG_PRI_NUM_DCHANS; x++) { 07953 if (pri->dchans[x]) { 07954 build_status(status, sizeof(status), pri->dchanavail[x], pri->dchans[x] == pri->pri); 07955 ast_cli(fd, "PRI span %d/%d: %s\n", span, x, status); 07956 } 07957 } 07958 }
static int sig_pri_cmp_pri_chans | ( | const void * | left, | |
const void * | right | |||
) | [static] |
Definition at line 7587 of file sig_pri.c.
References sig_pri_chan::channel.
Referenced by sig_pri_sort_pri_chans().
07588 { 07589 const struct sig_pri_chan *pvt_left; 07590 const struct sig_pri_chan *pvt_right; 07591 07592 pvt_left = *(struct sig_pri_chan **) left; 07593 pvt_right = *(struct sig_pri_chan **) right; 07594 if (!pvt_left) { 07595 if (!pvt_right) { 07596 return 0; 07597 } 07598 return 1; 07599 } 07600 if (!pvt_right) { 07601 return -1; 07602 } 07603 07604 return pvt_left->channel - pvt_right->channel; 07605 }
static struct sig_pri_chan* sig_pri_cw_available | ( | struct sig_pri_span * | pri | ) | [static] |
Definition at line 7301 of file sig_pri.c.
References ast_atomic_fetchadd_int(), sig_pri_chan::is_call_waiting, sig_pri_span::max_call_waiting_calls, sig_pri_span::num_call_waiting_calls, sig_pri_span::numchans, sig_pri_chan::pri, pri_find_empty_nobch(), sig_pri_span::pvts, sig_pri_available_check(), and sig_pri_init_config().
Referenced by sig_pri_available().
07302 { 07303 struct sig_pri_chan *cw; 07304 int idx; 07305 07306 cw = NULL; 07307 if (pri->num_call_waiting_calls < pri->max_call_waiting_calls) { 07308 if (!pri->num_call_waiting_calls) { 07309 /* 07310 * There are no outstanding call waiting calls. Check to see 07311 * if the span is in a congested state for the first call 07312 * waiting call. 07313 */ 07314 for (idx = 0; idx < pri->numchans; ++idx) { 07315 if (pri->pvts[idx] && sig_pri_available_check(pri->pvts[idx])) { 07316 /* There is another channel that is available on this span. */ 07317 return cw; 07318 } 07319 } 07320 } 07321 idx = pri_find_empty_nobch(pri); 07322 if (0 <= idx) { 07323 /* Setup the call waiting interface to use. */ 07324 cw = pri->pvts[idx]; 07325 cw->is_call_waiting = 1; 07326 sig_pri_init_config(cw, pri); 07327 ast_atomic_fetchadd_int(&pri->num_call_waiting_calls, 1); 07328 } 07329 } 07330 return cw; 07331 }
void sig_pri_dial_complete | ( | struct sig_pri_chan * | pvt, | |
struct ast_channel * | ast | |||
) |
DTMF dial string complete.
pvt | sig_pri private channel structure. | |
ast | Asterisk channel |
Definition at line 7428 of file sig_pri.c.
References AST_CONTROL_ANSWER, AST_FRAME_CONTROL, ast_queue_frame(), sig_pri_chan::call_level, sig_pri_chan::calls, sig_pri_chan::chan_pvt, f, sig_pri_callback::queue_control, SIG_PRI_CALL_LEVEL_CONNECT, SIG_PRI_CALL_LEVEL_DEFER_DIAL, sig_pri_open_media(), sig_pri_set_dialing(), and sig_pri_set_echocanceller().
Referenced by dahdi_handle_event().
07429 { 07430 /* If we just completed 'w' deferred dialing digits, we need to answer now. */ 07431 if (pvt->call_level == SIG_PRI_CALL_LEVEL_DEFER_DIAL) { 07432 pvt->call_level = SIG_PRI_CALL_LEVEL_CONNECT; 07433 07434 sig_pri_open_media(pvt); 07435 { 07436 struct ast_frame f = {AST_FRAME_CONTROL, }; 07437 07438 if (pvt->calls->queue_control) { 07439 pvt->calls->queue_control(pvt->chan_pvt, AST_CONTROL_ANSWER); 07440 } 07441 07442 f.subclass.integer = AST_CONTROL_ANSWER; 07443 ast_queue_frame(ast, &f); 07444 } 07445 sig_pri_set_dialing(pvt, 0); 07446 /* Enable echo cancellation if it's not on already */ 07447 sig_pri_set_echocanceller(pvt, 1); 07448 } 07449 }
static void sig_pri_dial_digits | ( | struct sig_pri_chan * | p, | |
const char * | dial_string | |||
) | [static] |
Definition at line 228 of file sig_pri.c.
References sig_pri_chan::calls, sig_pri_chan::chan_pvt, and sig_pri_callback::dial_digits.
00229 { 00230 if (p->calls->dial_digits) { 00231 p->calls->dial_digits(p->chan_pvt, dial_string); 00232 } 00233 }
int sig_pri_digit_begin | ( | struct sig_pri_chan * | pvt, | |
struct ast_channel * | ast, | |||
char | digit | |||
) |
Definition at line 7382 of file sig_pri.c.
References ast_channel::_state, ast_debug, ast_log(), AST_STATE_DIALING, sig_pri_chan::call_level, sig_pri_chan::dialdest, LOG_WARNING, sig_pri_chan::pri, pri_grab(), pri_rel(), sig_pri_call_level2str(), SIG_PRI_CALL_LEVEL_CONNECT, SIG_PRI_CALL_LEVEL_OVERLAP, SIG_PRI_CALL_LEVEL_PROCEEDING, and sig_pri_span::span.
Referenced by dahdi_digit_begin().
07383 { 07384 if (ast->_state == AST_STATE_DIALING) { 07385 if (pvt->call_level < SIG_PRI_CALL_LEVEL_OVERLAP) { 07386 unsigned int len; 07387 07388 len = strlen(pvt->dialdest); 07389 if (len < sizeof(pvt->dialdest) - 1) { 07390 ast_debug(1, "Queueing digit '%c' since setup_ack not yet received\n", 07391 digit); 07392 pvt->dialdest[len++] = digit; 07393 pvt->dialdest[len] = '\0'; 07394 } else { 07395 ast_log(LOG_WARNING, 07396 "Span %d: Deferred digit buffer overflow for digit '%c'.\n", 07397 pvt->pri->span, digit); 07398 } 07399 return 0; 07400 } 07401 if (pvt->call_level < SIG_PRI_CALL_LEVEL_PROCEEDING) { 07402 pri_grab(pvt, pvt->pri); 07403 pri_information(pvt->pri->pri, pvt->call, digit); 07404 pri_rel(pvt->pri); 07405 return 0; 07406 } 07407 if (pvt->call_level < SIG_PRI_CALL_LEVEL_CONNECT) { 07408 ast_log(LOG_WARNING, 07409 "Span %d: Digit '%c' may be ignored by peer. (Call level:%d(%s))\n", 07410 pvt->pri->span, digit, pvt->call_level, 07411 sig_pri_call_level2str(pvt->call_level)); 07412 } 07413 } 07414 return 1; 07415 }
static void sig_pri_dsp_reset_and_flush_digits | ( | struct sig_pri_chan * | p | ) | [static] |
Definition at line 913 of file sig_pri.c.
References sig_pri_chan::calls, sig_pri_chan::chan_pvt, and sig_pri_callback::dsp_reset_and_flush_digits.
Referenced by pri_ss_thread().
00914 { 00915 if (p->calls->dsp_reset_and_flush_digits) { 00916 p->calls->dsp_reset_and_flush_digits(p->chan_pvt); 00917 } 00918 }
static void sig_pri_event_party_id | ( | struct ast_str ** | msg, | |
const char * | prefix, | |||
struct ast_party_id * | party | |||
) | [static] |
Definition at line 2165 of file sig_pri.c.
References ast_describe_caller_presentation(), ast_party_id_presentation(), ast_party_name_charset_describe(), ast_str_append(), ast_party_name::char_set, ast_party_id::name, ast_party_id::number, ast_party_subaddress::odd_even_indicator, ast_party_number::plan, ast_party_name::presentation, ast_party_number::presentation, S_COR, S_OR, ast_party_subaddress::str, ast_party_name::str, ast_party_number::str, ast_party_id::subaddress, ast_party_subaddress::type, ast_party_subaddress::valid, ast_party_name::valid, and ast_party_number::valid.
Referenced by sig_pri_mcid_event().
02166 { 02167 int pres; 02168 02169 /* Combined party presentation */ 02170 pres = ast_party_id_presentation(party); 02171 ast_str_append(msg, 0, "%sPres: %d (%s)\r\n", prefix, pres, 02172 ast_describe_caller_presentation(pres)); 02173 02174 /* Party number */ 02175 ast_str_append(msg, 0, "%sNumValid: %d\r\n", prefix, 02176 (unsigned) party->number.valid); 02177 ast_str_append(msg, 0, "%sNum: %s\r\n", prefix, 02178 S_COR(party->number.valid, party->number.str, "")); 02179 ast_str_append(msg, 0, "%ston: %d\r\n", prefix, party->number.plan); 02180 if (party->number.valid) { 02181 ast_str_append(msg, 0, "%sNumPlan: %d\r\n", prefix, party->number.plan); 02182 ast_str_append(msg, 0, "%sNumPres: %d (%s)\r\n", prefix, 02183 party->number.presentation, 02184 ast_describe_caller_presentation(party->number.presentation)); 02185 } 02186 02187 /* Party name */ 02188 ast_str_append(msg, 0, "%sNameValid: %d\r\n", prefix, 02189 (unsigned) party->name.valid); 02190 ast_str_append(msg, 0, "%sName: %s\r\n", prefix, 02191 S_COR(party->name.valid, party->name.str, "")); 02192 if (party->name.valid) { 02193 ast_str_append(msg, 0, "%sNameCharSet: %s\r\n", prefix, 02194 ast_party_name_charset_describe(party->name.char_set)); 02195 ast_str_append(msg, 0, "%sNamePres: %d (%s)\r\n", prefix, 02196 party->name.presentation, 02197 ast_describe_caller_presentation(party->name.presentation)); 02198 } 02199 02200 #if defined(HAVE_PRI_SUBADDR) 02201 /* Party subaddress */ 02202 if (party->subaddress.valid) { 02203 static const char subaddress[] = "Subaddr"; 02204 02205 ast_str_append(msg, 0, "%s%s: %s\r\n", prefix, subaddress, 02206 S_OR(party->subaddress.str, "")); 02207 ast_str_append(msg, 0, "%s%sType: %d\r\n", prefix, subaddress, 02208 party->subaddress.type); 02209 ast_str_append(msg, 0, "%s%sOdd: %d\r\n", prefix, subaddress, 02210 party->subaddress.odd_even_indicator); 02211 } 02212 #endif /* defined(HAVE_PRI_SUBADDR) */ 02213 }
void sig_pri_extract_called_num_subaddr | ( | struct sig_pri_chan * | p, | |
const char * | rdest, | |||
char * | called, | |||
size_t | called_buff_size | |||
) |
Extract the called number and subaddress from the dial string.
p | sig_pri channel structure. | |
rdest | Dial string buffer to extract called number and subaddress. | |
called | Buffer to fill with extracted <number>[:<subaddress>] | |
called_buff_size | Size of buffer to fill. |
Definition at line 6478 of file sig_pri.c.
References args, AST_APP_ARG, AST_DECLARE_APP_ARGS, AST_NONSTANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), ext, and sig_pri_chan::stripmsd.
Referenced by dahdi_request().
06479 { 06480 char *dial; 06481 char *number; 06482 char *subaddr; 06483 AST_DECLARE_APP_ARGS(args, 06484 AST_APP_ARG(group); /* channel/group token */ 06485 AST_APP_ARG(ext); /* extension token */ 06486 //AST_APP_ARG(opts); /* options token */ 06487 AST_APP_ARG(other); /* Any remining unused arguments */ 06488 ); 06489 06490 /* Get private copy of dial string and break it up. */ 06491 dial = ast_strdupa(rdest); 06492 AST_NONSTANDARD_APP_ARGS(args, dial, '/'); 06493 06494 number = args.ext; 06495 if (!number) { 06496 number = ""; 06497 } 06498 06499 /* Find and extract dialed_subaddress */ 06500 subaddr = strchr(number, ':'); 06501 if (subaddr) { 06502 *subaddr++ = '\0'; 06503 06504 /* Skip subaddress type prefix. */ 06505 switch (*subaddr) { 06506 case 'U': 06507 case 'u': 06508 case 'N': 06509 case 'n': 06510 ++subaddr; 06511 break; 06512 default: 06513 break; 06514 } 06515 } 06516 06517 /* Skip type-of-number/dial-plan prefix characters. */ 06518 if (strlen(number) < p->stripmsd) { 06519 number = ""; 06520 } else { 06521 char *deferred; 06522 06523 number += p->stripmsd; 06524 deferred = strchr(number, 'w'); 06525 if (deferred) { 06526 /* Remove any 'w' deferred digits. */ 06527 *deferred = '\0'; 06528 } 06529 while (isalpha(*number)) { 06530 ++number; 06531 } 06532 } 06533 06534 /* Fill buffer with extracted number and subaddress. */ 06535 if (ast_strlen_zero(subaddr)) { 06536 /* Put in called number only since there is no subaddress. */ 06537 snprintf(called, called_buff_size, "%s", number); 06538 } else { 06539 /* Put in called number and subaddress. */ 06540 snprintf(called, called_buff_size, "%s:%s", number, subaddr); 06541 } 06542 }
static struct ast_cc_agent* sig_pri_find_cc_agent_by_cc_id | ( | struct sig_pri_span * | pri, | |
long | cc_id | |||
) | [static] |
Definition at line 2518 of file sig_pri.c.
References ast_cc_agent_callback(), sig_pri_cc_agent_prv::pri, sig_pri_cc_agent_cmp_cc_id(), and sig_pri_cc_type_name.
Referenced by sig_pri_cc_link_canceled(), sig_pri_handle_cis_subcmds(), and sig_pri_handle_subcmds().
02519 { 02520 struct sig_pri_cc_agent_prv finder = { 02521 .pri = pri, 02522 .cc_id = cc_id, 02523 }; 02524 02525 return ast_cc_agent_callback(0, sig_pri_cc_agent_cmp_cc_id, &finder, 02526 sig_pri_cc_type_name); 02527 }
static struct sig_pri_cc_monitor_instance* sig_pri_find_cc_monitor_by_cc_id | ( | struct sig_pri_span * | pri, | |
long | cc_id | |||
) | [static] |
Definition at line 2569 of file sig_pri.c.
References ao2_callback, sig_pri_cc_monitor_instance::pri, sig_pri_cc_monitor_cmp_cc_id(), and sig_pri_cc_monitors.
Referenced by sig_pri_cc_link_canceled(), and sig_pri_handle_cis_subcmds().
02570 { 02571 struct sig_pri_cc_monitor_instance finder = { 02572 .pri = pri, 02573 .cc_id = cc_id, 02574 }; 02575 02576 return ao2_callback(sig_pri_cc_monitors, 0, sig_pri_cc_monitor_cmp_cc_id, &finder); 02577 }
void sig_pri_fixup | ( | struct ast_channel * | oldchan, | |
struct ast_channel * | newchan, | |||
struct sig_pri_chan * | pchan | |||
) |
static void sig_pri_fixup_chans | ( | struct sig_pri_chan * | old_chan, | |
struct sig_pri_chan * | new_chan | |||
) | [static] |
Definition at line 928 of file sig_pri.c.
References sig_pri_chan::calls, sig_pri_chan::chan_pvt, and sig_pri_callback::fixup_chans.
Referenced by pri_fixup_principle().
00929 { 00930 if (old_chan->calls->fixup_chans) 00931 old_chan->calls->fixup_chans(old_chan->chan_pvt, new_chan->chan_pvt); 00932 }
static const char* sig_pri_get_orig_dialstring | ( | struct sig_pri_chan * | p | ) | [static] |
Definition at line 207 of file sig_pri.c.
References ast_log(), sig_pri_chan::calls, sig_pri_chan::chan_pvt, sig_pri_callback::get_orig_dialstring, and LOG_ERROR.
Referenced by sig_pri_cc_available(), and sig_pri_cc_generic_check().
00208 { 00209 if (p->calls->get_orig_dialstring) { 00210 return p->calls->get_orig_dialstring(p->chan_pvt); 00211 } 00212 ast_log(LOG_ERROR, "get_orig_dialstring callback not defined\n"); 00213 return ""; 00214 }
static void sig_pri_handle_cis_subcmds | ( | struct sig_pri_span * | pri, | |
int | event_id, | |||
const struct pri_subcommands * | subcmds, | |||
q931_call * | call_rsp | |||
) | [static] |
Definition at line 3838 of file sig_pri.c.
References ao2_ref, ast_cc_agent_accept_request(), ast_cc_agent_caller_available(), ast_cc_agent_caller_busy(), ast_cc_agent_status_response(), ast_cc_failed(), ast_cc_monitor_callee_available(), ast_cc_monitor_failed(), ast_cc_monitor_party_b_free(), ast_cc_monitor_request_acked(), ast_cc_monitor_status_request(), ast_cc_monitor_stop_ringing(), ast_cc_request_is_within_limits(), ast_debug, AST_DEVICE_INUSE, AST_DEVICE_NOT_INUSE, ast_verb, sig_pri_cc_agent_prv::cc_request_response_pending, ast_cc_agent::core_id, monitor, sig_pri_span::pri, sig_pri_cc_monitor_instance::pri, ast_cc_agent::private_data, sig_pri_aoc_e_from_pri(), sig_pri_cc_link_canceled(), sig_pri_cc_type_name, sig_pri_find_cc_agent_by_cc_id(), sig_pri_find_cc_monitor_by_cc_id(), and sig_pri_span::span.
03840 { 03841 int index; 03842 #if defined(HAVE_PRI_CCSS) 03843 struct ast_cc_agent *agent; 03844 struct sig_pri_cc_agent_prv *agent_prv; 03845 struct sig_pri_cc_monitor_instance *monitor; 03846 #endif /* defined(HAVE_PRI_CCSS) */ 03847 03848 if (!subcmds) { 03849 return; 03850 } 03851 for (index = 0; index < subcmds->counter_subcmd; ++index) { 03852 const struct pri_subcommand *subcmd = &subcmds->subcmd[index]; 03853 03854 switch (subcmd->cmd) { 03855 #if defined(STATUS_REQUEST_PLACE_HOLDER) 03856 case PRI_SUBCMD_STATUS_REQ: 03857 case PRI_SUBCMD_STATUS_REQ_RSP: 03858 /* Ignore for now. */ 03859 break; 03860 #endif /* defined(STATUS_REQUEST_PLACE_HOLDER) */ 03861 #if defined(HAVE_PRI_CCSS) 03862 case PRI_SUBCMD_CC_REQ: 03863 agent = sig_pri_find_cc_agent_by_cc_id(pri, subcmd->u.cc_request.cc_id); 03864 if (!agent) { 03865 pri_cc_cancel(pri->pri, subcmd->u.cc_request.cc_id); 03866 break; 03867 } 03868 if (!ast_cc_request_is_within_limits()) { 03869 if (pri_cc_req_rsp(pri->pri, subcmd->u.cc_request.cc_id, 03870 5/* queue_full */)) { 03871 pri_cc_cancel(pri->pri, subcmd->u.cc_request.cc_id); 03872 } 03873 ast_cc_failed(agent->core_id, "%s agent system CC queue full", 03874 sig_pri_cc_type_name); 03875 ao2_ref(agent, -1); 03876 break; 03877 } 03878 agent_prv = agent->private_data; 03879 agent_prv->cc_request_response_pending = 1; 03880 if (ast_cc_agent_accept_request(agent->core_id, 03881 "%s caller accepted CC offer.", sig_pri_cc_type_name)) { 03882 agent_prv->cc_request_response_pending = 0; 03883 if (pri_cc_req_rsp(pri->pri, subcmd->u.cc_request.cc_id, 03884 2/* short_term_denial */)) { 03885 pri_cc_cancel(pri->pri, subcmd->u.cc_request.cc_id); 03886 } 03887 ast_cc_failed(agent->core_id, "%s agent CC core request accept failed", 03888 sig_pri_cc_type_name); 03889 } 03890 ao2_ref(agent, -1); 03891 break; 03892 #endif /* defined(HAVE_PRI_CCSS) */ 03893 #if defined(HAVE_PRI_CCSS) 03894 case PRI_SUBCMD_CC_REQ_RSP: 03895 monitor = sig_pri_find_cc_monitor_by_cc_id(pri, 03896 subcmd->u.cc_request_rsp.cc_id); 03897 if (!monitor) { 03898 pri_cc_cancel(pri->pri, subcmd->u.cc_request_rsp.cc_id); 03899 break; 03900 } 03901 switch (subcmd->u.cc_request_rsp.status) { 03902 case 0:/* success */ 03903 ast_cc_monitor_request_acked(monitor->core_id, 03904 "%s far end accepted CC request", sig_pri_cc_type_name); 03905 break; 03906 case 1:/* timeout */ 03907 ast_verb(2, "core_id:%d %s CC request timeout\n", monitor->core_id, 03908 sig_pri_cc_type_name); 03909 ast_cc_monitor_failed(monitor->core_id, monitor->name, 03910 "%s CC request timeout", sig_pri_cc_type_name); 03911 break; 03912 case 2:/* error */ 03913 ast_verb(2, "core_id:%d %s CC request error: %s\n", monitor->core_id, 03914 sig_pri_cc_type_name, 03915 pri_facility_error2str(subcmd->u.cc_request_rsp.fail_code)); 03916 ast_cc_monitor_failed(monitor->core_id, monitor->name, 03917 "%s CC request error", sig_pri_cc_type_name); 03918 break; 03919 case 3:/* reject */ 03920 ast_verb(2, "core_id:%d %s CC request reject: %s\n", monitor->core_id, 03921 sig_pri_cc_type_name, 03922 pri_facility_reject2str(subcmd->u.cc_request_rsp.fail_code)); 03923 ast_cc_monitor_failed(monitor->core_id, monitor->name, 03924 "%s CC request reject", sig_pri_cc_type_name); 03925 break; 03926 default: 03927 ast_verb(2, "core_id:%d %s CC request unknown status %d\n", 03928 monitor->core_id, sig_pri_cc_type_name, 03929 subcmd->u.cc_request_rsp.status); 03930 ast_cc_monitor_failed(monitor->core_id, monitor->name, 03931 "%s CC request unknown status", sig_pri_cc_type_name); 03932 break; 03933 } 03934 ao2_ref(monitor, -1); 03935 break; 03936 #endif /* defined(HAVE_PRI_CCSS) */ 03937 #if defined(HAVE_PRI_CCSS) 03938 case PRI_SUBCMD_CC_REMOTE_USER_FREE: 03939 monitor = sig_pri_find_cc_monitor_by_cc_id(pri, 03940 subcmd->u.cc_remote_user_free.cc_id); 03941 if (!monitor) { 03942 pri_cc_cancel(pri->pri, subcmd->u.cc_remote_user_free.cc_id); 03943 break; 03944 } 03945 ast_cc_monitor_callee_available(monitor->core_id, 03946 "%s callee has become available", sig_pri_cc_type_name); 03947 ao2_ref(monitor, -1); 03948 break; 03949 #endif /* defined(HAVE_PRI_CCSS) */ 03950 #if defined(HAVE_PRI_CCSS) 03951 case PRI_SUBCMD_CC_B_FREE: 03952 monitor = sig_pri_find_cc_monitor_by_cc_id(pri, 03953 subcmd->u.cc_b_free.cc_id); 03954 if (!monitor) { 03955 pri_cc_cancel(pri->pri, subcmd->u.cc_b_free.cc_id); 03956 break; 03957 } 03958 ast_cc_monitor_party_b_free(monitor->core_id); 03959 ao2_ref(monitor, -1); 03960 break; 03961 #endif /* defined(HAVE_PRI_CCSS) */ 03962 #if defined(HAVE_PRI_CCSS) 03963 case PRI_SUBCMD_CC_STATUS_REQ: 03964 monitor = sig_pri_find_cc_monitor_by_cc_id(pri, 03965 subcmd->u.cc_status_req.cc_id); 03966 if (!monitor) { 03967 pri_cc_cancel(pri->pri, subcmd->u.cc_status_req.cc_id); 03968 break; 03969 } 03970 ast_cc_monitor_status_request(monitor->core_id); 03971 ao2_ref(monitor, -1); 03972 break; 03973 #endif /* defined(HAVE_PRI_CCSS) */ 03974 #if defined(HAVE_PRI_CCSS) 03975 case PRI_SUBCMD_CC_STATUS_REQ_RSP: 03976 agent = sig_pri_find_cc_agent_by_cc_id(pri, subcmd->u.cc_status_req_rsp.cc_id); 03977 if (!agent) { 03978 pri_cc_cancel(pri->pri, subcmd->u.cc_status_req_rsp.cc_id); 03979 break; 03980 } 03981 ast_cc_agent_status_response(agent->core_id, 03982 subcmd->u.cc_status_req_rsp.status ? AST_DEVICE_INUSE 03983 : AST_DEVICE_NOT_INUSE); 03984 ao2_ref(agent, -1); 03985 break; 03986 #endif /* defined(HAVE_PRI_CCSS) */ 03987 #if defined(HAVE_PRI_CCSS) 03988 case PRI_SUBCMD_CC_STATUS: 03989 agent = sig_pri_find_cc_agent_by_cc_id(pri, subcmd->u.cc_status.cc_id); 03990 if (!agent) { 03991 pri_cc_cancel(pri->pri, subcmd->u.cc_status.cc_id); 03992 break; 03993 } 03994 if (subcmd->u.cc_status.status) { 03995 ast_cc_agent_caller_busy(agent->core_id, "%s agent caller is busy", 03996 sig_pri_cc_type_name); 03997 } else { 03998 ast_cc_agent_caller_available(agent->core_id, 03999 "%s agent caller is available", sig_pri_cc_type_name); 04000 } 04001 ao2_ref(agent, -1); 04002 break; 04003 #endif /* defined(HAVE_PRI_CCSS) */ 04004 #if defined(HAVE_PRI_CCSS) 04005 case PRI_SUBCMD_CC_CANCEL: 04006 sig_pri_cc_link_canceled(pri, subcmd->u.cc_cancel.cc_id, 04007 subcmd->u.cc_cancel.is_agent); 04008 break; 04009 #endif /* defined(HAVE_PRI_CCSS) */ 04010 #if defined(HAVE_PRI_CCSS) 04011 case PRI_SUBCMD_CC_STOP_ALERTING: 04012 monitor = sig_pri_find_cc_monitor_by_cc_id(pri, 04013 subcmd->u.cc_stop_alerting.cc_id); 04014 if (!monitor) { 04015 pri_cc_cancel(pri->pri, subcmd->u.cc_stop_alerting.cc_id); 04016 break; 04017 } 04018 ast_cc_monitor_stop_ringing(monitor->core_id); 04019 ao2_ref(monitor, -1); 04020 break; 04021 #endif /* defined(HAVE_PRI_CCSS) */ 04022 #if defined(HAVE_PRI_AOC_EVENTS) 04023 case PRI_SUBCMD_AOC_E: 04024 /* Queue AST_CONTROL_AOC frame */ 04025 sig_pri_aoc_e_from_pri(&subcmd->u.aoc_e, NULL, 0); 04026 break; 04027 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 04028 default: 04029 ast_debug(2, 04030 "Unknown CIS subcommand(%d) in %s event on span %d.\n", 04031 subcmd->cmd, pri_event2str(event_id), pri->span); 04032 break; 04033 } 04034 } 04035 }
static void sig_pri_handle_dchan_exception | ( | struct sig_pri_span * | pri, | |
int | index | |||
) | [static] |
Definition at line 158 of file sig_pri.c.
References sig_pri_span::calls, and sig_pri_callback::handle_dchan_exception.
Referenced by pri_dchannel().
00159 { 00160 if (pri->calls->handle_dchan_exception) 00161 pri->calls->handle_dchan_exception(pri, index); 00162 }
static int sig_pri_handle_hold | ( | struct sig_pri_span * | pri, | |
pri_event * | ev | |||
) | [static] |
Definition at line 4449 of file sig_pri.c.
References ast_channel_unlock, AST_CONTROL_HOLD, AST_FRAME_CONTROL, ast_log(), ast_queue_frame(), sig_pri_chan::call_level, f, LOG_WARNING, sig_pri_chan::no_b_channel, sig_pri_chan::owner, pri_find_empty_nobch(), pri_find_principle_by_call(), pri_fixup_principle(), sig_pri_span::pvts, SIG_PRI_CALL_LEVEL_CONNECT, sig_pri_handle_subcmds(), sig_pri_lock_owner(), sig_pri_lock_private(), sig_pri_span_devstate_changed(), sig_pri_unlock_private(), and sig_pri_span::span.
04450 { 04451 int retval; 04452 int chanpos_old; 04453 int chanpos_new; 04454 struct ast_channel *owner; 04455 04456 chanpos_old = pri_find_principle_by_call(pri, ev->hold.call); 04457 if (chanpos_old < 0) { 04458 ast_log(LOG_WARNING, "Span %d: Received HOLD for unknown call.\n", pri->span); 04459 return -1; 04460 } 04461 if (pri->pvts[chanpos_old]->no_b_channel) { 04462 /* Call is already on hold or is call waiting call. */ 04463 return -1; 04464 } 04465 04466 chanpos_new = -1; 04467 04468 sig_pri_lock_private(pri->pvts[chanpos_old]); 04469 sig_pri_lock_owner(pri, chanpos_old); 04470 owner = pri->pvts[chanpos_old]->owner; 04471 if (!owner) { 04472 goto done_with_private; 04473 } 04474 if (pri->pvts[chanpos_old]->call_level != SIG_PRI_CALL_LEVEL_CONNECT) { 04475 /* 04476 * Make things simple. Don't allow placing a call on hold that 04477 * is not connected. 04478 */ 04479 goto done_with_owner; 04480 } 04481 chanpos_new = pri_find_empty_nobch(pri); 04482 if (chanpos_new < 0) { 04483 /* No hold channel available. */ 04484 goto done_with_owner; 04485 } 04486 sig_pri_handle_subcmds(pri, chanpos_old, ev->e, ev->hold.channel, ev->hold.subcmds, 04487 ev->hold.call); 04488 chanpos_new = pri_fixup_principle(pri, chanpos_new, ev->hold.call); 04489 if (chanpos_new < 0) { 04490 /* Should never happen. */ 04491 } else { 04492 struct ast_frame f = { AST_FRAME_CONTROL, }; 04493 04494 /* 04495 * Things are in an odd state here so we cannot use pri_queue_control(). 04496 * However, we already have the owner lock so we can simply queue the frame. 04497 */ 04498 f.subclass.integer = AST_CONTROL_HOLD; 04499 ast_queue_frame(owner, &f); 04500 } 04501 04502 done_with_owner:; 04503 ast_channel_unlock(owner); 04504 done_with_private:; 04505 sig_pri_unlock_private(pri->pvts[chanpos_old]); 04506 04507 if (chanpos_new < 0) { 04508 retval = -1; 04509 } else { 04510 sig_pri_span_devstate_changed(pri); 04511 retval = 0; 04512 } 04513 04514 return retval; 04515 }
static void sig_pri_handle_retrieve | ( | struct sig_pri_span * | pri, | |
pri_event * | ev | |||
) | [static] |
Definition at line 4531 of file sig_pri.c.
References AST_CONTROL_UNHOLD, ast_log(), LOG_WARNING, sig_pri_span::pri, PRI_CHANNEL, pri_find_empty_chan(), pri_find_principle(), pri_find_principle_by_call(), pri_fixup_principle(), PRI_HELD_CALL, pri_queue_control(), PVT_TO_CHANNEL(), sig_pri_span::pvts, sig_pri_handle_subcmds(), sig_pri_is_chan_available(), sig_pri_lock_private(), sig_pri_span_devstate_changed(), sig_pri_unlock_private(), and sig_pri_span::span.
04532 { 04533 int chanpos; 04534 04535 if (!(ev->retrieve.channel & PRI_HELD_CALL)) { 04536 /* The call is not currently held. */ 04537 pri_retrieve_rej(pri->pri, ev->retrieve.call, 04538 PRI_CAUSE_RESOURCE_UNAVAIL_UNSPECIFIED); 04539 return; 04540 } 04541 if (pri_find_principle_by_call(pri, ev->retrieve.call) < 0) { 04542 ast_log(LOG_WARNING, "Span %d: Received RETRIEVE for unknown call.\n", pri->span); 04543 pri_retrieve_rej(pri->pri, ev->retrieve.call, 04544 PRI_CAUSE_RESOURCE_UNAVAIL_UNSPECIFIED); 04545 return; 04546 } 04547 if (PRI_CHANNEL(ev->retrieve.channel) == 0xFF) { 04548 chanpos = pri_find_empty_chan(pri, 1); 04549 } else { 04550 chanpos = pri_find_principle(pri, 04551 ev->retrieve.channel & ~PRI_HELD_CALL, ev->retrieve.call); 04552 if (ev->retrieve.flexible 04553 && (chanpos < 0 || !sig_pri_is_chan_available(pri->pvts[chanpos]))) { 04554 /* 04555 * Channel selection is flexible and the requested channel 04556 * is bad or not available. Pick another channel. 04557 */ 04558 chanpos = pri_find_empty_chan(pri, 1); 04559 } 04560 } 04561 if (chanpos < 0) { 04562 pri_retrieve_rej(pri->pri, ev->retrieve.call, 04563 ev->retrieve.flexible ? PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION 04564 : PRI_CAUSE_REQUESTED_CHAN_UNAVAIL); 04565 return; 04566 } 04567 chanpos = pri_fixup_principle(pri, chanpos, ev->retrieve.call); 04568 if (chanpos < 0) { 04569 /* Channel is already in use. */ 04570 pri_retrieve_rej(pri->pri, ev->retrieve.call, 04571 PRI_CAUSE_REQUESTED_CHAN_UNAVAIL); 04572 return; 04573 } 04574 sig_pri_lock_private(pri->pvts[chanpos]); 04575 sig_pri_handle_subcmds(pri, chanpos, ev->e, ev->retrieve.channel, 04576 ev->retrieve.subcmds, ev->retrieve.call); 04577 pri_queue_control(pri, chanpos, AST_CONTROL_UNHOLD); 04578 sig_pri_unlock_private(pri->pvts[chanpos]); 04579 pri_retrieve_ack(pri->pri, ev->retrieve.call, 04580 PVT_TO_CHANNEL(pri->pvts[chanpos])); 04581 sig_pri_span_devstate_changed(pri); 04582 }
static void sig_pri_handle_subcmds | ( | struct sig_pri_span * | pri, | |
int | chanpos, | |||
int | event_id, | |||
int | channel, | |||
const struct pri_subcommands * | subcmds, | |||
q931_call * | call_rsp | |||
) | [static] |
Definition at line 4094 of file sig_pri.c.
References ast_party_caller::ani, ao2_ref, ast_cc_agent_recalling(), ast_cc_agent_set_interfaces_chanvar(), AST_CC_CCBS, AST_CC_CCNR, AST_CC_NONE, ast_channel_queue_connected_line_update(), ast_channel_queue_redirecting_update(), ast_channel_set_caller_event(), ast_channel_set_redirecting(), ast_channel_unlock, AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER, ast_copy_string(), ast_debug, ast_log(), ast_null_frame, ast_party_caller_set_init(), ast_party_connected_line_free(), ast_party_connected_line_init(), ast_party_id_presentation(), ast_party_redirecting_free(), ast_party_subaddress_set(), ast_queue_frame(), ast_setup_cc_recall_datastore(), ast_strdup, ast_string_field_set, ast_strlen_zero(), ast_verb, xfer_rsp_data::call, ast_channel::caller, ast_cc_agent::core_id, ast_party_redirecting::from, ast_party_caller::id, xfer_rsp_data::invoke_id, LOG_ERROR, LOG_WARNING, ast_channel::name, xfer_rsp_data::pri, PRI_CHANNEL, PRI_SPAN, ast_channel::redirecting, service, sig_pri_aoc_d_from_pri(), sig_pri_aoc_e_from_pri(), SIG_PRI_AOC_GRANT_D, SIG_PRI_AOC_GRANT_E, SIG_PRI_AOC_GRANT_S, sig_pri_aoc_request_from_pri(), sig_pri_aoc_s_from_pri(), sig_pri_attempt_transfer(), sig_pri_cc_available(), sig_pri_cc_link_canceled(), sig_pri_cc_type_name, sig_pri_find_cc_agent_by_cc_id(), sig_pri_lock_owner(), sig_pri_lock_private(), sig_pri_mcid_event(), sig_pri_party_id_convert(), sig_pri_redirecting_convert(), sig_pri_set_caller_id(), sig_pri_transfer_rsp(), sig_pri_unlock_private(), ast_party_id::subaddress, ast_party_id::tag, and ast_party_redirecting::to.
Referenced by sig_pri_handle_hold(), and sig_pri_handle_retrieve().
04096 { 04097 int index; 04098 struct ast_channel *owner; 04099 struct ast_party_redirecting ast_redirecting; 04100 #if defined(HAVE_PRI_TRANSFER) 04101 struct xfer_rsp_data xfer_rsp; 04102 #endif /* defined(HAVE_PRI_TRANSFER) */ 04103 04104 if (!subcmds) { 04105 return; 04106 } 04107 for (index = 0; index < subcmds->counter_subcmd; ++index) { 04108 const struct pri_subcommand *subcmd = &subcmds->subcmd[index]; 04109 04110 switch (subcmd->cmd) { 04111 case PRI_SUBCMD_CONNECTED_LINE: 04112 sig_pri_lock_owner(pri, chanpos); 04113 owner = pri->pvts[chanpos]->owner; 04114 if (owner) { 04115 struct ast_party_connected_line ast_connected; 04116 int caller_id_update; 04117 04118 /* Extract the connected line information */ 04119 ast_party_connected_line_init(&ast_connected); 04120 sig_pri_party_id_convert(&ast_connected.id, &subcmd->u.connected_line.id, 04121 pri); 04122 ast_connected.id.tag = ast_strdup(pri->pvts[chanpos]->user_tag); 04123 04124 caller_id_update = 0; 04125 if (ast_connected.id.name.str) { 04126 /* Save name for Caller-ID update */ 04127 ast_copy_string(pri->pvts[chanpos]->cid_name, 04128 ast_connected.id.name.str, sizeof(pri->pvts[chanpos]->cid_name)); 04129 caller_id_update = 1; 04130 } 04131 if (ast_connected.id.number.str) { 04132 /* Save number for Caller-ID update */ 04133 ast_copy_string(pri->pvts[chanpos]->cid_num, 04134 ast_connected.id.number.str, sizeof(pri->pvts[chanpos]->cid_num)); 04135 pri->pvts[chanpos]->cid_ton = ast_connected.id.number.plan; 04136 caller_id_update = 1; 04137 } 04138 ast_connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER; 04139 04140 pri->pvts[chanpos]->cid_subaddr[0] = '\0'; 04141 #if defined(HAVE_PRI_SUBADDR) 04142 if (ast_connected.id.subaddress.valid) { 04143 ast_party_subaddress_set(&owner->caller.id.subaddress, 04144 &ast_connected.id.subaddress); 04145 if (ast_connected.id.subaddress.str) { 04146 ast_copy_string(pri->pvts[chanpos]->cid_subaddr, 04147 ast_connected.id.subaddress.str, 04148 sizeof(pri->pvts[chanpos]->cid_subaddr)); 04149 } 04150 } 04151 #endif /* defined(HAVE_PRI_SUBADDR) */ 04152 if (caller_id_update) { 04153 struct ast_party_caller ast_caller; 04154 04155 pri->pvts[chanpos]->callingpres = 04156 ast_party_id_presentation(&ast_connected.id); 04157 sig_pri_set_caller_id(pri->pvts[chanpos]); 04158 04159 ast_party_caller_set_init(&ast_caller, &owner->caller); 04160 ast_caller.id = ast_connected.id; 04161 ast_caller.ani = ast_connected.id; 04162 ast_channel_set_caller_event(owner, &ast_caller, NULL); 04163 } 04164 04165 /* Update the connected line information on the other channel */ 04166 if (event_id != PRI_EVENT_RING) { 04167 /* This connected_line update was not from a SETUP message. */ 04168 ast_channel_queue_connected_line_update(owner, &ast_connected, NULL); 04169 } 04170 04171 ast_party_connected_line_free(&ast_connected); 04172 ast_channel_unlock(owner); 04173 } 04174 break; 04175 case PRI_SUBCMD_REDIRECTING: 04176 sig_pri_lock_owner(pri, chanpos); 04177 owner = pri->pvts[chanpos]->owner; 04178 if (owner) { 04179 sig_pri_redirecting_convert(&ast_redirecting, &subcmd->u.redirecting, 04180 &owner->redirecting, pri); 04181 ast_redirecting.from.tag = ast_strdup(pri->pvts[chanpos]->user_tag); 04182 ast_redirecting.to.tag = ast_strdup(pri->pvts[chanpos]->user_tag); 04183 04184 /*! \todo XXX Original called data can be put in a channel data store that is inherited. */ 04185 04186 ast_channel_set_redirecting(owner, &ast_redirecting, NULL); 04187 if (event_id != PRI_EVENT_RING) { 04188 /* This redirection was not from a SETUP message. */ 04189 ast_channel_queue_redirecting_update(owner, &ast_redirecting, NULL); 04190 } 04191 ast_party_redirecting_free(&ast_redirecting); 04192 04193 ast_channel_unlock(owner); 04194 } 04195 break; 04196 #if defined(HAVE_PRI_CALL_REROUTING) 04197 case PRI_SUBCMD_REROUTING: 04198 sig_pri_lock_owner(pri, chanpos); 04199 owner = pri->pvts[chanpos]->owner; 04200 if (owner) { 04201 struct pri_party_redirecting pri_deflection; 04202 04203 if (!call_rsp) { 04204 ast_log(LOG_WARNING, 04205 "Span %d: %s tried CallRerouting/CallDeflection to '%s' without call!\n", 04206 pri->span, owner->name, subcmd->u.rerouting.deflection.to.number.str); 04207 ast_channel_unlock(owner); 04208 break; 04209 } 04210 if (ast_strlen_zero(subcmd->u.rerouting.deflection.to.number.str)) { 04211 ast_log(LOG_WARNING, 04212 "Span %d: %s tried CallRerouting/CallDeflection to empty number!\n", 04213 pri->span, owner->name); 04214 pri_rerouting_rsp(pri->pri, call_rsp, subcmd->u.rerouting.invoke_id, 04215 PRI_REROUTING_RSP_INVALID_NUMBER); 04216 ast_channel_unlock(owner); 04217 break; 04218 } 04219 04220 ast_verb(3, "Span %d: %s is CallRerouting/CallDeflection to '%s'.\n", 04221 pri->span, owner->name, subcmd->u.rerouting.deflection.to.number.str); 04222 04223 /* 04224 * Send back positive ACK to CallRerouting/CallDeflection. 04225 * 04226 * Note: This call will be hungup by the core when it processes 04227 * the call_forward string. 04228 */ 04229 pri_rerouting_rsp(pri->pri, call_rsp, subcmd->u.rerouting.invoke_id, 04230 PRI_REROUTING_RSP_OK_CLEAR); 04231 04232 pri_deflection = subcmd->u.rerouting.deflection; 04233 04234 /* Adjust the deflecting to number based upon the subscription option. */ 04235 switch (subcmd->u.rerouting.subscription_option) { 04236 case 0: /* noNotification */ 04237 case 1: /* notificationWithoutDivertedToNr */ 04238 /* Delete the number because the far end is not supposed to see it. */ 04239 pri_deflection.to.number.presentation = 04240 PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_UNSCREENED; 04241 pri_deflection.to.number.plan = 04242 (PRI_TON_UNKNOWN << 4) | PRI_NPI_E163_E164; 04243 pri_deflection.to.number.str[0] = '\0'; 04244 break; 04245 case 2: /* notificationWithDivertedToNr */ 04246 break; 04247 case 3: /* notApplicable */ 04248 default: 04249 break; 04250 } 04251 sig_pri_redirecting_convert(&ast_redirecting, &pri_deflection, 04252 &owner->redirecting, pri); 04253 ast_redirecting.from.tag = ast_strdup(pri->pvts[chanpos]->user_tag); 04254 ast_redirecting.to.tag = ast_strdup(pri->pvts[chanpos]->user_tag); 04255 ast_channel_set_redirecting(owner, &ast_redirecting, NULL); 04256 ast_party_redirecting_free(&ast_redirecting); 04257 04258 /* Request the core to forward to the new number. */ 04259 ast_string_field_set(owner, call_forward, 04260 subcmd->u.rerouting.deflection.to.number.str); 04261 04262 /* Wake up the channel. */ 04263 ast_queue_frame(owner, &ast_null_frame); 04264 04265 ast_channel_unlock(owner); 04266 } 04267 break; 04268 #endif /* defined(HAVE_PRI_CALL_REROUTING) */ 04269 #if defined(HAVE_PRI_CCSS) 04270 case PRI_SUBCMD_CC_AVAILABLE: 04271 sig_pri_lock_owner(pri, chanpos); 04272 owner = pri->pvts[chanpos]->owner; 04273 if (owner) { 04274 enum ast_cc_service_type service; 04275 04276 switch (event_id) { 04277 case PRI_EVENT_RINGING: 04278 service = AST_CC_CCNR; 04279 break; 04280 case PRI_EVENT_HANGUP_REQ: 04281 /* We will assume that the cause was busy/congestion. */ 04282 service = AST_CC_CCBS; 04283 break; 04284 default: 04285 service = AST_CC_NONE; 04286 break; 04287 } 04288 if (service == AST_CC_NONE 04289 || sig_pri_cc_available(pri, chanpos, subcmd->u.cc_available.cc_id, 04290 service)) { 04291 pri_cc_cancel(pri->pri, subcmd->u.cc_available.cc_id); 04292 } 04293 ast_channel_unlock(owner); 04294 } else { 04295 /* No asterisk channel. */ 04296 pri_cc_cancel(pri->pri, subcmd->u.cc_available.cc_id); 04297 } 04298 break; 04299 #endif /* defined(HAVE_PRI_CCSS) */ 04300 #if defined(HAVE_PRI_CCSS) 04301 case PRI_SUBCMD_CC_CALL: 04302 sig_pri_lock_owner(pri, chanpos); 04303 owner = pri->pvts[chanpos]->owner; 04304 if (owner) { 04305 struct ast_cc_agent *agent; 04306 04307 agent = sig_pri_find_cc_agent_by_cc_id(pri, subcmd->u.cc_call.cc_id); 04308 if (agent) { 04309 ast_setup_cc_recall_datastore(owner, agent->core_id); 04310 ast_cc_agent_set_interfaces_chanvar(owner); 04311 ast_cc_agent_recalling(agent->core_id, 04312 "%s caller is attempting recall", sig_pri_cc_type_name); 04313 ao2_ref(agent, -1); 04314 } 04315 04316 ast_channel_unlock(owner); 04317 } 04318 break; 04319 #endif /* defined(HAVE_PRI_CCSS) */ 04320 #if defined(HAVE_PRI_CCSS) 04321 case PRI_SUBCMD_CC_CANCEL: 04322 sig_pri_cc_link_canceled(pri, subcmd->u.cc_cancel.cc_id, 04323 subcmd->u.cc_cancel.is_agent); 04324 break; 04325 #endif /* defined(HAVE_PRI_CCSS) */ 04326 #if defined(HAVE_PRI_TRANSFER) 04327 case PRI_SUBCMD_TRANSFER_CALL: 04328 if (!call_rsp) { 04329 /* Should never happen. */ 04330 ast_log(LOG_ERROR, 04331 "Call transfer subcommand without call to send response!\n"); 04332 break; 04333 } 04334 04335 sig_pri_unlock_private(pri->pvts[chanpos]); 04336 xfer_rsp.pri = pri; 04337 xfer_rsp.call = call_rsp; 04338 xfer_rsp.invoke_id = subcmd->u.transfer.invoke_id; 04339 sig_pri_attempt_transfer(pri, 04340 subcmd->u.transfer.call_1, subcmd->u.transfer.is_call_1_held, 04341 subcmd->u.transfer.call_2, subcmd->u.transfer.is_call_2_held, 04342 sig_pri_transfer_rsp, &xfer_rsp); 04343 sig_pri_lock_private(pri->pvts[chanpos]); 04344 break; 04345 #endif /* defined(HAVE_PRI_TRANSFER) */ 04346 #if defined(HAVE_PRI_AOC_EVENTS) 04347 case PRI_SUBCMD_AOC_S: 04348 sig_pri_lock_owner(pri, chanpos); 04349 owner = pri->pvts[chanpos]->owner; 04350 if (owner) { 04351 sig_pri_aoc_s_from_pri(&subcmd->u.aoc_s, owner, 04352 (pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_S)); 04353 ast_channel_unlock(owner); 04354 } 04355 break; 04356 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 04357 #if defined(HAVE_PRI_AOC_EVENTS) 04358 case PRI_SUBCMD_AOC_D: 04359 sig_pri_lock_owner(pri, chanpos); 04360 owner = pri->pvts[chanpos]->owner; 04361 if (owner) { 04362 /* Queue AST_CONTROL_AOC frame on channel */ 04363 sig_pri_aoc_d_from_pri(&subcmd->u.aoc_d, owner, 04364 (pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_D)); 04365 ast_channel_unlock(owner); 04366 } 04367 break; 04368 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 04369 #if defined(HAVE_PRI_AOC_EVENTS) 04370 case PRI_SUBCMD_AOC_E: 04371 sig_pri_lock_owner(pri, chanpos); 04372 owner = pri->pvts[chanpos]->owner; 04373 /* Queue AST_CONTROL_AOC frame */ 04374 sig_pri_aoc_e_from_pri(&subcmd->u.aoc_e, owner, 04375 (pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_E)); 04376 if (owner) { 04377 ast_channel_unlock(owner); 04378 } 04379 break; 04380 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 04381 #if defined(HAVE_PRI_AOC_EVENTS) 04382 case PRI_SUBCMD_AOC_CHARGING_REQ: 04383 sig_pri_lock_owner(pri, chanpos); 04384 owner = pri->pvts[chanpos]->owner; 04385 if (owner) { 04386 sig_pri_aoc_request_from_pri(&subcmd->u.aoc_request, pri->pvts[chanpos], 04387 call_rsp); 04388 ast_channel_unlock(owner); 04389 } 04390 break; 04391 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 04392 #if defined(HAVE_PRI_AOC_EVENTS) 04393 case PRI_SUBCMD_AOC_CHARGING_REQ_RSP: 04394 /* 04395 * An AOC request response may contain an AOC-S rate list. 04396 * If this is the case handle this just like we 04397 * would an incoming AOC-S msg. 04398 */ 04399 if (subcmd->u.aoc_request_response.valid_aoc_s) { 04400 sig_pri_lock_owner(pri, chanpos); 04401 owner = pri->pvts[chanpos]->owner; 04402 if (owner) { 04403 sig_pri_aoc_s_from_pri(&subcmd->u.aoc_request_response.aoc_s, owner, 04404 (pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_S)); 04405 ast_channel_unlock(owner); 04406 } 04407 } 04408 break; 04409 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 04410 #if defined(HAVE_PRI_MCID) 04411 case PRI_SUBCMD_MCID_REQ: 04412 sig_pri_lock_owner(pri, chanpos); 04413 owner = pri->pvts[chanpos]->owner; 04414 sig_pri_mcid_event(pri, &subcmd->u.mcid_req, owner); 04415 if (owner) { 04416 ast_channel_unlock(owner); 04417 } 04418 break; 04419 #endif /* defined(HAVE_PRI_MCID) */ 04420 #if defined(HAVE_PRI_MCID) 04421 case PRI_SUBCMD_MCID_RSP: 04422 /* Ignore for now. */ 04423 break; 04424 #endif /* defined(HAVE_PRI_MCID) */ 04425 default: 04426 ast_debug(2, 04427 "Unknown call subcommand(%d) in %s event on channel %d/%d on span %d.\n", 04428 subcmd->cmd, pri_event2str(event_id), PRI_SPAN(channel), 04429 PRI_CHANNEL(channel), pri->span); 04430 break; 04431 } 04432 } 04433 }
int sig_pri_hangup | ( | struct sig_pri_chan * | p, | |
struct ast_channel * | ast | |||
) |
Definition at line 6387 of file sig_pri.c.
References sig_pri_chan::allocated, sig_pri_chan::alreadyhungup, sig_pri_chan::aoc_e, sig_pri_chan::aoc_s_request_invoke_id_valid, ast_atomic_fetchadd_int(), ast_debug, ast_log(), ast_strlen_zero(), sig_pri_chan::call, sig_pri_chan::call_level, cause, sig_pri_chan::channel, sig_pri_chan::cid_name, sig_pri_chan::cid_num, sig_pri_chan::cid_subaddr, sig_pri_chan::exten, ast_channel::hangupcause, sig_pri_chan::holding_aoce, sig_pri_chan::is_call_waiting, LOG_WARNING, sig_pri_span::num_call_waiting_calls, sig_pri_chan::owner, pbx_builtin_getvar_helper(), sig_pri_chan::pri, sig_pri_span::pri, pri_grab(), pri_rel(), sig_pri_chan::progress, SIG_PRI_CALL_LEVEL_IDLE, sig_pri_set_dialing(), sig_pri_set_digital(), sig_pri_set_outgoing(), sig_pri_span_devstate_changed(), ast_channel::tech_pvt, sig_pri_chan::user_tag, and sig_pri_chan::waiting_for_aoce.
Referenced by dahdi_hangup().
06388 { 06389 ast_debug(1, "%s %d\n", __FUNCTION__, p->channel); 06390 if (!ast->tech_pvt) { 06391 ast_log(LOG_WARNING, "Asked to hangup channel not connected\n"); 06392 return 0; 06393 } 06394 06395 sig_pri_set_outgoing(p, 0); 06396 sig_pri_set_digital(p, 0); /* push up to parent for EC*/ 06397 #if defined(HAVE_PRI_CALL_WAITING) 06398 if (p->is_call_waiting) { 06399 p->is_call_waiting = 0; 06400 ast_atomic_fetchadd_int(&p->pri->num_call_waiting_calls, -1); 06401 } 06402 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 06403 p->call_level = SIG_PRI_CALL_LEVEL_IDLE; 06404 p->progress = 0; 06405 p->cid_num[0] = '\0'; 06406 p->cid_subaddr[0] = '\0'; 06407 p->cid_name[0] = '\0'; 06408 p->user_tag[0] = '\0'; 06409 p->exten[0] = '\0'; 06410 sig_pri_set_dialing(p, 0); 06411 06412 /* Make sure we really have a call */ 06413 pri_grab(p, p->pri); 06414 if (p->call) { 06415 #if defined(SUPPORT_USERUSER) 06416 const char *useruser = pbx_builtin_getvar_helper(ast, "USERUSERINFO"); 06417 06418 if (!ast_strlen_zero(useruser)) { 06419 pri_call_set_useruser(p->call, useruser); 06420 } 06421 #endif /* defined(SUPPORT_USERUSER) */ 06422 06423 #if defined(HAVE_PRI_AOC_EVENTS) 06424 if (p->holding_aoce) { 06425 pri_aoc_e_send(p->pri->pri, p->call, &p->aoc_e); 06426 } 06427 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 06428 06429 if (p->alreadyhungup) { 06430 ast_debug(1, "Already hungup... Calling hangup once, and clearing call\n"); 06431 06432 pri_hangup(p->pri->pri, p->call, -1); 06433 p->call = NULL; 06434 } else { 06435 const char *cause = pbx_builtin_getvar_helper(ast,"PRI_CAUSE"); 06436 int icause = ast->hangupcause ? ast->hangupcause : -1; 06437 06438 p->alreadyhungup = 1; 06439 if (!ast_strlen_zero(cause)) { 06440 if (atoi(cause)) { 06441 icause = atoi(cause); 06442 } 06443 } 06444 ast_debug(1, 06445 "Not yet hungup... Calling hangup with cause %d, and clearing call\n", 06446 icause); 06447 06448 pri_hangup(p->pri->pri, p->call, icause); 06449 } 06450 } 06451 #if defined(HAVE_PRI_AOC_EVENTS) 06452 p->aoc_s_request_invoke_id_valid = 0; 06453 p->holding_aoce = 0; 06454 p->waiting_for_aoce = 0; 06455 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 06456 06457 p->allocated = 0; 06458 p->owner = NULL; 06459 06460 sig_pri_span_devstate_changed(p->pri); 06461 pri_rel(p->pri); 06462 return 0; 06463 }
int sig_pri_indicate | ( | struct sig_pri_chan * | p, | |
struct ast_channel * | chan, | |||
int | condition, | |||
const void * | data, | |||
size_t | datalen | |||
) |
Definition at line 7010 of file sig_pri.c.
References ast_channel::_softhangup, ast_channel::_state, sig_pri_span::aoc_passthrough_flag, AST_AOC_D, ast_aoc_decode(), ast_aoc_destroy_decoded(), AST_AOC_E, ast_aoc_get_msg_type(), ast_aoc_get_termination_request(), AST_AOC_REQUEST, AST_AOC_S, AST_CAUSE_INVALID_NUMBER_FORMAT, AST_CAUSE_NORMAL_CLEARING, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_USER_BUSY, AST_CONTROL_AOC, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HOLD, AST_CONTROL_INCOMPLETE, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_REDIRECTING, AST_CONTROL_RINGING, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, ast_debug, ast_log(), ast_moh_start(), ast_moh_stop(), ast_setstate(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, sig_pri_chan::call, sig_pri_chan::call_level, ast_channel::connected, DAHDI_OVERLAPDIAL_INCOMING, sig_pri_chan::digital, ast_channel::hangupcause, ast_party_connected_line::id, LOG_DEBUG, sig_pri_chan::mohinterpret, ast_channel::name, sig_pri_chan::no_b_channel, sig_pri_chan::outgoing, sig_pri_span::overlapdial, sig_pri_chan::pri, sig_pri_span::pri, pri_grab(), pri_rel(), sig_pri_chan::priindication_oob, sig_pri_chan::prioffset, sig_pri_chan::progress, PVT_TO_CHANNEL(), sig_pri_aoc_d_from_ast(), sig_pri_aoc_e_from_ast(), SIG_PRI_AOC_GRANT_D, SIG_PRI_AOC_GRANT_E, SIG_PRI_AOC_GRANT_S, sig_pri_aoc_s_from_ast(), SIG_PRI_CALL_LEVEL_ALERTING, SIG_PRI_CALL_LEVEL_CONNECT, SIG_PRI_CALL_LEVEL_PROCEEDING, sig_pri_party_id_from_ast(), sig_pri_play_tone(), sig_pri_redirecting_update(), sig_pri_set_dialing(), sig_pri_set_digital(), SIG_PRI_TONE_BUSY, SIG_PRI_TONE_CONGESTION, SIG_PRI_TONE_RINGTONE, and sig_pri_chan::waiting_for_aoce.
Referenced by dahdi_indicate().
07011 { 07012 int res = -1; 07013 07014 switch (condition) { 07015 case AST_CONTROL_BUSY: 07016 if (p->priindication_oob || p->no_b_channel) { 07017 chan->hangupcause = AST_CAUSE_USER_BUSY; 07018 chan->_softhangup |= AST_SOFTHANGUP_DEV; 07019 res = 0; 07020 break; 07021 } 07022 res = sig_pri_play_tone(p, SIG_PRI_TONE_BUSY); 07023 if (p->call_level < SIG_PRI_CALL_LEVEL_ALERTING && !p->outgoing) { 07024 chan->hangupcause = AST_CAUSE_USER_BUSY; 07025 p->progress = 1;/* No need to send plain PROGRESS after this. */ 07026 if (p->pri && p->pri->pri) { 07027 pri_grab(p, p->pri); 07028 #ifdef HAVE_PRI_PROG_W_CAUSE 07029 pri_progress_with_cause(p->pri->pri, p->call, PVT_TO_CHANNEL(p), 1, chan->hangupcause); 07030 #else 07031 pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1); 07032 #endif 07033 pri_rel(p->pri); 07034 } 07035 } 07036 break; 07037 case AST_CONTROL_RINGING: 07038 if (p->call_level < SIG_PRI_CALL_LEVEL_ALERTING && !p->outgoing) { 07039 p->call_level = SIG_PRI_CALL_LEVEL_ALERTING; 07040 if (p->pri && p->pri->pri) { 07041 pri_grab(p, p->pri); 07042 pri_acknowledge(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 07043 p->no_b_channel || p->digital ? 0 : 1); 07044 pri_rel(p->pri); 07045 } 07046 } 07047 res = sig_pri_play_tone(p, SIG_PRI_TONE_RINGTONE); 07048 if (chan->_state != AST_STATE_UP) { 07049 if (chan->_state != AST_STATE_RING) 07050 ast_setstate(chan, AST_STATE_RINGING); 07051 } 07052 break; 07053 case AST_CONTROL_PROCEEDING: 07054 ast_debug(1,"Received AST_CONTROL_PROCEEDING on %s\n",chan->name); 07055 if (p->call_level < SIG_PRI_CALL_LEVEL_PROCEEDING && !p->outgoing) { 07056 p->call_level = SIG_PRI_CALL_LEVEL_PROCEEDING; 07057 if (p->pri && p->pri->pri) { 07058 pri_grab(p, p->pri); 07059 pri_proceeding(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 07060 p->no_b_channel || p->digital ? 0 : 1); 07061 if (!p->no_b_channel && !p->digital) { 07062 sig_pri_set_dialing(p, 0); 07063 } 07064 pri_rel(p->pri); 07065 } 07066 } 07067 /* don't continue in ast_indicate */ 07068 res = 0; 07069 break; 07070 case AST_CONTROL_PROGRESS: 07071 ast_debug(1,"Received AST_CONTROL_PROGRESS on %s\n",chan->name); 07072 sig_pri_set_digital(p, 0); /* Digital-only calls isn't allowing any inband progress messages */ 07073 if (!p->progress && p->call_level < SIG_PRI_CALL_LEVEL_ALERTING && !p->outgoing 07074 && !p->no_b_channel) { 07075 p->progress = 1;/* No need to send plain PROGRESS again. */ 07076 if (p->pri && p->pri->pri) { 07077 pri_grab(p, p->pri); 07078 #ifdef HAVE_PRI_PROG_W_CAUSE 07079 pri_progress_with_cause(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1, -1); /* no cause at all */ 07080 #else 07081 pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1); 07082 #endif 07083 pri_rel(p->pri); 07084 } 07085 } 07086 /* don't continue in ast_indicate */ 07087 res = 0; 07088 break; 07089 case AST_CONTROL_INCOMPLETE: 07090 /* If we are connected or if we support overlap dialing, wait for additional digits */ 07091 if (p->call_level == SIG_PRI_CALL_LEVEL_CONNECT || (p->pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)) { 07092 res = 0; 07093 break; 07094 } 07095 /* Otherwise, treat as congestion */ 07096 chan->hangupcause = AST_CAUSE_INVALID_NUMBER_FORMAT; 07097 /* Falls through */ 07098 case AST_CONTROL_CONGESTION: 07099 if (p->priindication_oob || p->no_b_channel) { 07100 /* There are many cause codes that generate an AST_CONTROL_CONGESTION. */ 07101 switch (chan->hangupcause) { 07102 case AST_CAUSE_USER_BUSY: 07103 case AST_CAUSE_NORMAL_CLEARING: 07104 case 0:/* Cause has not been set. */ 07105 /* Supply a more appropriate cause. */ 07106 chan->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 07107 break; 07108 default: 07109 break; 07110 } 07111 chan->_softhangup |= AST_SOFTHANGUP_DEV; 07112 res = 0; 07113 break; 07114 } 07115 res = sig_pri_play_tone(p, SIG_PRI_TONE_CONGESTION); 07116 if (p->call_level < SIG_PRI_CALL_LEVEL_ALERTING && !p->outgoing) { 07117 /* There are many cause codes that generate an AST_CONTROL_CONGESTION. */ 07118 switch (chan->hangupcause) { 07119 case AST_CAUSE_USER_BUSY: 07120 case AST_CAUSE_NORMAL_CLEARING: 07121 case 0:/* Cause has not been set. */ 07122 /* Supply a more appropriate cause. */ 07123 chan->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 07124 break; 07125 default: 07126 break; 07127 } 07128 p->progress = 1;/* No need to send plain PROGRESS after this. */ 07129 if (p->pri && p->pri->pri) { 07130 pri_grab(p, p->pri); 07131 #ifdef HAVE_PRI_PROG_W_CAUSE 07132 pri_progress_with_cause(p->pri->pri, p->call, PVT_TO_CHANNEL(p), 1, chan->hangupcause); 07133 #else 07134 pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1); 07135 #endif 07136 pri_rel(p->pri); 07137 } 07138 } 07139 break; 07140 case AST_CONTROL_HOLD: 07141 if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) { 07142 pri_grab(p, p->pri); 07143 res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_HOLD); 07144 pri_rel(p->pri); 07145 } else 07146 ast_moh_start(chan, data, p->mohinterpret); 07147 break; 07148 case AST_CONTROL_UNHOLD: 07149 if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) { 07150 pri_grab(p, p->pri); 07151 res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_RETRIEVAL); 07152 pri_rel(p->pri); 07153 } else 07154 ast_moh_stop(chan); 07155 break; 07156 case AST_CONTROL_SRCUPDATE: 07157 res = 0; 07158 break; 07159 case -1: 07160 res = sig_pri_play_tone(p, -1); 07161 break; 07162 case AST_CONTROL_CONNECTED_LINE: 07163 ast_debug(1, "Received AST_CONTROL_CONNECTED_LINE on %s\n", chan->name); 07164 if (p->pri) { 07165 struct pri_party_connected_line connected; 07166 07167 pri_grab(p, p->pri); 07168 memset(&connected, 0, sizeof(connected)); 07169 sig_pri_party_id_from_ast(&connected.id, &chan->connected.id); 07170 07171 pri_connected_line_update(p->pri->pri, p->call, &connected); 07172 pri_rel(p->pri); 07173 } 07174 break; 07175 case AST_CONTROL_REDIRECTING: 07176 ast_debug(1, "Received AST_CONTROL_REDIRECTING on %s\n", chan->name); 07177 if (p->pri) { 07178 pri_grab(p, p->pri); 07179 sig_pri_redirecting_update(p, chan); 07180 pri_rel(p->pri); 07181 } 07182 break; 07183 case AST_CONTROL_AOC: 07184 #if defined(HAVE_PRI_AOC_EVENTS) 07185 { 07186 struct ast_aoc_decoded *decoded 07187 = ast_aoc_decode((struct ast_aoc_encoded *) data, datalen, chan); 07188 ast_debug(1, "Received AST_CONTROL_AOC on %s\n", chan->name); 07189 if (decoded && p->pri) { 07190 pri_grab(p, p->pri); 07191 switch (ast_aoc_get_msg_type(decoded)) { 07192 case AST_AOC_S: 07193 if (p->pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_S) { 07194 sig_pri_aoc_s_from_ast(p, decoded); 07195 } 07196 break; 07197 case AST_AOC_D: 07198 if (p->pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_D) { 07199 sig_pri_aoc_d_from_ast(p, decoded); 07200 } 07201 break; 07202 case AST_AOC_E: 07203 if (p->pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_E) { 07204 sig_pri_aoc_e_from_ast(p, decoded); 07205 } 07206 /* if hangup was delayed for this AOC-E msg, waiting_for_aoc 07207 * will be set. A hangup is already occuring via a timeout during 07208 * this delay. Instead of waiting for that timeout to occur, go ahead 07209 * and initiate the softhangup since the delay is no longer necessary */ 07210 if (p->waiting_for_aoce) { 07211 p->waiting_for_aoce = 0; 07212 ast_log(LOG_DEBUG, 07213 "Received final AOC-E msg, continue with hangup on %s\n", 07214 chan->name); 07215 ast_softhangup_nolock(chan, AST_SOFTHANGUP_DEV); 07216 } 07217 break; 07218 case AST_AOC_REQUEST: 07219 /* We do not pass through AOC requests, So unless this 07220 * is an AOC termination request it will be ignored */ 07221 if (ast_aoc_get_termination_request(decoded)) { 07222 pri_hangup(p->pri->pri, p->call, -1); 07223 } 07224 break; 07225 default: 07226 break; 07227 } 07228 pri_rel(p->pri); 07229 } 07230 ast_aoc_destroy_decoded(decoded); 07231 } 07232 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 07233 break; 07234 } 07235 07236 return res; 07237 }
static void sig_pri_init_config | ( | struct sig_pri_chan * | pvt, | |
struct sig_pri_span * | pri | |||
) | [static] |
Definition at line 1733 of file sig_pri.c.
References ast_copy_string(), sig_pri_span::calls, sig_pri_span::ch_cfg, sig_pri_chan::chan_pvt, sig_pri_span::context, sig_pri_chan::context, sig_pri_span::hidecallerid, sig_pri_chan::hidecallerid, sig_pri_span::hidecalleridname, sig_pri_chan::hidecalleridname, sig_pri_span::immediate, sig_pri_chan::immediate, sig_pri_callback::init_config, sig_pri_span::mohinterpret, sig_pri_chan::mohinterpret, sig_pri_chan::pri, sig_pri_span::priexclusive, sig_pri_chan::priexclusive, sig_pri_span::priindication_oob, sig_pri_chan::priindication_oob, sig_pri_span::stripmsd, sig_pri_chan::stripmsd, sig_pri_span::use_callerid, sig_pri_chan::use_callerid, sig_pri_span::use_callingpres, and sig_pri_chan::use_callingpres.
Referenced by sig_pri_cw_available().
01734 { 01735 pvt->stripmsd = pri->ch_cfg.stripmsd; 01736 pvt->hidecallerid = pri->ch_cfg.hidecallerid; 01737 pvt->hidecalleridname = pri->ch_cfg.hidecalleridname; 01738 pvt->immediate = pri->ch_cfg.immediate; 01739 pvt->priexclusive = pri->ch_cfg.priexclusive; 01740 pvt->priindication_oob = pri->ch_cfg.priindication_oob; 01741 pvt->use_callerid = pri->ch_cfg.use_callerid; 01742 pvt->use_callingpres = pri->ch_cfg.use_callingpres; 01743 ast_copy_string(pvt->context, pri->ch_cfg.context, sizeof(pvt->context)); 01744 ast_copy_string(pvt->mohinterpret, pri->ch_cfg.mohinterpret, sizeof(pvt->mohinterpret)); 01745 01746 if (pri->calls->init_config) { 01747 pri->calls->init_config(pvt->chan_pvt, pri); 01748 } 01749 }
void sig_pri_init_pri | ( | struct sig_pri_span * | pri | ) |
Definition at line 6374 of file sig_pri.c.
References ast_mutex_init, AST_PTHREADT_NULL, and SIG_PRI_NUM_DCHANS.
Referenced by load_module().
06375 { 06376 int i; 06377 06378 memset(pri, 0, sizeof(*pri)); 06379 06380 ast_mutex_init(&pri->lock); 06381 06382 pri->master = AST_PTHREADT_NULL; 06383 for (i = 0; i < SIG_PRI_NUM_DCHANS; i++) 06384 pri->fds[i] = -1; 06385 }
int sig_pri_is_alarm_ignored | ( | struct sig_pri_span * | pri | ) |
Determine if layer 1 alarms are ignored.
p | Channel private pointer. |
Definition at line 7842 of file sig_pri.c.
References sig_pri_span::layer1_ignored.
Referenced by handle_alarms(), handle_clear_alarms(), my_handle_dchan_exception(), and sig_pri_set_alarm().
07843 { 07844 return pri->layer1_ignored; 07845 }
int sig_pri_is_chan_available | ( | struct sig_pri_chan * | pvt | ) |
Determine if a private channel structure is available.
pvt | Channel to determine if available. |
Definition at line 1159 of file sig_pri.c.
References sig_pri_chan::service_status, and sig_pri_is_chan_in_use().
Referenced by dahdi_pri_update_span_devstate(), pri_dchannel(), pri_find_empty_chan(), pri_find_empty_nobch(), pri_fixup_principle(), sig_pri_available_check(), sig_pri_cli_show_channels(), and sig_pri_handle_retrieve().
01160 { 01161 return !sig_pri_is_chan_in_use(pvt) 01162 #if defined(HAVE_PRI_SERVICE_MESSAGES) 01163 /* And not out-of-service */ 01164 && !pvt->service_status 01165 #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */ 01166 ; 01167 }
static int sig_pri_is_chan_in_use | ( | struct sig_pri_chan * | pvt | ) | [static] |
Definition at line 1145 of file sig_pri.c.
References sig_pri_chan::allocated, sig_pri_chan::call, sig_pri_chan::inalarm, sig_pri_chan::owner, sig_pri_chan::resetting, and SIG_PRI_RESET_IDLE.
Referenced by pri_check_restart(), and sig_pri_is_chan_available().
01146 { 01147 return pvt->owner || pvt->call || pvt->allocated || pvt->inalarm 01148 || pvt->resetting != SIG_PRI_RESET_IDLE; 01149 }
static int sig_pri_is_cis_call | ( | int | channel | ) | [static] |
Definition at line 3816 of file sig_pri.c.
References PRI_CIS_CALL.
03817 { 03818 return channel != -1 && (channel & PRI_CIS_CALL); 03819 }
static void sig_pri_kill_call | ( | struct sig_pri_span * | pri, | |
q931_call * | call, | |||
int | cause | |||
) | [static] |
Definition at line 1294 of file sig_pri.c.
References AST_CONTROL_HANGUP, sig_pri_chan::call, ast_channel::hangupcause, sig_pri_chan::owner, sig_pri_span::pri, sig_pri_chan::pri, pri_find_principle_by_call(), pri_queue_control(), sig_pri_span::pvts, sig_pri_lock_private(), sig_pri_span_devstate_changed(), and sig_pri_unlock_private().
Referenced by pri_find_fixup_principle().
01295 { 01296 int chanpos; 01297 01298 chanpos = pri_find_principle_by_call(pri, call); 01299 if (chanpos < 0) { 01300 pri_hangup(pri->pri, call, cause); 01301 return; 01302 } 01303 sig_pri_lock_private(pri->pvts[chanpos]); 01304 if (!pri->pvts[chanpos]->owner) { 01305 pri_hangup(pri->pri, call, cause); 01306 pri->pvts[chanpos]->call = NULL; 01307 sig_pri_unlock_private(pri->pvts[chanpos]); 01308 sig_pri_span_devstate_changed(pri); 01309 return; 01310 } 01311 pri->pvts[chanpos]->owner->hangupcause = cause; 01312 pri_queue_control(pri, chanpos, AST_CONTROL_HANGUP); 01313 sig_pri_unlock_private(pri->pvts[chanpos]); 01314 }
int sig_pri_load | ( | const char * | cc_type_name | ) |
Load the sig_pri submodule.
cc_type_name | CC type name to use when looking up agent/monitor. |
0 | on success. | |
-1 | on error. |
Definition at line 8652 of file sig_pri.c.
References ao2_container_alloc, sig_pri_cc_monitor_instance_cmp_fn(), sig_pri_cc_monitor_instance_hash_fn(), sig_pri_cc_monitors, and sig_pri_cc_type_name.
Referenced by load_module().
08653 { 08654 #if defined(HAVE_PRI_CCSS) 08655 sig_pri_cc_type_name = cc_type_name; 08656 sig_pri_cc_monitors = ao2_container_alloc(37, sig_pri_cc_monitor_instance_hash_fn, 08657 sig_pri_cc_monitor_instance_cmp_fn); 08658 if (!sig_pri_cc_monitors) { 08659 return -1; 08660 } 08661 #endif /* defined(HAVE_PRI_CCSS) */ 08662 return 0; 08663 }
static void sig_pri_lock_owner | ( | struct sig_pri_span * | pri, | |
int | chanpos | |||
) | [static] |
Definition at line 1182 of file sig_pri.c.
References ast_channel_trylock, sig_pri_chan::owner, and sig_pri_span::pvts.
Referenced by pri_fixup_principle(), pri_queue_frame(), sig_pri_attempt_transfer(), sig_pri_cc_generic_check(), sig_pri_cli_show_channels(), sig_pri_handle_hold(), sig_pri_handle_subcmds(), and sig_pri_send_aoce_termination_request().
01183 { 01184 for (;;) { 01185 if (!pri->pvts[chanpos]->owner) { 01186 /* There is no owner lock to get. */ 01187 break; 01188 } 01189 if (!ast_channel_trylock(pri->pvts[chanpos]->owner)) { 01190 /* We got the lock */ 01191 break; 01192 } 01193 01194 /* Avoid deadlock */ 01195 sig_pri_unlock_private(pri->pvts[chanpos]); 01196 DEADLOCK_AVOIDANCE(&pri->lock); 01197 sig_pri_lock_private(pri->pvts[chanpos]); 01198 } 01199 }
static void sig_pri_lock_private | ( | struct sig_pri_chan * | p | ) | [static] |
Definition at line 336 of file sig_pri.c.
References sig_pri_chan::calls, sig_pri_chan::chan_pvt, and sig_pri_callback::lock_private.
Referenced by pri_dchannel(), pri_fixup_principle(), pri_grab(), pri_send_callrerouting_facility_exec(), pri_send_keypad_facility_exec(), pri_ss_thread(), sig_pri_attempt_transfer(), sig_pri_cli_show_channels(), sig_pri_handle_hold(), sig_pri_handle_retrieve(), sig_pri_handle_subcmds(), and sig_pri_kill_call().
00337 { 00338 if (p->calls->lock_private) 00339 p->calls->lock_private(p->chan_pvt); 00340 }
static void sig_pri_make_cc_dialstring | ( | struct sig_pri_chan * | p, | |
char * | buf, | |||
size_t | buf_size | |||
) | [static] |
Definition at line 217 of file sig_pri.c.
References ast_log(), sig_pri_chan::calls, sig_pri_chan::chan_pvt, LOG_ERROR, and sig_pri_callback::make_cc_dialstring.
Referenced by sig_pri_cc_available().
00218 { 00219 if (p->calls->make_cc_dialstring) { 00220 p->calls->make_cc_dialstring(p->chan_pvt, buf, buf_size); 00221 } else { 00222 ast_log(LOG_ERROR, "make_cc_dialstring callback not defined\n"); 00223 buf[0] = '\0'; 00224 } 00225 }
static void sig_pri_mcid_event | ( | struct sig_pri_span * | pri, | |
const struct pri_subcmd_mcid_req * | mcid, | |||
struct ast_channel * | owner | |||
) | [static] |
Definition at line 2232 of file sig_pri.c.
References ast_free, ast_manager_event_multichan, ast_party_id_free(), ast_party_id_init(), ast_str_append(), ast_str_buffer(), ast_str_create(), ast_channel::connected, EVENT_FLAG_CALL, ast_party_connected_line::id, ast_channel::name, sig_pri_event_party_id(), sig_pri_party_id_convert(), and ast_channel::uniqueid.
Referenced by sig_pri_handle_subcmds().
02233 { 02234 struct ast_channel *chans[1]; 02235 struct ast_str *msg; 02236 struct ast_party_id party; 02237 02238 msg = ast_str_create(4096); 02239 if (!msg) { 02240 return; 02241 } 02242 02243 if (owner) { 02244 /* The owner channel is present. */ 02245 ast_str_append(&msg, 0, "Channel: %s\r\n", owner->name); 02246 ast_str_append(&msg, 0, "UniqueID: %s\r\n", owner->uniqueid); 02247 02248 sig_pri_event_party_id(&msg, "CallerID", &owner->connected.id); 02249 } else { 02250 /* 02251 * Since we no longer have an owner channel, 02252 * we have to use the caller information supplied by libpri. 02253 */ 02254 ast_party_id_init(&party); 02255 sig_pri_party_id_convert(&party, &mcid->originator, pri); 02256 sig_pri_event_party_id(&msg, "CallerID", &party); 02257 ast_party_id_free(&party); 02258 } 02259 02260 /* Always use libpri's called party information. */ 02261 ast_party_id_init(&party); 02262 sig_pri_party_id_convert(&party, &mcid->answerer, pri); 02263 sig_pri_event_party_id(&msg, "ConnectedID", &party); 02264 ast_party_id_free(&party); 02265 02266 chans[0] = owner; 02267 ast_manager_event_multichan(EVENT_FLAG_CALL, "MCID", owner ? 1 : 0, chans, "%s", 02268 ast_str_buffer(msg)); 02269 ast_free(msg); 02270 }
static int sig_pri_msn_match | ( | const char * | msn_patterns, | |
const char * | exten | |||
) | [static] |
Definition at line 2131 of file sig_pri.c.
References ast_extension_match(), ast_strdupa, ast_strip(), and ast_strlen_zero().
02132 { 02133 char *pattern; 02134 char *msn_list; 02135 char *list_tail; 02136 02137 msn_list = ast_strdupa(msn_patterns); 02138 02139 list_tail = NULL; 02140 pattern = strtok_r(msn_list, ",", &list_tail); 02141 while (pattern) { 02142 pattern = ast_strip(pattern); 02143 if (!ast_strlen_zero(pattern) && ast_extension_match(pattern, exten)) { 02144 /* Extension matched the pattern. */ 02145 return 1; 02146 } 02147 pattern = strtok_r(NULL, ",", &list_tail); 02148 } 02149 /* Did not match any pattern in the list. */ 02150 return 0; 02151 }
static void sig_pri_mwi_cache_update | ( | struct sig_pri_span * | pri | ) | [static] |
Definition at line 7524 of file sig_pri.c.
References ARRAY_LEN, ast_event_destroy(), ast_event_get_cached(), ast_event_get_ie_uint(), AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_MWI, sig_pri_mbox::context, sig_pri_span::mbox, sig_pri_mbox::number, sig_pri_send_mwi_indication(), and sig_pri_mbox::sub.
07525 { 07526 int idx; 07527 int num_messages; 07528 struct ast_event *event; 07529 07530 for (idx = 0; idx < ARRAY_LEN(pri->mbox); ++idx) { 07531 if (!pri->mbox[idx].sub) { 07532 /* There are no more mailboxes on this span. */ 07533 break; 07534 } 07535 07536 event = ast_event_get_cached(AST_EVENT_MWI, 07537 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, pri->mbox[idx].number, 07538 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, pri->mbox[idx].context, 07539 AST_EVENT_IE_END); 07540 if (!event) { 07541 /* No cached event for this mailbox. */ 07542 continue; 07543 } 07544 num_messages = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS); 07545 sig_pri_send_mwi_indication(pri, pri->mbox[idx].number, pri->mbox[idx].context, 07546 num_messages); 07547 ast_event_destroy(event); 07548 } 07549 }
static void sig_pri_mwi_event_cb | ( | const struct ast_event * | event, | |
void * | userdata | |||
) | [static] |
Definition at line 7494 of file sig_pri.c.
References ast_event_get_ie_str(), ast_event_get_ie_uint(), AST_EVENT_IE_CONTEXT, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_NEWMSGS, ast_strlen_zero(), sig_pri_span::pri, and sig_pri_send_mwi_indication().
Referenced by sig_pri_start_pri().
07495 { 07496 struct sig_pri_span *pri = userdata; 07497 const char *mbox_context; 07498 const char *mbox_number; 07499 int num_messages; 07500 07501 mbox_number = ast_event_get_ie_str(event, AST_EVENT_IE_MAILBOX); 07502 if (ast_strlen_zero(mbox_number)) { 07503 return; 07504 } 07505 mbox_context = ast_event_get_ie_str(event, AST_EVENT_IE_CONTEXT); 07506 if (ast_strlen_zero(mbox_context)) { 07507 return; 07508 } 07509 num_messages = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS); 07510 sig_pri_send_mwi_indication(pri, mbox_number, mbox_context, num_messages); 07511 }
static struct ast_channel* sig_pri_new_ast_channel | ( | struct sig_pri_chan * | p, | |
int | state, | |||
int | ulaw, | |||
int | transfercapability, | |||
char * | exten, | |||
const struct ast_channel * | requestor | |||
) | [static] |
Definition at line 942 of file sig_pri.c.
References sig_pri_chan::alreadyhungup, ast_mutex_lock, ast_mutex_unlock, AST_TRANS_CAP_DIGITAL, ast_transfercapability2str(), sig_pri_chan::calls, sig_pri_chan::chan_pvt, sig_pri_chan::isidlecall, sig_pri_span::lock, sig_pri_callback::new_ast_channel, sig_pri_chan::owner, pbx_builtin_setvar_helper(), sig_pri_chan::pri, sig_pri_set_digital(), sig_pri_span_devstate_changed(), and ast_channel::transfercapability.
Referenced by sig_pri_request().
00943 { 00944 struct ast_channel *c; 00945 00946 if (p->calls->new_ast_channel) { 00947 c = p->calls->new_ast_channel(p->chan_pvt, state, ulaw, exten, requestor); 00948 } else { 00949 return NULL; 00950 } 00951 if (!c) { 00952 return NULL; 00953 } 00954 00955 if (!p->owner) 00956 p->owner = c; 00957 p->isidlecall = 0; 00958 p->alreadyhungup = 0; 00959 c->transfercapability = transfercapability; 00960 pbx_builtin_setvar_helper(c, "TRANSFERCAPABILITY", 00961 ast_transfercapability2str(transfercapability)); 00962 if (transfercapability & AST_TRANS_CAP_DIGITAL) { 00963 sig_pri_set_digital(p, 1); 00964 } 00965 if (p->pri) { 00966 ast_mutex_lock(&p->pri->lock); 00967 sig_pri_span_devstate_changed(p->pri); 00968 ast_mutex_unlock(&p->pri->lock); 00969 } 00970 00971 return c; 00972 }
static void sig_pri_open_media | ( | struct sig_pri_chan * | p | ) | [static] |
Definition at line 983 of file sig_pri.c.
References sig_pri_chan::calls, sig_pri_chan::chan_pvt, sig_pri_chan::no_b_channel, and sig_pri_callback::open_media.
Referenced by pri_fixup_principle(), sig_pri_answer(), and sig_pri_dial_complete().
00984 { 00985 if (p->no_b_channel) { 00986 return; 00987 } 00988 00989 if (p->calls->open_media) { 00990 p->calls->open_media(p->chan_pvt); 00991 } 00992 }
static void sig_pri_party_id_convert | ( | struct ast_party_id * | ast_id, | |
const struct pri_party_id * | pri_id, | |||
struct sig_pri_span * | pri | |||
) | [static] |
Definition at line 2077 of file sig_pri.c.
References ast_party_id::name, ast_party_id::number, sig_pri_party_name_convert(), sig_pri_party_number_convert(), sig_pri_set_subaddress(), and ast_party_id::subaddress.
Referenced by sig_pri_handle_subcmds(), sig_pri_mcid_event(), and sig_pri_redirecting_convert().
02078 { 02079 if (pri_id->name.valid) { 02080 sig_pri_party_name_convert(&ast_id->name, &pri_id->name); 02081 } 02082 if (pri_id->number.valid) { 02083 sig_pri_party_number_convert(&ast_id->number, &pri_id->number, pri); 02084 } 02085 #if defined(HAVE_PRI_SUBADDR) 02086 if (pri_id->subaddress.valid) { 02087 sig_pri_set_subaddress(&ast_id->subaddress, &pri_id->subaddress); 02088 } 02089 #endif /* defined(HAVE_PRI_SUBADDR) */ 02090 }
static void sig_pri_party_id_from_ast | ( | struct pri_party_id * | pri_id, | |
const struct ast_party_id * | ast_id | |||
) | [static] |
Definition at line 868 of file sig_pri.c.
References ast_party_id::name, ast_party_id::number, sig_pri_party_name_from_ast(), sig_pri_party_number_from_ast(), sig_pri_party_subaddress_from_ast(), and ast_party_id::subaddress.
Referenced by sig_pri_indicate(), and sig_pri_redirecting_update().
00869 { 00870 sig_pri_party_name_from_ast(&pri_id->name, &ast_id->name); 00871 sig_pri_party_number_from_ast(&pri_id->number, &ast_id->number); 00872 #if defined(HAVE_PRI_SUBADDR) 00873 sig_pri_party_subaddress_from_ast(&pri_id->subaddress, &ast_id->subaddress); 00874 #endif /* defined(HAVE_PRI_SUBADDR) */ 00875 }
static void sig_pri_party_name_convert | ( | struct ast_party_name * | ast_name, | |
const struct pri_party_name * | pri_name | |||
) | [static] |
Definition at line 2029 of file sig_pri.c.
References ast_strdup, ast_party_name::char_set, ast_party_name::presentation, pri_to_ast_char_set(), pri_to_ast_presentation(), ast_party_name::str, and ast_party_name::valid.
Referenced by sig_pri_party_id_convert().
02030 { 02031 ast_name->str = ast_strdup(pri_name->str); 02032 ast_name->char_set = pri_to_ast_char_set(pri_name->char_set); 02033 ast_name->presentation = pri_to_ast_presentation(pri_name->presentation); 02034 ast_name->valid = 1; 02035 }
static void sig_pri_party_name_from_ast | ( | struct pri_party_name * | pri_name, | |
const struct ast_party_name * | ast_name | |||
) | [static] |
Definition at line 818 of file sig_pri.c.
References ast_copy_string(), ast_strlen_zero(), ast_to_pri_char_set(), ast_to_pri_presentation(), ast_party_name::char_set, ast_party_name::presentation, ast_party_name::str, and ast_party_name::valid.
Referenced by sig_pri_party_id_from_ast().
00819 { 00820 if (!ast_name->valid) { 00821 return; 00822 } 00823 pri_name->valid = 1; 00824 pri_name->presentation = ast_to_pri_presentation(ast_name->presentation); 00825 pri_name->char_set = ast_to_pri_char_set(ast_name->char_set); 00826 if (!ast_strlen_zero(ast_name->str)) { 00827 ast_copy_string(pri_name->str, ast_name->str, sizeof(pri_name->str)); 00828 } 00829 }
static void sig_pri_party_number_convert | ( | struct ast_party_number * | ast_number, | |
const struct pri_party_number * | pri_number, | |||
struct sig_pri_span * | pri | |||
) | [static] |
Definition at line 2051 of file sig_pri.c.
References apply_plan_to_existing_number(), AST_MAX_EXTENSION, ast_strdup, ast_party_number::plan, ast_party_number::presentation, pri_to_ast_presentation(), ast_party_number::str, and ast_party_number::valid.
Referenced by sig_pri_party_id_convert().
02052 { 02053 char number[AST_MAX_EXTENSION]; 02054 02055 apply_plan_to_existing_number(number, sizeof(number), pri, pri_number->str, 02056 pri_number->plan); 02057 ast_number->str = ast_strdup(number); 02058 ast_number->plan = pri_number->plan; 02059 ast_number->presentation = pri_to_ast_presentation(pri_number->presentation); 02060 ast_number->valid = 1; 02061 }
static void sig_pri_party_number_from_ast | ( | struct pri_party_number * | pri_number, | |
const struct ast_party_number * | ast_number | |||
) | [static] |
Definition at line 843 of file sig_pri.c.
References ast_copy_string(), ast_strlen_zero(), ast_to_pri_presentation(), ast_party_number::plan, ast_party_number::presentation, ast_party_number::str, and ast_party_number::valid.
Referenced by sig_pri_party_id_from_ast().
00844 { 00845 if (!ast_number->valid) { 00846 return; 00847 } 00848 pri_number->valid = 1; 00849 pri_number->presentation = ast_to_pri_presentation(ast_number->presentation); 00850 pri_number->plan = ast_number->plan; 00851 if (!ast_strlen_zero(ast_number->str)) { 00852 ast_copy_string(pri_number->str, ast_number->str, sizeof(pri_number->str)); 00853 } 00854 }
static void sig_pri_party_subaddress_from_ast | ( | struct pri_party_subaddress * | pri_subaddress, | |
const struct ast_party_subaddress * | ast_subaddress | |||
) | [static] |
Definition at line 772 of file sig_pri.c.
References ast_copy_string(), ast_pri_pack_hex_string(), ast_strlen_zero(), ast_party_subaddress::str, ast_party_subaddress::type, and ast_party_subaddress::valid.
Referenced by sig_pri_call(), and sig_pri_party_id_from_ast().
00773 { 00774 if (ast_subaddress->valid && !ast_strlen_zero(ast_subaddress->str)) { 00775 pri_subaddress->type = ast_subaddress->type; 00776 if (!ast_subaddress->type) { 00777 /* 0 = NSAP */ 00778 ast_copy_string((char *) pri_subaddress->data, ast_subaddress->str, 00779 sizeof(pri_subaddress->data)); 00780 pri_subaddress->length = strlen((char *) pri_subaddress->data); 00781 pri_subaddress->odd_even_indicator = 0; 00782 pri_subaddress->valid = 1; 00783 } else { 00784 /* 2 = User Specified */ 00785 /* 00786 * Copy HexString to packed HexData, 00787 * if odd length then right pad trailing byte with 0 00788 */ 00789 int length = ast_pri_pack_hex_string(pri_subaddress->data, 00790 ast_subaddress->str, sizeof(pri_subaddress->data)); 00791 00792 pri_subaddress->length = length; /* packed data length */ 00793 00794 length = strlen(ast_subaddress->str); 00795 if (length > 2 * sizeof(pri_subaddress->data)) { 00796 pri_subaddress->odd_even_indicator = 0; 00797 } else { 00798 pri_subaddress->odd_even_indicator = (length & 1); 00799 } 00800 pri_subaddress->valid = 1; 00801 } 00802 } 00803 }
static int sig_pri_play_tone | ( | struct sig_pri_chan * | p, | |
enum sig_pri_tone | tone | |||
) | [static] |
Definition at line 934 of file sig_pri.c.
References sig_pri_chan::calls, sig_pri_chan::chan_pvt, and sig_pri_callback::play_tone.
Referenced by pri_ss_thread(), and sig_pri_indicate().
00935 { 00936 if (p->calls->play_tone) 00937 return p->calls->play_tone(p->chan_pvt, tone); 00938 else 00939 return -1; 00940 }
static void sig_pri_redirecting_convert | ( | struct ast_party_redirecting * | ast_redirecting, | |
const struct pri_party_redirecting * | pri_redirecting, | |||
const struct ast_party_redirecting * | ast_guide, | |||
struct sig_pri_span * | pri | |||
) | [static] |
Definition at line 2107 of file sig_pri.c.
References ast_party_redirecting_set_init(), ast_party_redirecting::count, ast_party_redirecting::from, pri_to_ast_reason(), ast_party_redirecting::reason, sig_pri_party_id_convert(), and ast_party_redirecting::to.
Referenced by sig_pri_handle_subcmds().
02111 { 02112 ast_party_redirecting_set_init(ast_redirecting, ast_guide); 02113 02114 sig_pri_party_id_convert(&ast_redirecting->from, &pri_redirecting->from, pri); 02115 sig_pri_party_id_convert(&ast_redirecting->to, &pri_redirecting->to, pri); 02116 ast_redirecting->count = pri_redirecting->count; 02117 ast_redirecting->reason = pri_to_ast_reason(pri_redirecting->reason); 02118 }
static void sig_pri_redirecting_update | ( | struct sig_pri_chan * | pvt, | |
struct ast_channel * | ast | |||
) | [static] |
Definition at line 889 of file sig_pri.c.
References ast_to_pri_reason(), sig_pri_chan::call, ast_party_redirecting::count, ast_party_redirecting::from, sig_pri_span::pri, sig_pri_chan::pri, ast_party_redirecting::reason, ast_channel::redirecting, sig_pri_party_id_from_ast(), and ast_party_redirecting::to.
Referenced by sig_pri_call(), and sig_pri_indicate().
00890 { 00891 struct pri_party_redirecting pri_redirecting; 00892 00893 /*! \todo XXX Original called data can be put in a channel data store that is inherited. */ 00894 00895 memset(&pri_redirecting, 0, sizeof(pri_redirecting)); 00896 sig_pri_party_id_from_ast(&pri_redirecting.from, &ast->redirecting.from); 00897 sig_pri_party_id_from_ast(&pri_redirecting.to, &ast->redirecting.to); 00898 pri_redirecting.count = ast->redirecting.count; 00899 pri_redirecting.reason = ast_to_pri_reason(ast->redirecting.reason); 00900 00901 pri_redirecting_update(pvt->pri->pri, pvt->call, &pri_redirecting); 00902 }
struct ast_channel* sig_pri_request | ( | struct sig_pri_chan * | p, | |
enum sig_pri_law | law, | |||
const struct ast_channel * | requestor, | |||
int | transfercapability | |||
) |
Definition at line 1012 of file sig_pri.c.
References ast_log(), AST_STATE_RESERVED, sig_pri_chan::channel, sig_pri_chan::exten, LOG_DEBUG, sig_pri_new_ast_channel(), and sig_pri_set_outgoing().
Referenced by dahdi_request(), and pri_dchannel().
01013 { 01014 struct ast_channel *ast; 01015 01016 ast_log(LOG_DEBUG, "%s %d\n", __FUNCTION__, p->channel); 01017 01018 sig_pri_set_outgoing(p, 1); 01019 ast = sig_pri_new_ast_channel(p, AST_STATE_RESERVED, law, transfercapability, p->exten, requestor); 01020 if (!ast) { 01021 sig_pri_set_outgoing(p, 0); 01022 } 01023 return ast; 01024 }
static void sig_pri_send_aoce_termination_request | ( | struct sig_pri_span * | pri, | |
int | chanpos, | |||
unsigned int | ms | |||
) | [static] |
Definition at line 3761 of file sig_pri.c.
References ast_aoc_create(), ast_aoc_destroy_decoded(), ast_aoc_destroy_encoded(), ast_aoc_encode(), AST_AOC_REQUEST, AST_AOC_REQUEST_E, ast_aoc_set_termination_request(), ast_channel_setwhentohangup_tv(), ast_channel_unlock, AST_CONTROL_AOC, ast_log(), ast_queue_control_data(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), LOG_DEBUG, ast_channel::name, sig_pri_chan::owner, sig_pri_span::pvts, sig_pri_lock_owner(), and sig_pri_chan::waiting_for_aoce.
03762 { 03763 struct sig_pri_chan *pvt; 03764 struct ast_aoc_decoded *decoded = NULL; 03765 struct ast_aoc_encoded *encoded = NULL; 03766 size_t encoded_size; 03767 struct timeval whentohangup = { 0, }; 03768 03769 sig_pri_lock_owner(pri, chanpos); 03770 pvt = pri->pvts[chanpos]; 03771 if (!pvt->owner) { 03772 return; 03773 } 03774 03775 if (!(decoded = ast_aoc_create(AST_AOC_REQUEST, 0, AST_AOC_REQUEST_E))) { 03776 ast_softhangup_nolock(pvt->owner, AST_SOFTHANGUP_DEV); 03777 goto cleanup_termination_request; 03778 } 03779 03780 ast_aoc_set_termination_request(decoded); 03781 03782 if (!(encoded = ast_aoc_encode(decoded, &encoded_size, pvt->owner))) { 03783 ast_softhangup_nolock(pvt->owner, AST_SOFTHANGUP_DEV); 03784 goto cleanup_termination_request; 03785 } 03786 03787 /* convert ms to timeval */ 03788 whentohangup.tv_usec = (ms % 1000) * 1000; 03789 whentohangup.tv_sec = ms / 1000; 03790 03791 if (ast_queue_control_data(pvt->owner, AST_CONTROL_AOC, encoded, encoded_size)) { 03792 ast_softhangup_nolock(pvt->owner, AST_SOFTHANGUP_DEV); 03793 goto cleanup_termination_request; 03794 } 03795 03796 pvt->waiting_for_aoce = 1; 03797 ast_channel_setwhentohangup_tv(pvt->owner, whentohangup); 03798 ast_log(LOG_DEBUG, "Delaying hangup on %s for aoc-e msg\n", pvt->owner->name); 03799 03800 cleanup_termination_request: 03801 ast_channel_unlock(pvt->owner); 03802 ast_aoc_destroy_decoded(decoded); 03803 ast_aoc_destroy_encoded(encoded); 03804 }
static void sig_pri_send_mwi_indication | ( | struct sig_pri_span * | pri, | |
const char * | mbox_number, | |||
const char * | mbox_context, | |||
int | num_messages | |||
) | [static] |
Definition at line 7464 of file sig_pri.c.
References ast_copy_string(), ast_debug, ast_mutex_lock, ast_mutex_unlock, sig_pri_span::lock, and sig_pri_span::pri.
Referenced by sig_pri_mwi_cache_update(), and sig_pri_mwi_event_cb().
07465 { 07466 struct pri_party_id mailbox; 07467 07468 ast_debug(1, "Send MWI indication for %s@%s num_messages:%d\n", mbox_number, 07469 mbox_context, num_messages); 07470 07471 memset(&mailbox, 0, sizeof(mailbox)); 07472 mailbox.number.valid = 1; 07473 mailbox.number.presentation = PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; 07474 mailbox.number.plan = (PRI_TON_UNKNOWN << 4) | PRI_NPI_UNKNOWN; 07475 ast_copy_string(mailbox.number.str, mbox_number, sizeof(mailbox.number.str)); 07476 07477 ast_mutex_lock(&pri->lock); 07478 pri_mwi_indicate(pri->pri, &mailbox, 1 /* speech */, num_messages, NULL, NULL, -1, 0); 07479 ast_mutex_unlock(&pri->lock); 07480 }
void sig_pri_set_alarm | ( | struct sig_pri_chan * | p, | |
int | in_alarm | |||
) |
Definition at line 187 of file sig_pri.c.
References sig_pri_chan::calls, sig_pri_chan::chan_pvt, sig_pri_chan::inalarm, sig_pri_chan::pri, sig_pri_chan::resetting, sig_pri_callback::set_alarm, sig_pri_is_alarm_ignored(), and SIG_PRI_RESET_IDLE.
Referenced by sig_pri_chan_alarm_notify().
00188 { 00189 if (sig_pri_is_alarm_ignored(p->pri)) { 00190 /* Always set not in alarm */ 00191 in_alarm = 0; 00192 } 00193 00194 /* 00195 * Clear the channel restart state when the channel alarm 00196 * changes to prevent the state from getting stuck when the link 00197 * goes down. 00198 */ 00199 p->resetting = SIG_PRI_RESET_IDLE; 00200 00201 p->inalarm = in_alarm; 00202 if (p->calls->set_alarm) { 00203 p->calls->set_alarm(p->chan_pvt, in_alarm); 00204 } 00205 }
static void sig_pri_set_caller_id | ( | struct sig_pri_chan * | p | ) | [static] |
Definition at line 262 of file sig_pri.c.
References ast_party_caller::ani, ast_party_caller::ani2, ast_party_caller_init(), ast_strlen_zero(), sig_pri_chan::callingpres, sig_pri_chan::calls, sig_pri_chan::chan_pvt, sig_pri_chan::cid_ani, sig_pri_chan::cid_ani2, sig_pri_chan::cid_name, sig_pri_chan::cid_num, sig_pri_chan::cid_subaddr, sig_pri_chan::cid_ton, ast_party_caller::id, ast_party_id::name, ast_party_id::number, ast_party_number::plan, ast_party_number::presentation, ast_party_name::presentation, sig_pri_callback::set_callerid, ast_party_subaddress::str, ast_party_number::str, ast_party_name::str, ast_party_id::subaddress, ast_party_id::tag, sig_pri_chan::user_tag, ast_party_subaddress::valid, ast_party_number::valid, and ast_party_name::valid.
Referenced by sig_pri_handle_subcmds().
00263 { 00264 struct ast_party_caller caller; 00265 00266 if (p->calls->set_callerid) { 00267 ast_party_caller_init(&caller); 00268 00269 caller.id.name.str = p->cid_name; 00270 caller.id.name.presentation = p->callingpres; 00271 caller.id.name.valid = 1; 00272 00273 caller.id.number.str = p->cid_num; 00274 caller.id.number.plan = p->cid_ton; 00275 caller.id.number.presentation = p->callingpres; 00276 caller.id.number.valid = 1; 00277 00278 if (!ast_strlen_zero(p->cid_subaddr)) { 00279 caller.id.subaddress.valid = 1; 00280 //caller.id.subaddress.type = 0;/* nsap */ 00281 //caller.id.subaddress.odd_even_indicator = 0; 00282 caller.id.subaddress.str = p->cid_subaddr; 00283 } 00284 caller.id.tag = p->user_tag; 00285 00286 caller.ani.number.str = p->cid_ani; 00287 //caller.ani.number.plan = p->xxx; 00288 //caller.ani.number.presentation = p->xxx; 00289 caller.ani.number.valid = 1; 00290 00291 caller.ani2 = p->cid_ani2; 00292 p->calls->set_callerid(p->chan_pvt, &caller); 00293 } 00294 }
static void sig_pri_set_dialing | ( | struct sig_pri_chan * | p, | |
int | is_dialing | |||
) | [static] |
Definition at line 164 of file sig_pri.c.
References sig_pri_chan::calls, sig_pri_chan::chan_pvt, and sig_pri_callback::set_dialing.
Referenced by sig_pri_answer(), sig_pri_call(), sig_pri_dial_complete(), sig_pri_hangup(), and sig_pri_indicate().
00165 { 00166 if (p->calls->set_dialing) { 00167 p->calls->set_dialing(p->chan_pvt, is_dialing); 00168 } 00169 }
static void sig_pri_set_digital | ( | struct sig_pri_chan * | p, | |
int | is_digital | |||
) | [static] |
Definition at line 171 of file sig_pri.c.
References sig_pri_chan::calls, sig_pri_chan::chan_pvt, sig_pri_chan::digital, and sig_pri_callback::set_digital.
Referenced by sig_pri_call(), sig_pri_hangup(), sig_pri_indicate(), and sig_pri_new_ast_channel().
00172 { 00173 p->digital = is_digital; 00174 if (p->calls->set_digital) { 00175 p->calls->set_digital(p->chan_pvt, is_digital); 00176 } 00177 }
static void sig_pri_set_dnid | ( | struct sig_pri_chan * | p, | |
const char * | dnid | |||
) | [static] |
Definition at line 306 of file sig_pri.c.
References sig_pri_chan::calls, sig_pri_chan::chan_pvt, and sig_pri_callback::set_dnid.
00307 { 00308 if (p->calls->set_dnid) { 00309 p->calls->set_dnid(p->chan_pvt, dnid); 00310 } 00311 }
static int sig_pri_set_echocanceller | ( | struct sig_pri_chan * | p, | |
int | enable | |||
) | [static] |
Definition at line 920 of file sig_pri.c.
References sig_pri_chan::calls, sig_pri_chan::chan_pvt, and sig_pri_callback::set_echocanceller.
Referenced by pri_ss_thread(), and sig_pri_dial_complete().
00921 { 00922 if (p->calls->set_echocanceller) 00923 return p->calls->set_echocanceller(p->chan_pvt, enable); 00924 else 00925 return -1; 00926 }
static void sig_pri_set_outgoing | ( | struct sig_pri_chan * | p, | |
int | is_outgoing | |||
) | [static] |
Definition at line 179 of file sig_pri.c.
References sig_pri_chan::calls, sig_pri_chan::chan_pvt, sig_pri_chan::outgoing, and sig_pri_callback::set_outgoing.
Referenced by sig_pri_call(), sig_pri_hangup(), and sig_pri_request().
00180 { 00181 p->outgoing = is_outgoing; 00182 if (p->calls->set_outgoing) { 00183 p->calls->set_outgoing(p->chan_pvt, is_outgoing); 00184 } 00185 }
static void sig_pri_set_rdnis | ( | struct sig_pri_chan * | p, | |
const char * | rdnis | |||
) | [static] |
Definition at line 323 of file sig_pri.c.
References sig_pri_chan::calls, sig_pri_chan::chan_pvt, and sig_pri_callback::set_rdnis.
00324 { 00325 if (p->calls->set_rdnis) { 00326 p->calls->set_rdnis(p->chan_pvt, rdnis); 00327 } 00328 }
static void sig_pri_set_subaddress | ( | struct ast_party_subaddress * | ast_subaddress, | |
const struct pri_party_subaddress * | pri_subaddress | |||
) | [static] |
Definition at line 650 of file sig_pri.c.
References ast_free, ast_malloc, ast_party_subaddress_init(), ast_strdup, len(), and ast_party_subaddress::str.
Referenced by sig_pri_party_id_convert().
00651 { 00652 char *cnum, *ptr; 00653 int x, len; 00654 00655 if (ast_subaddress->str) { 00656 ast_free(ast_subaddress->str); 00657 } 00658 if (pri_subaddress->length <= 0) { 00659 ast_party_subaddress_init(ast_subaddress); 00660 return; 00661 } 00662 00663 if (!pri_subaddress->type) { 00664 /* NSAP */ 00665 ast_subaddress->str = ast_strdup((char *) pri_subaddress->data); 00666 } else { 00667 /* User Specified */ 00668 if (!(cnum = ast_malloc(2 * pri_subaddress->length + 1))) { 00669 ast_party_subaddress_init(ast_subaddress); 00670 return; 00671 } 00672 00673 ptr = cnum; 00674 len = pri_subaddress->length - 1; /* -1 account for zero based indexing */ 00675 for (x = 0; x < len; ++x) { 00676 ptr += sprintf(ptr, "%02x", pri_subaddress->data[x]); 00677 } 00678 00679 if (pri_subaddress->odd_even_indicator) { 00680 /* ODD */ 00681 sprintf(ptr, "%01x", (pri_subaddress->data[len]) >> 4); 00682 } else { 00683 /* EVEN */ 00684 sprintf(ptr, "%02x", pri_subaddress->data[len]); 00685 } 00686 ast_subaddress->str = cnum; 00687 } 00688 ast_subaddress->type = pri_subaddress->type; 00689 ast_subaddress->odd_even_indicator = pri_subaddress->odd_even_indicator; 00690 ast_subaddress->valid = 1; 00691 }
static void sig_pri_sort_pri_chans | ( | struct sig_pri_span * | pri | ) | [static] |
Definition at line 7620 of file sig_pri.c.
References sig_pri_span::numchans, sig_pri_chan::pri, sig_pri_span::pvts, and sig_pri_cmp_pri_chans().
Referenced by sig_pri_start_pri().
07621 { 07622 qsort(&pri->pvts, pri->numchans, sizeof(pri->pvts[0]), sig_pri_cmp_pri_chans); 07623 }
static void sig_pri_span_devstate_changed | ( | struct sig_pri_span * | pri | ) | [static] |
Definition at line 246 of file sig_pri.c.
References sig_pri_span::calls, and sig_pri_callback::update_span_devstate.
Referenced by pri_check_restart(), pri_dchannel(), pri_ss_thread(), sig_pri_chan_alarm_notify(), sig_pri_handle_hold(), sig_pri_handle_retrieve(), sig_pri_hangup(), sig_pri_kill_call(), and sig_pri_new_ast_channel().
00247 { 00248 if (pri->calls->update_span_devstate) { 00249 pri->calls->update_span_devstate(pri); 00250 } 00251 }
int sig_pri_start_pri | ( | struct sig_pri_span * | pri | ) |
Definition at line 7625 of file sig_pri.c.
References ARRAY_LEN, AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_MWI, ast_event_subscribe(), ast_event_unsubscribe(), ast_log(), ast_mutex_init, ast_str_alloca, ast_str_buffer(), ast_str_set(), ast_strip(), ast_strlen_zero(), sig_pri_mbox::context, sig_pri_span::dchans, sig_pri_span::enable_service_message_support, sig_pri_span::fds, HAVE_PRI_SERVICE_MESSAGES, sig_pri_span::lock, LOG_ERROR, sig_pri_span::mbox, sig_pri_span::mwi_mailboxes, sig_pri_span::nodetype, sig_pri_mbox::number, sig_pri_span::sig, SIG_BRI, SIG_BRI_PTMP, sig_pri_cc_type_name, sig_pri_mwi_event_cb(), SIG_PRI_NUM_DCHANS, sig_pri_sort_pri_chans(), sig_pri_span::span, strsep(), sig_pri_mbox::sub, and sig_pri_span::switchtype.
Referenced by setup_dahdi_int().
07626 { 07627 int x; 07628 int i; 07629 #if defined(HAVE_PRI_MWI) 07630 char *saveptr; 07631 char *mbox_number; 07632 char *mbox_context; 07633 struct ast_str *mwi_description = ast_str_alloca(64); 07634 #endif /* defined(HAVE_PRI_MWI) */ 07635 07636 #if defined(HAVE_PRI_MWI) 07637 /* Prepare the mbox[] for use. */ 07638 for (i = 0; i < ARRAY_LEN(pri->mbox); ++i) { 07639 if (pri->mbox[i].sub) { 07640 pri->mbox[i].sub = ast_event_unsubscribe(pri->mbox[i].sub); 07641 } 07642 } 07643 #endif /* defined(HAVE_PRI_MWI) */ 07644 07645 ast_mutex_init(&pri->lock); 07646 sig_pri_sort_pri_chans(pri); 07647 07648 #if defined(HAVE_PRI_MWI) 07649 /* 07650 * Split the mwi_mailboxes configuration string into the mbox[]: 07651 * mailbox_number[@context]{,mailbox_number[@context]} 07652 */ 07653 i = 0; 07654 saveptr = pri->mwi_mailboxes; 07655 while (i < ARRAY_LEN(pri->mbox)) { 07656 mbox_number = strsep(&saveptr, ","); 07657 if (!mbox_number) { 07658 break; 07659 } 07660 /* Split the mailbox_number and context */ 07661 mbox_context = strchr(mbox_number, '@'); 07662 if (mbox_context) { 07663 *mbox_context++ = '\0'; 07664 mbox_context = ast_strip(mbox_context); 07665 } 07666 mbox_number = ast_strip(mbox_number); 07667 if (ast_strlen_zero(mbox_number)) { 07668 /* There is no mailbox number. Skip it. */ 07669 continue; 07670 } 07671 if (ast_strlen_zero(mbox_context)) { 07672 /* There was no context so use the default. */ 07673 mbox_context = "default"; 07674 } 07675 07676 /* Fill the mbox[] element. */ 07677 ast_str_set(&mwi_description, -1, "%s span %d[%d] MWI mailbox %s@%s", 07678 sig_pri_cc_type_name, pri->span, i, mbox_number, mbox_context); 07679 pri->mbox[i].sub = ast_event_subscribe(AST_EVENT_MWI, sig_pri_mwi_event_cb, 07680 ast_str_buffer(mwi_description), pri, 07681 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mbox_number, 07682 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, mbox_context, 07683 AST_EVENT_IE_END); 07684 if (!pri->mbox[i].sub) { 07685 ast_log(LOG_ERROR, "%s span %d could not subscribe to MWI events for %s@%s.", 07686 sig_pri_cc_type_name, pri->span, mbox_number, mbox_context); 07687 continue; 07688 } 07689 pri->mbox[i].number = mbox_number; 07690 pri->mbox[i].context = mbox_context; 07691 ++i; 07692 } 07693 #endif /* defined(HAVE_PRI_MWI) */ 07694 07695 for (i = 0; i < SIG_PRI_NUM_DCHANS; i++) { 07696 if (pri->fds[i] == -1) { 07697 break; 07698 } 07699 07700 switch (pri->sig) { 07701 case SIG_BRI: 07702 pri->dchans[i] = pri_new_bri(pri->fds[i], 1, pri->nodetype, pri->switchtype); 07703 break; 07704 case SIG_BRI_PTMP: 07705 pri->dchans[i] = pri_new_bri(pri->fds[i], 0, pri->nodetype, pri->switchtype); 07706 break; 07707 default: 07708 pri->dchans[i] = pri_new(pri->fds[i], pri->nodetype, pri->switchtype); 07709 #if defined(HAVE_PRI_SERVICE_MESSAGES) 07710 if (pri->enable_service_message_support) { 07711 pri_set_service_message_support(pri->dchans[i], 1); 07712 } 07713 #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */ 07714 break; 07715 } 07716 07717 pri_set_overlapdial(pri->dchans[i], (pri->overlapdial & DAHDI_OVERLAPDIAL_OUTGOING) ? 1 : 0); 07718 #ifdef HAVE_PRI_PROG_W_CAUSE 07719 pri_set_chan_mapping_logical(pri->dchans[i], pri->qsigchannelmapping == DAHDI_CHAN_MAPPING_LOGICAL); 07720 #endif 07721 #ifdef HAVE_PRI_INBANDDISCONNECT 07722 pri_set_inbanddisconnect(pri->dchans[i], pri->inbanddisconnect); 07723 #endif 07724 /* Enslave to master if appropriate */ 07725 if (i) 07726 pri_enslave(pri->dchans[0], pri->dchans[i]); 07727 if (!pri->dchans[i]) { 07728 if (pri->fds[i] > 0) 07729 close(pri->fds[i]); 07730 pri->fds[i] = -1; 07731 ast_log(LOG_ERROR, "Unable to create PRI structure\n"); 07732 return -1; 07733 } 07734 pri_set_debug(pri->dchans[i], SIG_PRI_DEBUG_DEFAULT); 07735 pri_set_nsf(pri->dchans[i], pri->nsf); 07736 #ifdef PRI_GETSET_TIMERS 07737 for (x = 0; x < PRI_MAX_TIMERS; x++) { 07738 if (pri->pritimers[x] != 0) 07739 pri_set_timer(pri->dchans[i], x, pri->pritimers[x]); 07740 } 07741 #endif 07742 } 07743 07744 /* Assume primary is the one we use */ 07745 pri->pri = pri->dchans[0]; 07746 07747 #if defined(HAVE_PRI_CALL_HOLD) 07748 pri_hold_enable(pri->pri, 1); 07749 #endif /* defined(HAVE_PRI_CALL_HOLD) */ 07750 #if defined(HAVE_PRI_CALL_REROUTING) 07751 pri_reroute_enable(pri->pri, 1); 07752 #endif /* defined(HAVE_PRI_CALL_REROUTING) */ 07753 #if defined(HAVE_PRI_HANGUP_FIX) 07754 pri_hangup_fix_enable(pri->pri, 1); 07755 #endif /* defined(HAVE_PRI_HANGUP_FIX) */ 07756 #if defined(HAVE_PRI_CCSS) 07757 pri_cc_enable(pri->pri, 1); 07758 pri_cc_recall_mode(pri->pri, pri->cc_ptmp_recall_mode); 07759 pri_cc_retain_signaling_req(pri->pri, pri->cc_qsig_signaling_link_req); 07760 pri_cc_retain_signaling_rsp(pri->pri, pri->cc_qsig_signaling_link_rsp); 07761 #endif /* defined(HAVE_PRI_CCSS) */ 07762 #if defined(HAVE_PRI_TRANSFER) 07763 pri_transfer_enable(pri->pri, 1); 07764 #endif /* defined(HAVE_PRI_TRANSFER) */ 07765 #if defined(HAVE_PRI_AOC_EVENTS) 07766 pri_aoc_events_enable(pri->pri, 1); 07767 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 07768 #if defined(HAVE_PRI_CALL_WAITING) 07769 pri_connect_ack_enable(pri->pri, 1); 07770 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 07771 #if defined(HAVE_PRI_MCID) 07772 pri_mcid_enable(pri->pri, 1); 07773 #endif /* defined(HAVE_PRI_MCID) */ 07774 #if defined(HAVE_PRI_L2_PERSISTENCE) 07775 pri_persistent_layer2_option(pri->pri, pri->l2_persistence); 07776 #endif /* defined(HAVE_PRI_L2_PERSISTENCE) */ 07777 07778 pri->resetpos = -1; 07779 if (ast_pthread_create_background(&pri->master, NULL, pri_dchannel, pri)) { 07780 for (i = 0; i < SIG_PRI_NUM_DCHANS; i++) { 07781 if (!pri->dchans[i]) 07782 break; 07783 if (pri->fds[i] > 0) 07784 close(pri->fds[i]); 07785 pri->fds[i] = -1; 07786 } 07787 ast_log(LOG_ERROR, "Unable to spawn D-channel: %s\n", strerror(errno)); 07788 return -1; 07789 } 07790 07791 #if defined(HAVE_PRI_MWI) 07792 /* 07793 * Send the initial MWI indications from the event cache for this span. 07794 * 07795 * If we were loaded after app_voicemail the event would already be in 07796 * the cache. If we were loaded before app_voicemail the event would not 07797 * be in the cache yet and app_voicemail will send the event when it 07798 * gets loaded. 07799 */ 07800 sig_pri_mwi_cache_update(pri); 07801 #endif /* defined(HAVE_PRI_MWI) */ 07802 07803 return 0; 07804 }
void sig_pri_stop_pri | ( | struct sig_pri_span * | pri | ) |
Stop PRI span.
pri | PRI span control structure. |
Definition at line 7560 of file sig_pri.c.
References ARRAY_LEN, ast_event_unsubscribe(), sig_pri_span::mbox, and sig_pri_mbox::sub.
Referenced by __unload_module().
07561 { 07562 #if defined(HAVE_PRI_MWI) 07563 int idx; 07564 #endif /* defined(HAVE_PRI_MWI) */ 07565 07566 #if defined(HAVE_PRI_MWI) 07567 for (idx = 0; idx < ARRAY_LEN(pri->mbox); ++idx) { 07568 if (pri->mbox[idx].sub) { 07569 pri->mbox[idx].sub = ast_event_unsubscribe(pri->mbox[idx].sub); 07570 } 07571 } 07572 #endif /* defined(HAVE_PRI_MWI) */ 07573 }
static void sig_pri_transfer_rsp | ( | void * | data, | |
int | is_successful | |||
) | [static] |
Definition at line 2294 of file sig_pri.c.
References xfer_rsp_data::call, xfer_rsp_data::invoke_id, sig_pri_span::pri, and xfer_rsp_data::pri.
Referenced by sig_pri_handle_subcmds().
02295 { 02296 struct xfer_rsp_data *rsp = data; 02297 02298 pri_transfer_rsp(rsp->pri->pri, rsp->call, rsp->invoke_id, is_successful); 02299 }
void sig_pri_unload | ( | void | ) |
Unload the sig_pri submodule.
Definition at line 8671 of file sig_pri.c.
References ao2_ref, and sig_pri_cc_monitors.
Referenced by __unload_module().
08672 { 08673 #if defined(HAVE_PRI_CCSS) 08674 if (sig_pri_cc_monitors) { 08675 ao2_ref(sig_pri_cc_monitors, -1); 08676 sig_pri_cc_monitors = NULL; 08677 } 08678 #endif /* defined(HAVE_PRI_CCSS) */ 08679 }
static void sig_pri_unlock_private | ( | struct sig_pri_chan * | p | ) | [static] |
Definition at line 330 of file sig_pri.c.
References sig_pri_chan::calls, sig_pri_chan::chan_pvt, and sig_pri_callback::unlock_private.
Referenced by pri_dchannel(), pri_fixup_principle(), pri_grab(), pri_send_callrerouting_facility_exec(), pri_send_keypad_facility_exec(), pri_ss_thread(), sig_pri_attempt_transfer(), sig_pri_cli_show_channels(), sig_pri_handle_hold(), sig_pri_handle_retrieve(), sig_pri_handle_subcmds(), and sig_pri_kill_call().
00331 { 00332 if (p->calls->unlock_private) 00333 p->calls->unlock_private(p->chan_pvt); 00334 }
int pri_gendigittimeout = 8000 [static] |
int pri_matchdigittimeout = 3000 [static] |
struct ast_app_option sig_pri_call_opts[128] = { [ 'K' ] = { .flag = OPT_KEYPAD , .arg_index = OPT_ARG_KEYPAD + 1 }, [ 'R' ] = { .flag = OPT_REVERSE_CHARGE }, [ 'A' ] = { .flag = OPT_AOC_REQUEST , .arg_index = OPT_ARG_AOC_REQUEST + 1 }, } [static] |
struct ao2_container* sig_pri_cc_monitors [static] |
Container of sig_pri monitor instances.
Definition at line 101 of file sig_pri.c.
Referenced by sig_pri_cc_available(), sig_pri_cc_monitor_destructor(), sig_pri_cc_monitor_instance_init(), sig_pri_find_cc_monitor_by_cc_id(), sig_pri_load(), and sig_pri_unload().
const char* sig_pri_cc_type_name [static] |
Upper level agent/monitor type name.
Definition at line 99 of file sig_pri.c.
Referenced by sig_pri_call(), sig_pri_cc_agent_req_rsp(), sig_pri_cc_available(), sig_pri_cc_link_canceled(), sig_pri_find_cc_agent_by_cc_id(), sig_pri_handle_cis_subcmds(), sig_pri_handle_subcmds(), sig_pri_load(), and sig_pri_start_pri().