#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.
Defines | |
#define | DCHAN_AVAILABLE (DCHAN_NOTINALARM | DCHAN_UP) |
#define | DCHAN_NOTINALARM (1 << 0) |
#define | DCHAN_UP (1 << 1) |
#define | PRI_CHANNEL(p) ((p) & 0xff) |
#define | PRI_CIS_CALL (1 << 17) |
#define | PRI_DEADLOCK_AVOIDANCE(p) |
#define | PRI_EXPLICIT (1 << 16) |
#define | PRI_HELD_CALL (1 << 18) |
#define | PRI_SPAN(p) (((p) >> 8) & 0xff) |
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_number (char *buf, size_t size, const struct sig_pri_span *pri, const char *number, const 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 char * | dialplan2str (int dialplan) |
static void * | do_idle_thread (void *v_pvt) |
static int | pri_active_dchan_index (struct sig_pri_span *pri) |
static int | 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 int | 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_pri_call (struct sig_pri_span *pri, q931_call *call) |
static int | pri_find_principle (struct sig_pri_span *pri, int channel, 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 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) |
int | sig_pri_answer (struct sig_pri_chan *p, struct ast_channel *ast) |
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 void | sig_pri_cc_generic_check (struct sig_pri_span *pri, int chanpos, enum ast_cc_service_type service) |
void | sig_pri_chan_alarm_notify (struct sig_pri_chan *p, int noalarm) |
void | sig_pri_chan_delete (struct sig_pri_chan *doomed) |
Delete the sig_pri private channel structure. | |
sig_pri_chan * | sig_pri_chan_new (void *pvt_data, struct sig_pri_callback *callback, struct sig_pri_span *pri, int logicalspan, int channo, int trunkgroup) |
void | sig_pri_cli_show_span (int fd, int *dchannels, struct sig_pri_span *pri) |
void | sig_pri_cli_show_spans (int fd, int span, struct sig_pri_span *pri) |
static int | sig_pri_cmp_pri_chans (const void *left, const void *right) |
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) |
void | sig_pri_extract_called_num_subaddr (struct sig_pri_chan *p, const char *rdest, char *called, size_t called_buff_size) |
Extract the called number and subaddress from the dial string. | |
void | sig_pri_fixup (struct ast_channel *oldchan, struct ast_channel *newchan, struct sig_pri_chan *pchan) |
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) |
void | sig_pri_init_pri (struct sig_pri_span *pri) |
static int | sig_pri_is_cis_call (int channel) |
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 int | sig_pri_msn_match (const char *msn_patterns, const char *exten) |
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_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_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. | |
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 }, } |
Definition in file sig_pri.c.
#define DCHAN_AVAILABLE (DCHAN_NOTINALARM | DCHAN_UP) |
#define DCHAN_NOTINALARM (1 << 0) |
Definition at line 90 of file sig_pri.c.
Referenced by build_status(), pri_event_alarm(), and pri_event_noalarm().
#define DCHAN_UP (1 << 1) |
#define PRI_CHANNEL | ( | p | ) | ((p) & 0xff) |
Definition at line 94 of file sig_pri.c.
Referenced by pri_find_principle(), sig_pri_handle_hold(), sig_pri_handle_retrieve(), and sig_pri_handle_subcmds().
#define PRI_CIS_CALL (1 << 17) |
#define PRI_DEADLOCK_AVOIDANCE | ( | p | ) |
Value:
do { \ sig_pri_unlock_private(p); \ usleep(1); \ sig_pri_lock_private(p); \ } while (0)
Definition at line 103 of file sig_pri.c.
Referenced by pri_grab().
#define PRI_EXPLICIT (1 << 16) |
#define PRI_HELD_CALL (1 << 18) |
Definition at line 98 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 95 of file sig_pri.c.
Referenced by pri_maintenance_bservice(), sig_pri_handle_hold(), and sig_pri_handle_subcmds().
typedef void(*) xfer_rsp_callback(void *data, int is_successful) |
Definition at line 6076 of file sig_pri.c.
06076 { 06077 OPT_ARG_KEYPAD = 0, 06078 OPT_ARG_AOC_REQUEST, 06079 06080 /* note: this entry _MUST_ be the last one in the enum */ 06081 OPT_ARG_ARRAY_SIZE, 06082 };
Definition at line 6071 of file sig_pri.c.
06071 { 06072 OPT_KEYPAD = (1 << 0), 06073 OPT_REVERSE_CHARGE = (1 << 1), /* Collect call */ 06074 OPT_AOC_REQUEST = (1 << 2), /* AOC Request */ 06075 };
static void apply_plan_to_number | ( | char * | buf, | |
size_t | size, | |||
const struct sig_pri_span * | pri, | |||
const char * | number, | |||
const int | plan | |||
) | [static] |
Definition at line 1330 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 sig_pri_party_number_convert().
01331 { 01332 switch (plan) { 01333 case PRI_INTERNATIONAL_ISDN: /* Q.931 dialplan == 0x11 international dialplan => prepend international prefix digits */ 01334 snprintf(buf, size, "%s%s", pri->internationalprefix, number); 01335 break; 01336 case PRI_NATIONAL_ISDN: /* Q.931 dialplan == 0x21 national dialplan => prepend national prefix digits */ 01337 snprintf(buf, size, "%s%s", pri->nationalprefix, number); 01338 break; 01339 case PRI_LOCAL_ISDN: /* Q.931 dialplan == 0x41 local dialplan => prepend local prefix digits */ 01340 snprintf(buf, size, "%s%s", pri->localprefix, number); 01341 break; 01342 case PRI_PRIVATE: /* Q.931 dialplan == 0x49 private dialplan => prepend private prefix digits */ 01343 snprintf(buf, size, "%s%s", pri->privateprefix, number); 01344 break; 01345 case PRI_UNKNOWN: /* Q.931 dialplan == 0x00 unknown dialplan => prepend unknown prefix digits */ 01346 snprintf(buf, size, "%s%s", pri->unknownprefix, number); 01347 break; 01348 default: /* other Q.931 dialplan => don't twiddle with callingnum */ 01349 snprintf(buf, size, "%s", number); 01350 break; 01351 } 01352 }
static unsigned char ast_pri_pack_hex_char | ( | char | c | ) | [static] |
Definition at line 623 of file sig_pri.c.
Referenced by ast_pri_pack_hex_string().
00624 { 00625 unsigned char res; 00626 00627 if (c < '0') { 00628 res = 0; 00629 } else if (c < ('9' + 1)) { 00630 res = c - '0'; 00631 } else if (c < 'A') { 00632 res = 0; 00633 } else if (c < ('F' + 1)) { 00634 res = c - 'A' + 10; 00635 } else if (c < 'a') { 00636 res = 0; 00637 } else if (c < ('f' + 1)) { 00638 res = c - 'a' + 10; 00639 } else { 00640 res = 0; 00641 } 00642 return res; 00643 }
static int ast_pri_pack_hex_string | ( | unsigned char * | dst, | |
char * | src, | |||
int | maxlen | |||
) | [static] |
Definition at line 662 of file sig_pri.c.
References ast_pri_pack_hex_char(), and len().
Referenced by sig_pri_party_subaddress_from_ast().
00663 { 00664 int res = 0; 00665 int len = strlen(src); 00666 00667 if (len > (2 * maxlen)) { 00668 len = 2 * maxlen; 00669 } 00670 00671 res = len / 2 + len % 2; 00672 00673 while (len > 1) { 00674 *dst = ast_pri_pack_hex_char(*src) << 4; 00675 src++; 00676 *dst |= ast_pri_pack_hex_char(*src); 00677 dst++, src++; 00678 len -= 2; 00679 } 00680 if (len) { /* 1 left */ 00681 *dst = ast_pri_pack_hex_char(*src) << 4; 00682 } 00683 return res; 00684 }
static int ast_to_pri_char_set | ( | enum AST_PARTY_CHAR_SET | ast_char_set | ) | [static] |
Definition at line 525 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().
00526 { 00527 int pri_char_set; 00528 00529 switch (ast_char_set) { 00530 default: 00531 case AST_PARTY_CHAR_SET_UNKNOWN: 00532 pri_char_set = PRI_CHAR_SET_UNKNOWN; 00533 break; 00534 case AST_PARTY_CHAR_SET_ISO8859_1: 00535 pri_char_set = PRI_CHAR_SET_ISO8859_1; 00536 break; 00537 case AST_PARTY_CHAR_SET_WITHDRAWN: 00538 pri_char_set = PRI_CHAR_SET_WITHDRAWN; 00539 break; 00540 case AST_PARTY_CHAR_SET_ISO8859_2: 00541 pri_char_set = PRI_CHAR_SET_ISO8859_2; 00542 break; 00543 case AST_PARTY_CHAR_SET_ISO8859_3: 00544 pri_char_set = PRI_CHAR_SET_ISO8859_3; 00545 break; 00546 case AST_PARTY_CHAR_SET_ISO8859_4: 00547 pri_char_set = PRI_CHAR_SET_ISO8859_4; 00548 break; 00549 case AST_PARTY_CHAR_SET_ISO8859_5: 00550 pri_char_set = PRI_CHAR_SET_ISO8859_5; 00551 break; 00552 case AST_PARTY_CHAR_SET_ISO8859_7: 00553 pri_char_set = PRI_CHAR_SET_ISO8859_7; 00554 break; 00555 case AST_PARTY_CHAR_SET_ISO10646_BMPSTRING: 00556 pri_char_set = PRI_CHAR_SET_ISO10646_BMPSTRING; 00557 break; 00558 case AST_PARTY_CHAR_SET_ISO10646_UTF_8STRING: 00559 pri_char_set = PRI_CHAR_SET_ISO10646_UTF_8STRING; 00560 break; 00561 } 00562 00563 return pri_char_set; 00564 }
static int ast_to_pri_presentation | ( | int | ast_presentation | ) | [static] |
Definition at line 426 of file sig_pri.c.
References AST_PRES_ALLOWED_NETWORK_NUMBER, AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN, AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, AST_PRES_NUMBER_NOT_AVAILABLE, AST_PRES_PROHIB_NETWORK_NUMBER, AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN, AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED, and AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN.
Referenced by sig_pri_party_name_from_ast(), and sig_pri_party_number_from_ast().
00427 { 00428 int pri_presentation; 00429 00430 switch (ast_presentation) { 00431 case AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED: 00432 pri_presentation = PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; 00433 break; 00434 case AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN: 00435 pri_presentation = PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN; 00436 break; 00437 case AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN: 00438 pri_presentation = PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN; 00439 break; 00440 case AST_PRES_ALLOWED_NETWORK_NUMBER: 00441 pri_presentation = PRES_ALLOWED_NETWORK_NUMBER; 00442 break; 00443 case AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED: 00444 pri_presentation = PRES_PROHIB_USER_NUMBER_NOT_SCREENED; 00445 break; 00446 case AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN: 00447 pri_presentation = PRES_PROHIB_USER_NUMBER_PASSED_SCREEN; 00448 break; 00449 case AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN: 00450 pri_presentation = PRES_PROHIB_USER_NUMBER_FAILED_SCREEN; 00451 break; 00452 case AST_PRES_PROHIB_NETWORK_NUMBER: 00453 pri_presentation = PRES_PROHIB_NETWORK_NUMBER; 00454 break; 00455 case AST_PRES_NUMBER_NOT_AVAILABLE: 00456 pri_presentation = PRES_NUMBER_NOT_AVAILABLE; 00457 break; 00458 default: 00459 pri_presentation = PRES_PROHIB_USER_NUMBER_NOT_SCREENED; 00460 break; 00461 } 00462 00463 return pri_presentation; 00464 }
static int ast_to_pri_reason | ( | enum AST_REDIRECTING_REASON | ast_reason | ) | [static] |
Definition at line 342 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().
00343 { 00344 int pri_reason; 00345 00346 switch (ast_reason) { 00347 case AST_REDIRECTING_REASON_USER_BUSY: 00348 pri_reason = PRI_REDIR_FORWARD_ON_BUSY; 00349 break; 00350 case AST_REDIRECTING_REASON_NO_ANSWER: 00351 pri_reason = PRI_REDIR_FORWARD_ON_NO_REPLY; 00352 break; 00353 case AST_REDIRECTING_REASON_UNCONDITIONAL: 00354 pri_reason = PRI_REDIR_UNCONDITIONAL; 00355 break; 00356 case AST_REDIRECTING_REASON_DEFLECTION: 00357 pri_reason = PRI_REDIR_DEFLECTION; 00358 break; 00359 case AST_REDIRECTING_REASON_UNKNOWN: 00360 default: 00361 pri_reason = PRI_REDIR_UNKNOWN; 00362 break; 00363 } 00364 00365 return pri_reason; 00366 }
static void build_status | ( | char * | s, | |
size_t | len, | |||
int | status, | |||
int | active | |||
) | [static] |
Definition at line 7353 of file sig_pri.c.
References DCHAN_NOTINALARM.
Referenced by sig_pri_cli_show_span(), and sig_pri_cli_show_spans().
07354 { 07355 if (!s || len < 1) { 07356 return; 07357 } 07358 s[0] = '\0'; 07359 if (!(status & DCHAN_NOTINALARM)) 07360 strncat(s, "In Alarm, ", len - strlen(s) - 1); 07361 if (status & DCHAN_UP) 07362 strncat(s, "Up", len - strlen(s) - 1); 07363 else 07364 strncat(s, "Down", len - strlen(s) - 1); 07365 if (active) 07366 strncat(s, ", Active", len - strlen(s) - 1); 07367 else 07368 strncat(s, ", Standby", len - strlen(s) - 1); 07369 s[len - 1] = '\0'; 07370 }
static char* dialplan2str | ( | int | dialplan | ) | [static] |
Definition at line 1322 of file sig_pri.c.
Referenced by sig_pri_call().
01323 { 01324 if (dialplan == -1) { 01325 return("Dynamically set dialplan in ISDN"); 01326 } 01327 return (pri_plan2str(dialplan)); 01328 }
static void* do_idle_thread | ( | void * | v_pvt | ) | [static] |
Definition at line 1514 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().
01515 { 01516 struct sig_pri_chan *pvt = v_pvt; 01517 struct ast_channel *chan = pvt->owner; 01518 struct ast_frame *f; 01519 char ex[80]; 01520 /* Wait up to 30 seconds for an answer */ 01521 int newms, ms = 30000; 01522 01523 ast_verb(3, "Initiating idle call on channel %s\n", chan->name); 01524 snprintf(ex, sizeof(ex), "%d/%s", pvt->channel, pvt->pri->idledial); 01525 if (ast_call(chan, ex, 0)) { 01526 ast_log(LOG_WARNING, "Idle dial failed on '%s' to '%s'\n", chan->name, ex); 01527 ast_hangup(chan); 01528 return NULL; 01529 } 01530 while ((newms = ast_waitfor(chan, ms)) > 0) { 01531 f = ast_read(chan); 01532 if (!f) { 01533 /* Got hangup */ 01534 break; 01535 } 01536 if (f->frametype == AST_FRAME_CONTROL) { 01537 switch (f->subclass.integer) { 01538 case AST_CONTROL_ANSWER: 01539 /* Launch the PBX */ 01540 ast_copy_string(chan->exten, pvt->pri->idleext, sizeof(chan->exten)); 01541 ast_copy_string(chan->context, pvt->pri->idlecontext, sizeof(chan->context)); 01542 chan->priority = 1; 01543 ast_verb(4, "Idle channel '%s' answered, sending to %s@%s\n", chan->name, chan->exten, chan->context); 01544 ast_pbx_run(chan); 01545 /* It's already hungup, return immediately */ 01546 return NULL; 01547 case AST_CONTROL_BUSY: 01548 ast_verb(4, "Idle channel '%s' busy, waiting...\n", chan->name); 01549 break; 01550 case AST_CONTROL_CONGESTION: 01551 ast_verb(4, "Idle channel '%s' congested, waiting...\n", chan->name); 01552 break; 01553 }; 01554 } 01555 ast_frfree(f); 01556 ms = newms; 01557 } 01558 /* Hangup the channel since nothing happend */ 01559 ast_hangup(chan); 01560 return NULL; 01561 }
static int pri_active_dchan_index | ( | struct sig_pri_span * | pri | ) | [static] |
Definition at line 957 of file sig_pri.c.
References ast_log(), sig_pri_span::dchans, LOG_WARNING, sig_pri_span::pri, and SIG_PRI_NUM_DCHANS.
00958 { 00959 int x; 00960 00961 for (x = 0; x < SIG_PRI_NUM_DCHANS; x++) { 00962 if ((pri->dchans[x] == pri->pri)) 00963 return x; 00964 } 00965 00966 ast_log(LOG_WARNING, "No active dchan found!\n"); 00967 return -1; 00968 }
static int pri_check_restart | ( | struct sig_pri_span * | pri | ) | [static] |
Definition at line 1355 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_span::span, SRVST_FAREND, and SRVST_NEAREND.
Referenced by pri_dchannel().
01356 { 01357 #if defined(HAVE_PRI_SERVICE_MESSAGES) 01358 tryanotherpos: 01359 #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */ 01360 do { 01361 pri->resetpos++; 01362 } while (pri->resetpos < pri->numchans 01363 && (!pri->pvts[pri->resetpos] 01364 || pri->pvts[pri->resetpos]->no_b_channel 01365 || pri->pvts[pri->resetpos]->call 01366 || pri->pvts[pri->resetpos]->resetting)); 01367 if (pri->resetpos < pri->numchans) { 01368 #if defined(HAVE_PRI_SERVICE_MESSAGES) 01369 unsigned why; 01370 01371 why = pri->pvts[pri->resetpos]->service_status; 01372 if (why) { 01373 ast_log(LOG_NOTICE, "span '%d' channel '%d' out-of-service (reason: %s), not sending RESTART\n", pri->span, 01374 pri->pvts[pri->resetpos]->channel, (why & SRVST_FAREND) ? (why & SRVST_NEAREND) ? "both ends" : "far end" : "near end"); 01375 goto tryanotherpos; 01376 } 01377 #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */ 01378 01379 /* Mark the channel as resetting and restart it */ 01380 pri->pvts[pri->resetpos]->resetting = 1; 01381 pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[pri->resetpos])); 01382 } else { 01383 pri->resetting = 0; 01384 time(&pri->lastreset); 01385 } 01386 return 0; 01387 }
static void* pri_dchannel | ( | void * | vpri | ) | [static] |
Definition at line 4250 of file sig_pri.c.
References ast_channel::_softhangup, 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::call, 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, 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_chan::resetting, sig_pri_span::resetting, sig_pri_span::sig, SIG_BRI_PTMP, sig_pri_handle_dchan_exception(), sig_pri_request(), sig_pri_span::span, and sig_pri_span::switchtype.
04251 { 04252 struct sig_pri_span *pri = vpri; 04253 pri_event *e; 04254 struct pollfd fds[SIG_PRI_NUM_DCHANS]; 04255 int res; 04256 int chanpos = 0; 04257 int x; 04258 struct ast_channel *c; 04259 struct timeval tv, lowest, *next; 04260 int doidling=0; 04261 char *cc; 04262 time_t t; 04263 int i, which=-1; 04264 int numdchans; 04265 pthread_t threadid; 04266 char ani2str[6]; 04267 char plancallingnum[AST_MAX_EXTENSION]; 04268 char plancallingani[AST_MAX_EXTENSION]; 04269 char calledtonstr[10]; 04270 struct timeval lastidle = { 0, 0 }; 04271 pthread_t p; 04272 struct ast_channel *idle; 04273 char idlen[80]; 04274 int nextidle = -1; 04275 int haveidles; 04276 int activeidles; 04277 04278 gettimeofday(&lastidle, NULL); 04279 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); 04280 04281 if (!ast_strlen_zero(pri->idledial) && !ast_strlen_zero(pri->idleext)) { 04282 /* Need to do idle dialing, check to be sure though */ 04283 cc = strchr(pri->idleext, '@'); 04284 if (cc) { 04285 *cc = '\0'; 04286 cc++; 04287 ast_copy_string(pri->idlecontext, cc, sizeof(pri->idlecontext)); 04288 #if 0 04289 /* Extensions may not be loaded yet */ 04290 if (!ast_exists_extension(NULL, pri->idlecontext, pri->idleext, 1, NULL)) 04291 ast_log(LOG_WARNING, "Extension '%s @ %s' does not exist\n", pri->idleext, pri->idlecontext); 04292 else 04293 #endif 04294 doidling = 1; 04295 } else 04296 ast_log(LOG_WARNING, "Idle dial string '%s' lacks '@context'\n", pri->idleext); 04297 } 04298 for (;;) { 04299 for (i = 0; i < SIG_PRI_NUM_DCHANS; i++) { 04300 if (!pri->dchans[i]) 04301 break; 04302 fds[i].fd = pri->fds[i]; 04303 fds[i].events = POLLIN | POLLPRI; 04304 fds[i].revents = 0; 04305 } 04306 numdchans = i; 04307 time(&t); 04308 ast_mutex_lock(&pri->lock); 04309 if (pri->switchtype != PRI_SWITCH_GR303_TMC && (pri->sig != SIG_BRI_PTMP) && (pri->resetinterval > 0)) { 04310 if (pri->resetting && pri_is_up(pri)) { 04311 if (pri->resetpos < 0) 04312 pri_check_restart(pri); 04313 } else { 04314 if (!pri->resetting && (t - pri->lastreset) >= pri->resetinterval) { 04315 pri->resetting = 1; 04316 pri->resetpos = -1; 04317 } 04318 } 04319 } 04320 /* Look for any idle channels if appropriate */ 04321 if (doidling && pri_is_up(pri)) { 04322 nextidle = -1; 04323 haveidles = 0; 04324 activeidles = 0; 04325 for (x = pri->numchans; x >= 0; x--) { 04326 if (pri->pvts[x] 04327 && !pri->pvts[x]->owner 04328 && !pri->pvts[x]->call 04329 && !pri->pvts[x]->no_b_channel) { 04330 if (haveidles < pri->minunused) { 04331 haveidles++; 04332 } else if (!pri->pvts[x]->resetting) { 04333 nextidle = x; 04334 break; 04335 } 04336 } else if (pri->pvts[x] && pri->pvts[x]->owner && pri->pvts[x]->isidlecall) 04337 activeidles++; 04338 } 04339 if (nextidle > -1) { 04340 if (ast_tvdiff_ms(ast_tvnow(), lastidle) > 1000) { 04341 /* Don't create a new idle call more than once per second */ 04342 snprintf(idlen, sizeof(idlen), "%d/%s", pri->pvts[nextidle]->channel, pri->idledial); 04343 idle = sig_pri_request(pri->pvts[nextidle], AST_FORMAT_ULAW, NULL, 0); 04344 if (idle) { 04345 pri->pvts[nextidle]->isidlecall = 1; 04346 if (ast_pthread_create_background(&p, NULL, do_idle_thread, pri->pvts[nextidle])) { 04347 ast_log(LOG_WARNING, "Unable to start new thread for idle channel '%s'\n", idle->name); 04348 ast_hangup(idle); 04349 } 04350 } else 04351 ast_log(LOG_WARNING, "Unable to request channel 'DAHDI/%s' for idle call\n", idlen); 04352 gettimeofday(&lastidle, NULL); 04353 } 04354 } else if ((haveidles < pri->minunused) && 04355 (activeidles > pri->minidle)) { 04356 /* Mark something for hangup if there is something 04357 that can be hungup */ 04358 for (x = pri->numchans; x >= 0; x--) { 04359 /* find a candidate channel */ 04360 if (pri->pvts[x] && pri->pvts[x]->owner && pri->pvts[x]->isidlecall) { 04361 pri->pvts[x]->owner->_softhangup |= AST_SOFTHANGUP_DEV; 04362 haveidles++; 04363 /* Stop if we have enough idle channels or 04364 can't spare any more active idle ones */ 04365 if ((haveidles >= pri->minunused) || 04366 (activeidles <= pri->minidle)) 04367 break; 04368 } 04369 } 04370 } 04371 } 04372 /* Start with reasonable max */ 04373 if (doidling || pri->resetting) { 04374 /* 04375 * Make sure we stop at least once per second if we're 04376 * monitoring idle channels 04377 */ 04378 lowest = ast_tv(1, 0); 04379 } else { 04380 /* Don't poll for more than 60 seconds */ 04381 lowest = ast_tv(60, 0); 04382 } 04383 for (i = 0; i < SIG_PRI_NUM_DCHANS; i++) { 04384 if (!pri->dchans[i]) { 04385 /* We scanned all D channels on this span. */ 04386 break; 04387 } 04388 next = pri_schedule_next(pri->dchans[i]); 04389 if (next) { 04390 /* We need relative time here */ 04391 tv = ast_tvsub(*next, ast_tvnow()); 04392 if (tv.tv_sec < 0) { 04393 /* 04394 * A timer has already expired. 04395 * By definition zero time is the lowest so we can quit early. 04396 */ 04397 lowest = ast_tv(0, 0); 04398 break; 04399 } 04400 if (ast_tvcmp(tv, lowest) < 0) { 04401 lowest = tv; 04402 } 04403 } 04404 } 04405 ast_mutex_unlock(&pri->lock); 04406 04407 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); 04408 pthread_testcancel(); 04409 e = NULL; 04410 res = poll(fds, numdchans, lowest.tv_sec * 1000 + lowest.tv_usec / 1000); 04411 pthread_testcancel(); 04412 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); 04413 04414 ast_mutex_lock(&pri->lock); 04415 if (!res) { 04416 for (which = 0; which < SIG_PRI_NUM_DCHANS; which++) { 04417 if (!pri->dchans[which]) 04418 break; 04419 /* Just a timeout, run the scheduler */ 04420 e = pri_schedule_run(pri->dchans[which]); 04421 if (e) 04422 break; 04423 } 04424 } else if (res > -1) { 04425 for (which = 0; which < SIG_PRI_NUM_DCHANS; which++) { 04426 if (!pri->dchans[which]) 04427 break; 04428 if (fds[which].revents & POLLPRI) { 04429 sig_pri_handle_dchan_exception(pri, which); 04430 } else if (fds[which].revents & POLLIN) { 04431 e = pri_check_event(pri->dchans[which]); 04432 } 04433 if (e) 04434 break; 04435 } 04436 } else if (errno != EINTR) 04437 ast_log(LOG_WARNING, "pri_event returned error %d (%s)\n", errno, strerror(errno)); 04438 04439 if (e) { 04440 if (pri->debug) { 04441 ast_verbose("Span: %d Processing event: %s\n", 04442 pri->span, pri_event2str(e->e)); 04443 } 04444 04445 if (e->e != PRI_EVENT_DCHAN_DOWN) { 04446 if (!(pri->dchanavail[which] & DCHAN_UP)) { 04447 ast_verb(2, "%s D-Channel on span %d up\n", pri_order(which), pri->span); 04448 } 04449 pri->dchanavail[which] |= DCHAN_UP; 04450 } else { 04451 if (pri->dchanavail[which] & DCHAN_UP) { 04452 ast_verb(2, "%s D-Channel on span %d down\n", pri_order(which), pri->span); 04453 } 04454 pri->dchanavail[which] &= ~DCHAN_UP; 04455 } 04456 04457 if ((e->e != PRI_EVENT_DCHAN_UP) && (e->e != PRI_EVENT_DCHAN_DOWN) && (pri->pri != pri->dchans[which])) 04458 /* Must be an NFAS group that has the secondary dchan active */ 04459 pri->pri = pri->dchans[which]; 04460 04461 switch (e->e) { 04462 case PRI_EVENT_DCHAN_UP: 04463 pri->no_d_channels = 0; 04464 if (!pri->pri) pri_find_dchan(pri); 04465 04466 /* Note presense of D-channel */ 04467 time(&pri->lastreset); 04468 04469 /* Restart in 5 seconds */ 04470 if (pri->resetinterval > -1) { 04471 pri->lastreset -= pri->resetinterval; 04472 pri->lastreset += 5; 04473 } 04474 pri->resetting = 0; 04475 /* Take the channels from inalarm condition */ 04476 for (i = 0; i < pri->numchans; i++) { 04477 if (pri->pvts[i]) { 04478 sig_pri_set_alarm(pri->pvts[i], 0); 04479 } 04480 } 04481 sig_pri_span_devstate_changed(pri); 04482 break; 04483 case PRI_EVENT_DCHAN_DOWN: 04484 pri_find_dchan(pri); 04485 if (!pri_is_up(pri)) { 04486 pri->resetting = 0; 04487 if (pri->sig == SIG_BRI_PTMP) { 04488 /* For PTMP connections with non persistent layer 2 we want 04489 * to *not* declare inalarm unless there actually is an alarm */ 04490 break; 04491 } 04492 /* Hangup active channels and put them in alarm mode */ 04493 for (i = 0; i < pri->numchans; i++) { 04494 struct sig_pri_chan *p = pri->pvts[i]; 04495 if (p) { 04496 if (!p->pri || !p->pri->pri || pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0) { 04497 /* T309 is not enabled : hangup calls when alarm occurs */ 04498 if (p->call) { 04499 if (p->pri && p->pri->pri) { 04500 pri_hangup(p->pri->pri, p->call, -1); 04501 pri_destroycall(p->pri->pri, p->call); 04502 p->call = NULL; 04503 } else 04504 ast_log(LOG_WARNING, "The PRI Call have not been destroyed\n"); 04505 } 04506 if (p->owner) 04507 p->owner->_softhangup |= AST_SOFTHANGUP_DEV; 04508 } 04509 sig_pri_set_alarm(p, 1); 04510 } 04511 } 04512 sig_pri_span_devstate_changed(pri); 04513 } 04514 break; 04515 case PRI_EVENT_RESTART: 04516 if (e->restart.channel > -1) { 04517 chanpos = pri_find_principle(pri, e->restart.channel, NULL); 04518 if (chanpos < 0) 04519 ast_log(LOG_WARNING, "Restart requested on odd/unavailable channel number %d/%d on span %d\n", 04520 PRI_SPAN(e->restart.channel), PRI_CHANNEL(e->restart.channel), pri->span); 04521 else { 04522 int skipit = 0; 04523 #if defined(HAVE_PRI_SERVICE_MESSAGES) 04524 unsigned why; 04525 04526 why = pri->pvts[chanpos]->service_status; 04527 if (why) { 04528 ast_log(LOG_NOTICE, 04529 "span '%d' channel '%d' out-of-service (reason: %s), ignoring RESTART\n", 04530 pri->span, PRI_CHANNEL(e->restart.channel), 04531 (why & SRVST_FAREND) ? (why & SRVST_NEAREND) ? "both ends" : "far end" : "near end"); 04532 skipit = 1; 04533 } 04534 #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */ 04535 sig_pri_lock_private(pri->pvts[chanpos]); 04536 if (!skipit) { 04537 ast_verb(3, "B-channel %d/%d restarted on span %d\n", 04538 PRI_SPAN(e->restart.channel), PRI_CHANNEL(e->restart.channel), pri->span); 04539 if (pri->pvts[chanpos]->call) { 04540 pri_destroycall(pri->pri, pri->pvts[chanpos]->call); 04541 pri->pvts[chanpos]->call = NULL; 04542 } 04543 } 04544 /* Force soft hangup if appropriate */ 04545 if (pri->pvts[chanpos]->owner) 04546 pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV; 04547 sig_pri_unlock_private(pri->pvts[chanpos]); 04548 } 04549 } else { 04550 ast_verb(3, "Restart requested on entire span %d\n", pri->span); 04551 for (x = 0; x < pri->numchans; x++) 04552 if (pri->pvts[x]) { 04553 sig_pri_lock_private(pri->pvts[x]); 04554 if (pri->pvts[x]->call) { 04555 pri_destroycall(pri->pri, pri->pvts[x]->call); 04556 pri->pvts[x]->call = NULL; 04557 } 04558 if (pri->pvts[x]->owner) 04559 pri->pvts[x]->owner->_softhangup |= AST_SOFTHANGUP_DEV; 04560 sig_pri_unlock_private(pri->pvts[x]); 04561 } 04562 } 04563 break; 04564 case PRI_EVENT_KEYPAD_DIGIT: 04565 if (sig_pri_is_cis_call(e->digit.channel)) { 04566 sig_pri_handle_cis_subcmds(pri, e->e, e->digit.subcmds, 04567 e->digit.call); 04568 break; 04569 } 04570 chanpos = pri_find_principle(pri, e->digit.channel, e->digit.call); 04571 if (chanpos < 0) { 04572 ast_log(LOG_WARNING, "KEYPAD_DIGITs received on unconfigured channel %d/%d span %d\n", 04573 PRI_SPAN(e->digit.channel), PRI_CHANNEL(e->digit.channel), pri->span); 04574 } else { 04575 chanpos = pri_fixup_principle(pri, chanpos, e->digit.call); 04576 if (chanpos > -1) { 04577 sig_pri_lock_private(pri->pvts[chanpos]); 04578 sig_pri_handle_subcmds(pri, chanpos, e->e, e->digit.channel, 04579 e->digit.subcmds, e->digit.call); 04580 /* queue DTMF frame if the PBX for this call was already started (we're forwarding KEYPAD_DIGITs further on */ 04581 if ((pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING) 04582 && pri->pvts[chanpos]->call == e->digit.call 04583 && pri->pvts[chanpos]->owner) { 04584 /* how to do that */ 04585 int digitlen = strlen(e->digit.digits); 04586 int i; 04587 04588 for (i = 0; i < digitlen; i++) { 04589 struct ast_frame f = { AST_FRAME_DTMF, .subclass.integer = e->digit.digits[i], }; 04590 04591 pri_queue_frame(pri, chanpos, &f); 04592 } 04593 } 04594 sig_pri_unlock_private(pri->pvts[chanpos]); 04595 } 04596 } 04597 break; 04598 04599 case PRI_EVENT_INFO_RECEIVED: 04600 if (sig_pri_is_cis_call(e->ring.channel)) { 04601 sig_pri_handle_cis_subcmds(pri, e->e, e->ring.subcmds, 04602 e->ring.call); 04603 break; 04604 } 04605 chanpos = pri_find_principle(pri, e->ring.channel, e->ring.call); 04606 if (chanpos < 0) { 04607 ast_log(LOG_WARNING, "INFO received on unconfigured channel %d/%d span %d\n", 04608 PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span); 04609 } else { 04610 chanpos = pri_fixup_principle(pri, chanpos, e->ring.call); 04611 if (chanpos > -1) { 04612 sig_pri_lock_private(pri->pvts[chanpos]); 04613 sig_pri_handle_subcmds(pri, chanpos, e->e, e->ring.channel, 04614 e->ring.subcmds, e->ring.call); 04615 /* queue DTMF frame if the PBX for this call was already started (we're forwarding INFORMATION further on */ 04616 if ((pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING) 04617 && pri->pvts[chanpos]->call == e->ring.call 04618 && pri->pvts[chanpos]->owner) { 04619 /* how to do that */ 04620 int digitlen = strlen(e->ring.callednum); 04621 int i; 04622 04623 for (i = 0; i < digitlen; i++) { 04624 struct ast_frame f = { AST_FRAME_DTMF, .subclass.integer = e->ring.callednum[i], }; 04625 04626 pri_queue_frame(pri, chanpos, &f); 04627 } 04628 } 04629 sig_pri_unlock_private(pri->pvts[chanpos]); 04630 } 04631 } 04632 break; 04633 #if defined(HAVE_PRI_SERVICE_MESSAGES) 04634 case PRI_EVENT_SERVICE: 04635 chanpos = pri_find_principle(pri, e->service.channel, NULL); 04636 if (chanpos < 0) { 04637 ast_log(LOG_WARNING, "Received service change status %d on unconfigured channel %d/%d span %d\n", 04638 e->service_ack.changestatus, PRI_SPAN(e->service_ack.channel), PRI_CHANNEL(e->service_ack.channel), pri->span); 04639 } else { 04640 char db_chan_name[20]; 04641 char db_answer[5]; 04642 int ch; 04643 unsigned *why; 04644 04645 ch = pri->pvts[chanpos]->channel; 04646 snprintf(db_chan_name, sizeof(db_chan_name), "%s/%d:%d", dahdi_db, pri->span, ch); 04647 why = &pri->pvts[chanpos]->service_status; 04648 switch (e->service.changestatus) { 04649 case 0: /* in-service */ 04650 /* Far end wants to be in service now. */ 04651 ast_db_del(db_chan_name, SRVST_DBKEY); 04652 *why &= ~SRVST_FAREND; 04653 if (*why) { 04654 snprintf(db_answer, sizeof(db_answer), "%s:%u", 04655 SRVST_TYPE_OOS, *why); 04656 ast_db_put(db_chan_name, SRVST_DBKEY, db_answer); 04657 } else { 04658 sig_pri_span_devstate_changed(pri); 04659 } 04660 break; 04661 case 2: /* out-of-service */ 04662 /* Far end wants to be out-of-service now. */ 04663 ast_db_del(db_chan_name, SRVST_DBKEY); 04664 *why |= SRVST_FAREND; 04665 snprintf(db_answer, sizeof(db_answer), "%s:%u", SRVST_TYPE_OOS, 04666 *why); 04667 ast_db_put(db_chan_name, SRVST_DBKEY, db_answer); 04668 sig_pri_span_devstate_changed(pri); 04669 break; 04670 default: 04671 ast_log(LOG_ERROR, "Huh? changestatus is: %d\n", e->service.changestatus); 04672 break; 04673 } 04674 ast_log(LOG_NOTICE, "Channel %d/%d span %d (logical: %d) received a change of service message, status '%d'\n", 04675 PRI_SPAN(e->service.channel), PRI_CHANNEL(e->service.channel), pri->span, ch, e->service.changestatus); 04676 } 04677 break; 04678 case PRI_EVENT_SERVICE_ACK: 04679 chanpos = pri_find_principle(pri, e->service_ack.channel, NULL); 04680 if (chanpos < 0) { 04681 ast_log(LOG_WARNING, "Received service acknowledge change status '%d' on unconfigured channel %d/%d span %d\n", 04682 e->service_ack.changestatus, PRI_SPAN(e->service_ack.channel), PRI_CHANNEL(e->service_ack.channel), pri->span); 04683 } else { 04684 ast_debug(2, "Channel %d/%d span %d received a change os service acknowledgement message, status '%d'\n", 04685 PRI_SPAN(e->service_ack.channel), PRI_CHANNEL(e->service_ack.channel), pri->span, e->service_ack.changestatus); 04686 } 04687 break; 04688 #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */ 04689 case PRI_EVENT_RING: 04690 if (!ast_strlen_zero(pri->msn_list) 04691 && !sig_pri_msn_match(pri->msn_list, e->ring.callednum)) { 04692 /* The call is not for us so ignore it. */ 04693 ast_verb(3, 04694 "Ignoring call to '%s' on span %d. Its not in the MSN list: %s\n", 04695 e->ring.callednum, pri->span, pri->msn_list); 04696 pri_destroycall(pri->pri, e->ring.call); 04697 break; 04698 } 04699 if (sig_pri_is_cis_call(e->ring.channel)) { 04700 sig_pri_handle_cis_subcmds(pri, e->e, e->ring.subcmds, 04701 e->ring.call); 04702 break; 04703 } 04704 if (e->ring.channel == -1 || PRI_CHANNEL(e->ring.channel) == 0xFF) { 04705 /* Any channel requested. */ 04706 chanpos = pri_find_empty_chan(pri, 1); 04707 } else if (PRI_CHANNEL(e->ring.channel) == 0x00) { 04708 /* No channel specified. */ 04709 #if defined(HAVE_PRI_CALL_WAITING) 04710 if (!pri->allow_call_waiting_calls) 04711 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 04712 { 04713 /* We will not accept incoming call waiting calls. */ 04714 pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_INCOMPATIBLE_DESTINATION); 04715 break; 04716 } 04717 #if defined(HAVE_PRI_CALL_WAITING) 04718 chanpos = pri_find_empty_nobch(pri); 04719 if (chanpos < 0) { 04720 /* We could not find/create a call interface. */ 04721 pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION); 04722 break; 04723 } 04724 /* Setup the call interface to use. */ 04725 sig_pri_init_config(pri->pvts[chanpos], pri); 04726 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 04727 } else { 04728 /* A channel is specified. */ 04729 chanpos = pri_find_principle(pri, e->ring.channel, e->ring.call); 04730 } 04731 /* if no channel specified find one empty */ 04732 if (chanpos < 0) { 04733 ast_log(LOG_WARNING, "Ring requested on unconfigured channel %d/%d span %d\n", 04734 PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span); 04735 } else { 04736 sig_pri_lock_private(pri->pvts[chanpos]); 04737 if (pri->pvts[chanpos]->owner) { 04738 if (pri->pvts[chanpos]->call == e->ring.call) { 04739 ast_log(LOG_WARNING, "Duplicate setup requested on channel %d/%d already in use on span %d\n", 04740 PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span); 04741 sig_pri_unlock_private(pri->pvts[chanpos]); 04742 break; 04743 } else { 04744 /* This is where we handle initial glare */ 04745 ast_debug(1, "Ring requested on channel %d/%d already in use or previously requested on span %d. Attempting to renegotiating channel.\n", 04746 PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span); 04747 sig_pri_unlock_private(pri->pvts[chanpos]); 04748 chanpos = -1; 04749 } 04750 } 04751 if (chanpos > -1) 04752 sig_pri_unlock_private(pri->pvts[chanpos]); 04753 } 04754 if ((chanpos < 0) && (e->ring.flexible)) 04755 chanpos = pri_find_empty_chan(pri, 1); 04756 if (chanpos > -1) { 04757 sig_pri_lock_private(pri->pvts[chanpos]); 04758 pri->pvts[chanpos]->call = e->ring.call; 04759 04760 /* Use plancallingnum as a scratch buffer since it is initialized next. */ 04761 apply_plan_to_number(plancallingnum, sizeof(plancallingnum), pri, 04762 e->ring.redirectingnum, e->ring.callingplanrdnis); 04763 sig_pri_set_rdnis(pri->pvts[chanpos], plancallingnum); 04764 04765 /* Setup caller-id info */ 04766 apply_plan_to_number(plancallingnum, sizeof(plancallingnum), pri, e->ring.callingnum, e->ring.callingplan); 04767 pri->pvts[chanpos]->cid_ani2 = 0; 04768 if (pri->pvts[chanpos]->use_callerid) { 04769 ast_shrink_phone_number(plancallingnum); 04770 ast_copy_string(pri->pvts[chanpos]->cid_num, plancallingnum, sizeof(pri->pvts[chanpos]->cid_num)); 04771 #ifdef PRI_ANI 04772 if (!ast_strlen_zero(e->ring.callingani)) { 04773 apply_plan_to_number(plancallingani, sizeof(plancallingani), pri, e->ring.callingani, e->ring.callingplanani); 04774 ast_shrink_phone_number(plancallingani); 04775 ast_copy_string(pri->pvts[chanpos]->cid_ani, plancallingani, sizeof(pri->pvts[chanpos]->cid_ani)); 04776 } else { 04777 pri->pvts[chanpos]->cid_ani[0] = '\0'; 04778 } 04779 #endif 04780 pri->pvts[chanpos]->cid_subaddr[0] = '\0'; 04781 #if defined(HAVE_PRI_SUBADDR) 04782 if (e->ring.calling.subaddress.valid) { 04783 struct ast_party_subaddress calling_subaddress; 04784 04785 ast_party_subaddress_init(&calling_subaddress); 04786 sig_pri_set_subaddress(&calling_subaddress, 04787 &e->ring.calling.subaddress); 04788 if (calling_subaddress.str) { 04789 ast_copy_string(pri->pvts[chanpos]->cid_subaddr, 04790 calling_subaddress.str, 04791 sizeof(pri->pvts[chanpos]->cid_subaddr)); 04792 } 04793 ast_party_subaddress_free(&calling_subaddress); 04794 } 04795 #endif /* defined(HAVE_PRI_SUBADDR) */ 04796 ast_copy_string(pri->pvts[chanpos]->cid_name, e->ring.callingname, sizeof(pri->pvts[chanpos]->cid_name)); 04797 pri->pvts[chanpos]->cid_ton = e->ring.callingplan; /* this is the callingplan (TON/NPI), e->ring.callingplan>>4 would be the TON */ 04798 pri->pvts[chanpos]->callingpres = e->ring.callingpres; 04799 if (e->ring.ani2 >= 0) { 04800 pri->pvts[chanpos]->cid_ani2 = e->ring.ani2; 04801 } 04802 } else { 04803 pri->pvts[chanpos]->cid_num[0] = '\0'; 04804 pri->pvts[chanpos]->cid_subaddr[0] = '\0'; 04805 pri->pvts[chanpos]->cid_ani[0] = '\0'; 04806 pri->pvts[chanpos]->cid_name[0] = '\0'; 04807 pri->pvts[chanpos]->cid_ton = 0; 04808 pri->pvts[chanpos]->callingpres = 0; 04809 } 04810 04811 /* Setup the user tag for party id's from this device for this call. */ 04812 if (pri->append_msn_to_user_tag) { 04813 snprintf(pri->pvts[chanpos]->user_tag, 04814 sizeof(pri->pvts[chanpos]->user_tag), "%s_%s", 04815 pri->initial_user_tag, 04816 pri->nodetype == PRI_NETWORK 04817 ? plancallingnum : e->ring.callednum); 04818 } else { 04819 ast_copy_string(pri->pvts[chanpos]->user_tag, 04820 pri->initial_user_tag, sizeof(pri->pvts[chanpos]->user_tag)); 04821 } 04822 04823 sig_pri_set_caller_id(pri->pvts[chanpos]); 04824 04825 /* Set DNID on all incoming calls -- even immediate */ 04826 sig_pri_set_dnid(pri->pvts[chanpos], e->ring.callednum); 04827 04828 /* If immediate=yes go to s|1 */ 04829 if (pri->pvts[chanpos]->immediate) { 04830 ast_verb(3, "Going to extension s|1 because of immediate=yes\n"); 04831 pri->pvts[chanpos]->exten[0] = 's'; 04832 pri->pvts[chanpos]->exten[1] = '\0'; 04833 } 04834 /* Get called number */ 04835 else if (!ast_strlen_zero(e->ring.callednum)) { 04836 ast_copy_string(pri->pvts[chanpos]->exten, e->ring.callednum, sizeof(pri->pvts[chanpos]->exten)); 04837 } else if (pri->overlapdial) 04838 pri->pvts[chanpos]->exten[0] = '\0'; 04839 else { 04840 /* Some PRI circuits are set up to send _no_ digits. Handle them as 's'. */ 04841 pri->pvts[chanpos]->exten[0] = 's'; 04842 pri->pvts[chanpos]->exten[1] = '\0'; 04843 } 04844 /* No number yet, but received "sending complete"? */ 04845 if (e->ring.complete && (ast_strlen_zero(e->ring.callednum))) { 04846 ast_verb(3, "Going to extension s|1 because of Complete received\n"); 04847 pri->pvts[chanpos]->exten[0] = 's'; 04848 pri->pvts[chanpos]->exten[1] = '\0'; 04849 } 04850 04851 /* Make sure extension exists (or in overlap dial mode, can exist) */ 04852 if (((pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING) && ast_canmatch_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) || 04853 ast_exists_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) { 04854 /* Setup law */ 04855 if (e->ring.complete || !(pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)) { 04856 /* Just announce proceeding */ 04857 pri->pvts[chanpos]->call_level = SIG_PRI_CALL_LEVEL_PROCEEDING; 04858 pri_proceeding(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 0); 04859 } else if (pri->switchtype == PRI_SWITCH_GR303_TMC) { 04860 pri->pvts[chanpos]->call_level = SIG_PRI_CALL_LEVEL_CONNECT; 04861 pri_answer(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 1); 04862 } else { 04863 pri->pvts[chanpos]->call_level = SIG_PRI_CALL_LEVEL_OVERLAP; 04864 pri_need_more_info(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 1); 04865 } 04866 04867 /* Start PBX */ 04868 if (!e->ring.complete 04869 && (pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING) 04870 && ast_matchmore_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) { 04871 /* 04872 * Release the PRI lock while we create the channel 04873 * so other threads can send D channel messages. 04874 */ 04875 ast_mutex_unlock(&pri->lock); 04876 c = sig_pri_new_ast_channel(pri->pvts[chanpos], 04877 AST_STATE_RESERVED, 04878 (e->ring.layer1 == PRI_LAYER_1_ALAW) 04879 ? SIG_PRI_ALAW : SIG_PRI_ULAW, 04880 e->ring.ctype, pri->pvts[chanpos]->exten, NULL); 04881 ast_mutex_lock(&pri->lock); 04882 if (c) { 04883 #if defined(HAVE_PRI_SUBADDR) 04884 if (e->ring.calling.subaddress.valid) { 04885 /* Set Calling Subaddress */ 04886 sig_pri_lock_owner(pri, chanpos); 04887 sig_pri_set_subaddress( 04888 &pri->pvts[chanpos]->owner->caller.id.subaddress, 04889 &e->ring.calling.subaddress); 04890 if (!e->ring.calling.subaddress.type 04891 && !ast_strlen_zero( 04892 (char *) e->ring.calling.subaddress.data)) { 04893 /* NSAP */ 04894 pbx_builtin_setvar_helper(c, "CALLINGSUBADDR", 04895 (char *) e->ring.calling.subaddress.data); 04896 } 04897 ast_channel_unlock(c); 04898 } 04899 if (e->ring.called_subaddress.valid) { 04900 /* Set Called Subaddress */ 04901 sig_pri_lock_owner(pri, chanpos); 04902 sig_pri_set_subaddress( 04903 &pri->pvts[chanpos]->owner->dialed.subaddress, 04904 &e->ring.called_subaddress); 04905 if (!e->ring.called_subaddress.type 04906 && !ast_strlen_zero( 04907 (char *) e->ring.called_subaddress.data)) { 04908 /* NSAP */ 04909 pbx_builtin_setvar_helper(c, "CALLEDSUBADDR", 04910 (char *) e->ring.called_subaddress.data); 04911 } 04912 ast_channel_unlock(c); 04913 } 04914 #else 04915 if (!ast_strlen_zero(e->ring.callingsubaddr)) { 04916 pbx_builtin_setvar_helper(c, "CALLINGSUBADDR", e->ring.callingsubaddr); 04917 } 04918 #endif /* !defined(HAVE_PRI_SUBADDR) */ 04919 if (e->ring.ani2 >= 0) { 04920 snprintf(ani2str, sizeof(ani2str), "%d", e->ring.ani2); 04921 pbx_builtin_setvar_helper(c, "ANI2", ani2str); 04922 } 04923 04924 #ifdef SUPPORT_USERUSER 04925 if (!ast_strlen_zero(e->ring.useruserinfo)) { 04926 pbx_builtin_setvar_helper(c, "USERUSERINFO", e->ring.useruserinfo); 04927 } 04928 #endif 04929 04930 snprintf(calledtonstr, sizeof(calledtonstr), "%d", e->ring.calledplan); 04931 pbx_builtin_setvar_helper(c, "CALLEDTON", calledtonstr); 04932 if (e->ring.redirectingreason >= 0) { 04933 /* This is now just a status variable. Use REDIRECTING() dialplan function. */ 04934 pbx_builtin_setvar_helper(c, "PRIREDIRECTREASON", redirectingreason2str(e->ring.redirectingreason)); 04935 } 04936 #if defined(HAVE_PRI_REVERSE_CHARGE) 04937 pri->pvts[chanpos]->reverse_charging_indication = e->ring.reversecharge; 04938 #endif 04939 #if defined(HAVE_PRI_SETUP_KEYPAD) 04940 ast_copy_string(pri->pvts[chanpos]->keypad_digits, 04941 e->ring.keypad_digits, 04942 sizeof(pri->pvts[chanpos]->keypad_digits)); 04943 #endif /* defined(HAVE_PRI_SETUP_KEYPAD) */ 04944 04945 sig_pri_handle_subcmds(pri, chanpos, e->e, e->ring.channel, 04946 e->ring.subcmds, e->ring.call); 04947 04948 if (!pri->pvts[chanpos]->digital 04949 && !pri->pvts[chanpos]->no_b_channel) { 04950 /* 04951 * Call has a channel. 04952 * Indicate that we are providing dialtone. 04953 */ 04954 pri->pvts[chanpos]->progress = 1;/* No need to send plain PROGRESS again. */ 04955 #ifdef HAVE_PRI_PROG_W_CAUSE 04956 pri_progress_with_cause(pri->pri, e->ring.call, 04957 PVT_TO_CHANNEL(pri->pvts[chanpos]), 1, -1);/* no cause at all */ 04958 #else 04959 pri_progress(pri->pri, e->ring.call, 04960 PVT_TO_CHANNEL(pri->pvts[chanpos]), 1); 04961 #endif 04962 } 04963 } 04964 if (c && !ast_pthread_create_detached(&threadid, NULL, pri_ss_thread, pri->pvts[chanpos])) { 04965 ast_verb(3, "Accepting overlap call from '%s' to '%s' on channel %d/%d, span %d\n", 04966 plancallingnum, S_OR(pri->pvts[chanpos]->exten, "<unspecified>"), 04967 pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span); 04968 } else { 04969 ast_log(LOG_WARNING, "Unable to start PBX on channel %d/%d, span %d\n", 04970 pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span); 04971 if (c) 04972 ast_hangup(c); 04973 else { 04974 pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_SWITCH_CONGESTION); 04975 pri->pvts[chanpos]->call = NULL; 04976 } 04977 } 04978 } else { 04979 /* 04980 * Release the PRI lock while we create the channel 04981 * so other threads can send D channel messages. 04982 */ 04983 ast_mutex_unlock(&pri->lock); 04984 c = sig_pri_new_ast_channel(pri->pvts[chanpos], 04985 AST_STATE_RING, 04986 (e->ring.layer1 == PRI_LAYER_1_ALAW) 04987 ? SIG_PRI_ALAW : SIG_PRI_ULAW, e->ring.ctype, 04988 pri->pvts[chanpos]->exten, NULL); 04989 ast_mutex_lock(&pri->lock); 04990 if (c) { 04991 /* 04992 * It is reasonably safe to set the following 04993 * channel variables while the PRI and DAHDI private 04994 * structures are locked. The PBX has not been 04995 * started yet and it is unlikely that any other task 04996 * will do anything with the channel we have just 04997 * created. 04998 */ 04999 #if defined(HAVE_PRI_SUBADDR) 05000 if (e->ring.calling.subaddress.valid) { 05001 /* Set Calling Subaddress */ 05002 sig_pri_lock_owner(pri, chanpos); 05003 sig_pri_set_subaddress( 05004 &pri->pvts[chanpos]->owner->caller.id.subaddress, 05005 &e->ring.calling.subaddress); 05006 if (!e->ring.calling.subaddress.type 05007 && !ast_strlen_zero( 05008 (char *) e->ring.calling.subaddress.data)) { 05009 /* NSAP */ 05010 pbx_builtin_setvar_helper(c, "CALLINGSUBADDR", 05011 (char *) e->ring.calling.subaddress.data); 05012 } 05013 ast_channel_unlock(c); 05014 } 05015 if (e->ring.called_subaddress.valid) { 05016 /* Set Called Subaddress */ 05017 sig_pri_lock_owner(pri, chanpos); 05018 sig_pri_set_subaddress( 05019 &pri->pvts[chanpos]->owner->dialed.subaddress, 05020 &e->ring.called_subaddress); 05021 if (!e->ring.called_subaddress.type 05022 && !ast_strlen_zero( 05023 (char *) e->ring.called_subaddress.data)) { 05024 /* NSAP */ 05025 pbx_builtin_setvar_helper(c, "CALLEDSUBADDR", 05026 (char *) e->ring.called_subaddress.data); 05027 } 05028 ast_channel_unlock(c); 05029 } 05030 #else 05031 if (!ast_strlen_zero(e->ring.callingsubaddr)) { 05032 pbx_builtin_setvar_helper(c, "CALLINGSUBADDR", e->ring.callingsubaddr); 05033 } 05034 #endif /* !defined(HAVE_PRI_SUBADDR) */ 05035 if (e->ring.ani2 >= 0) { 05036 snprintf(ani2str, sizeof(ani2str), "%d", e->ring.ani2); 05037 pbx_builtin_setvar_helper(c, "ANI2", ani2str); 05038 } 05039 05040 #ifdef SUPPORT_USERUSER 05041 if (!ast_strlen_zero(e->ring.useruserinfo)) { 05042 pbx_builtin_setvar_helper(c, "USERUSERINFO", e->ring.useruserinfo); 05043 } 05044 #endif 05045 05046 if (e->ring.redirectingreason >= 0) { 05047 /* This is now just a status variable. Use REDIRECTING() dialplan function. */ 05048 pbx_builtin_setvar_helper(c, "PRIREDIRECTREASON", redirectingreason2str(e->ring.redirectingreason)); 05049 } 05050 #if defined(HAVE_PRI_REVERSE_CHARGE) 05051 pri->pvts[chanpos]->reverse_charging_indication = e->ring.reversecharge; 05052 #endif 05053 #if defined(HAVE_PRI_SETUP_KEYPAD) 05054 ast_copy_string(pri->pvts[chanpos]->keypad_digits, 05055 e->ring.keypad_digits, 05056 sizeof(pri->pvts[chanpos]->keypad_digits)); 05057 #endif /* defined(HAVE_PRI_SETUP_KEYPAD) */ 05058 05059 snprintf(calledtonstr, sizeof(calledtonstr), "%d", e->ring.calledplan); 05060 pbx_builtin_setvar_helper(c, "CALLEDTON", calledtonstr); 05061 05062 sig_pri_handle_subcmds(pri, chanpos, e->e, e->ring.channel, 05063 e->ring.subcmds, e->ring.call); 05064 05065 } 05066 if (c && !ast_pbx_start(c)) { 05067 ast_verb(3, "Accepting call from '%s' to '%s' on channel %d/%d, span %d\n", 05068 plancallingnum, pri->pvts[chanpos]->exten, 05069 pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span); 05070 sig_pri_set_echocanceller(pri->pvts[chanpos], 1); 05071 } else { 05072 ast_log(LOG_WARNING, "Unable to start PBX on channel %d/%d, span %d\n", 05073 pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span); 05074 if (c) { 05075 ast_hangup(c); 05076 } else { 05077 pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_SWITCH_CONGESTION); 05078 pri->pvts[chanpos]->call = NULL; 05079 } 05080 } 05081 } 05082 } else { 05083 ast_verb(3, "Extension '%s' in context '%s' from '%s' does not exist. Rejecting call on channel %d/%d, span %d\n", 05084 pri->pvts[chanpos]->exten, pri->pvts[chanpos]->context, pri->pvts[chanpos]->cid_num, pri->pvts[chanpos]->logicalspan, 05085 pri->pvts[chanpos]->prioffset, pri->span); 05086 pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_UNALLOCATED); 05087 pri->pvts[chanpos]->call = NULL; 05088 pri->pvts[chanpos]->exten[0] = '\0'; 05089 } 05090 sig_pri_unlock_private(pri->pvts[chanpos]); 05091 } else { 05092 if (e->ring.flexible) 05093 pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION); 05094 else 05095 pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_REQUESTED_CHAN_UNAVAIL); 05096 } 05097 break; 05098 case PRI_EVENT_RINGING: 05099 if (sig_pri_is_cis_call(e->ringing.channel)) { 05100 sig_pri_handle_cis_subcmds(pri, e->e, e->ringing.subcmds, 05101 e->ringing.call); 05102 break; 05103 } 05104 chanpos = pri_find_principle(pri, e->ringing.channel, e->ringing.call); 05105 if (chanpos < 0) { 05106 ast_log(LOG_WARNING, "Ringing requested on unconfigured channel %d/%d span %d\n", 05107 PRI_SPAN(e->ringing.channel), PRI_CHANNEL(e->ringing.channel), pri->span); 05108 } else { 05109 chanpos = pri_fixup_principle(pri, chanpos, e->ringing.call); 05110 if (chanpos < 0) { 05111 ast_log(LOG_WARNING, "Ringing requested on channel %d/%d not in use on span %d\n", 05112 PRI_SPAN(e->ringing.channel), PRI_CHANNEL(e->ringing.channel), pri->span); 05113 } else { 05114 sig_pri_lock_private(pri->pvts[chanpos]); 05115 05116 sig_pri_handle_subcmds(pri, chanpos, e->e, e->ringing.channel, 05117 e->ringing.subcmds, e->ringing.call); 05118 sig_pri_cc_generic_check(pri, chanpos, AST_CC_CCNR); 05119 sig_pri_set_echocanceller(pri->pvts[chanpos], 1); 05120 pri_queue_control(pri, chanpos, AST_CONTROL_RINGING); 05121 if (pri->pvts[chanpos]->call_level < SIG_PRI_CALL_LEVEL_ALERTING) { 05122 pri->pvts[chanpos]->call_level = SIG_PRI_CALL_LEVEL_ALERTING; 05123 } 05124 05125 if ( 05126 #ifdef PRI_PROGRESS_MASK 05127 e->ringing.progressmask & PRI_PROG_INBAND_AVAILABLE 05128 #else 05129 e->ringing.progress == 8 05130 #endif 05131 ) { 05132 sig_pri_open_media(pri->pvts[chanpos]); 05133 } 05134 05135 05136 #ifdef SUPPORT_USERUSER 05137 if (!ast_strlen_zero(e->ringing.useruserinfo)) { 05138 struct ast_channel *owner; 05139 05140 sig_pri_lock_owner(pri, chanpos); 05141 owner = pri->pvts[chanpos]->owner; 05142 if (owner) { 05143 pbx_builtin_setvar_helper(owner, "USERUSERINFO", 05144 e->ringing.useruserinfo); 05145 ast_channel_unlock(owner); 05146 } 05147 } 05148 #endif 05149 05150 sig_pri_unlock_private(pri->pvts[chanpos]); 05151 } 05152 } 05153 break; 05154 case PRI_EVENT_PROGRESS: 05155 if (sig_pri_is_cis_call(e->proceeding.channel)) { 05156 sig_pri_handle_cis_subcmds(pri, e->e, e->proceeding.subcmds, 05157 e->proceeding.call); 05158 break; 05159 } 05160 chanpos = pri_find_principle(pri, e->proceeding.channel, e->proceeding.call); 05161 if (chanpos > -1) { 05162 sig_pri_lock_private(pri->pvts[chanpos]); 05163 sig_pri_handle_subcmds(pri, chanpos, e->e, e->proceeding.channel, 05164 e->proceeding.subcmds, e->proceeding.call); 05165 05166 if (e->proceeding.cause > -1) { 05167 ast_verb(3, "PROGRESS with cause code %d received\n", e->proceeding.cause); 05168 05169 /* Work around broken, out of spec USER_BUSY cause in a progress message */ 05170 if (e->proceeding.cause == AST_CAUSE_USER_BUSY) { 05171 if (pri->pvts[chanpos]->owner) { 05172 ast_verb(3, "PROGRESS with 'user busy' received, signaling AST_CONTROL_BUSY instead of AST_CONTROL_PROGRESS\n"); 05173 05174 pri->pvts[chanpos]->owner->hangupcause = e->proceeding.cause; 05175 pri_queue_control(pri, chanpos, AST_CONTROL_BUSY); 05176 } 05177 } 05178 } 05179 05180 if (!pri->pvts[chanpos]->progress 05181 && !pri->pvts[chanpos]->no_b_channel 05182 #ifdef PRI_PROGRESS_MASK 05183 && (e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE) 05184 #else 05185 && e->proceeding.progress == 8 05186 #endif 05187 ) { 05188 /* Bring voice path up */ 05189 ast_debug(1, "Queuing frame from PRI_EVENT_PROGRESS on channel %d/%d span %d\n", 05190 pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset,pri->span); 05191 pri_queue_control(pri, chanpos, AST_CONTROL_PROGRESS); 05192 pri->pvts[chanpos]->progress = 1; 05193 sig_pri_set_dialing(pri->pvts[chanpos], 0); 05194 sig_pri_open_media(pri->pvts[chanpos]); 05195 } 05196 sig_pri_unlock_private(pri->pvts[chanpos]); 05197 } 05198 break; 05199 case PRI_EVENT_PROCEEDING: 05200 if (sig_pri_is_cis_call(e->proceeding.channel)) { 05201 sig_pri_handle_cis_subcmds(pri, e->e, e->proceeding.subcmds, 05202 e->proceeding.call); 05203 break; 05204 } 05205 chanpos = pri_find_principle(pri, e->proceeding.channel, e->proceeding.call); 05206 if (chanpos > -1) { 05207 sig_pri_lock_private(pri->pvts[chanpos]); 05208 sig_pri_handle_subcmds(pri, chanpos, e->e, e->proceeding.channel, 05209 e->proceeding.subcmds, e->proceeding.call); 05210 if (pri->pvts[chanpos]->call_level < SIG_PRI_CALL_LEVEL_PROCEEDING) { 05211 pri->pvts[chanpos]->call_level = SIG_PRI_CALL_LEVEL_PROCEEDING; 05212 ast_debug(1, "Queuing frame from PRI_EVENT_PROCEEDING on channel %d/%d span %d\n", 05213 pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset,pri->span); 05214 pri_queue_control(pri, chanpos, AST_CONTROL_PROCEEDING); 05215 } 05216 if (!pri->pvts[chanpos]->progress 05217 && !pri->pvts[chanpos]->no_b_channel 05218 #ifdef PRI_PROGRESS_MASK 05219 && (e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE) 05220 #else 05221 && e->proceeding.progress == 8 05222 #endif 05223 ) { 05224 /* Bring voice path up */ 05225 pri_queue_control(pri, chanpos, AST_CONTROL_PROGRESS); 05226 pri->pvts[chanpos]->progress = 1; 05227 sig_pri_set_dialing(pri->pvts[chanpos], 0); 05228 sig_pri_open_media(pri->pvts[chanpos]); 05229 } 05230 sig_pri_unlock_private(pri->pvts[chanpos]); 05231 } 05232 break; 05233 case PRI_EVENT_FACILITY: 05234 if (!e->facility.call || sig_pri_is_cis_call(e->facility.channel)) { 05235 /* Event came in on the dummy channel or a CIS call. */ 05236 #if defined(HAVE_PRI_CALL_REROUTING) 05237 sig_pri_handle_cis_subcmds(pri, e->e, e->facility.subcmds, 05238 e->facility.subcall); 05239 #else 05240 sig_pri_handle_cis_subcmds(pri, e->e, e->facility.subcmds, 05241 e->facility.call); 05242 #endif /* !defined(HAVE_PRI_CALL_REROUTING) */ 05243 break; 05244 } 05245 chanpos = pri_find_principle(pri, e->facility.channel, e->facility.call); 05246 if (chanpos < 0) { 05247 ast_log(LOG_WARNING, "Facility requested on unconfigured channel %d/%d span %d\n", 05248 PRI_SPAN(e->facility.channel), PRI_CHANNEL(e->facility.channel), pri->span); 05249 } else { 05250 chanpos = pri_fixup_principle(pri, chanpos, e->facility.call); 05251 if (chanpos < 0) { 05252 ast_log(LOG_WARNING, "Facility requested on channel %d/%d not in use on span %d\n", 05253 PRI_SPAN(e->facility.channel), PRI_CHANNEL(e->facility.channel), pri->span); 05254 } else { 05255 sig_pri_lock_private(pri->pvts[chanpos]); 05256 #if defined(HAVE_PRI_CALL_REROUTING) 05257 sig_pri_handle_subcmds(pri, chanpos, e->e, e->facility.channel, 05258 e->facility.subcmds, e->facility.subcall); 05259 #else 05260 sig_pri_handle_subcmds(pri, chanpos, e->e, e->facility.channel, 05261 e->facility.subcmds, e->facility.call); 05262 #endif /* !defined(HAVE_PRI_CALL_REROUTING) */ 05263 sig_pri_unlock_private(pri->pvts[chanpos]); 05264 } 05265 } 05266 break; 05267 case PRI_EVENT_ANSWER: 05268 if (sig_pri_is_cis_call(e->answer.channel)) { 05269 #if defined(HAVE_PRI_CALL_WAITING) 05270 /* Call is CIS so do normal CONNECT_ACKNOWLEDGE. */ 05271 pri_connect_ack(pri->pri, e->answer.call, 0); 05272 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 05273 sig_pri_handle_cis_subcmds(pri, e->e, e->answer.subcmds, 05274 e->answer.call); 05275 break; 05276 } 05277 chanpos = pri_find_principle(pri, e->answer.channel, e->answer.call); 05278 if (chanpos < 0) { 05279 ast_log(LOG_WARNING, "Answer on unconfigured channel %d/%d span %d\n", 05280 PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), pri->span); 05281 break; 05282 } 05283 chanpos = pri_fixup_principle(pri, chanpos, e->answer.call); 05284 if (chanpos < 0) { 05285 ast_log(LOG_WARNING, "Answer requested on channel %d/%d not in use on span %d\n", 05286 PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), pri->span); 05287 break; 05288 } 05289 #if defined(HAVE_PRI_CALL_WAITING) 05290 if (pri->pvts[chanpos]->is_call_waiting) { 05291 if (pri->pvts[chanpos]->no_b_channel) { 05292 int new_chanpos; 05293 05294 /* 05295 * Need to find a free channel now or 05296 * kill the call with PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION. 05297 */ 05298 new_chanpos = pri_find_empty_chan(pri, 1); 05299 if (new_chanpos < 0) { 05300 sig_pri_lock_private(pri->pvts[chanpos]); 05301 sig_pri_handle_subcmds(pri, chanpos, e->e, e->answer.channel, 05302 e->answer.subcmds, e->answer.call); 05303 sig_pri_cc_generic_check(pri, chanpos, AST_CC_CCBS); 05304 if (pri->pvts[chanpos]->owner) { 05305 pri->pvts[chanpos]->owner->hangupcause = PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION; 05306 switch (pri->pvts[chanpos]->owner->_state) { 05307 case AST_STATE_BUSY: 05308 case AST_STATE_UP: 05309 ast_softhangup_nolock(pri->pvts[chanpos]->owner, AST_SOFTHANGUP_DEV); 05310 break; 05311 default: 05312 pri_queue_control(pri, chanpos, AST_CONTROL_CONGESTION); 05313 break; 05314 } 05315 } else { 05316 pri->pvts[chanpos]->is_call_waiting = 0; 05317 ast_atomic_fetchadd_int(&pri->num_call_waiting_calls, -1); 05318 pri_hangup(pri->pri, e->answer.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION); 05319 pri->pvts[chanpos]->call = NULL; 05320 } 05321 sig_pri_unlock_private(pri->pvts[chanpos]); 05322 break; 05323 } 05324 chanpos = pri_fixup_principle(pri, new_chanpos, e->answer.call); 05325 if (chanpos < 0) { 05326 ast_log(LOG_WARNING, 05327 "Unable to move call waiting call channel on span %d\n", 05328 pri->span); 05329 break; 05330 } 05331 } 05332 pri_connect_ack(pri->pri, e->answer.call, PVT_TO_CHANNEL(pri->pvts[chanpos])); 05333 } else { 05334 /* Call is normal so do normal CONNECT_ACKNOWLEDGE. */ 05335 pri_connect_ack(pri->pri, e->answer.call, 0); 05336 } 05337 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 05338 sig_pri_lock_private(pri->pvts[chanpos]); 05339 05340 #if defined(HAVE_PRI_CALL_WAITING) 05341 if (pri->pvts[chanpos]->is_call_waiting) { 05342 pri->pvts[chanpos]->is_call_waiting = 0; 05343 ast_atomic_fetchadd_int(&pri->num_call_waiting_calls, -1); 05344 sig_pri_span_devstate_changed(pri); 05345 } 05346 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 05347 sig_pri_handle_subcmds(pri, chanpos, e->e, e->answer.channel, 05348 e->answer.subcmds, e->answer.call); 05349 if (pri->pvts[chanpos]->call_level < SIG_PRI_CALL_LEVEL_CONNECT) { 05350 pri->pvts[chanpos]->call_level = SIG_PRI_CALL_LEVEL_CONNECT; 05351 } 05352 sig_pri_open_media(pri->pvts[chanpos]); 05353 pri_queue_control(pri, chanpos, AST_CONTROL_ANSWER); 05354 /* Enable echo cancellation if it's not on already */ 05355 sig_pri_set_dialing(pri->pvts[chanpos], 0); 05356 sig_pri_set_echocanceller(pri->pvts[chanpos], 1); 05357 05358 #ifdef SUPPORT_USERUSER 05359 if (!ast_strlen_zero(e->answer.useruserinfo)) { 05360 struct ast_channel *owner; 05361 05362 sig_pri_lock_owner(pri, chanpos); 05363 owner = pri->pvts[chanpos]->owner; 05364 if (owner) { 05365 pbx_builtin_setvar_helper(owner, "USERUSERINFO", 05366 e->answer.useruserinfo); 05367 ast_channel_unlock(owner); 05368 } 05369 } 05370 #endif 05371 05372 sig_pri_unlock_private(pri->pvts[chanpos]); 05373 break; 05374 #if defined(HAVE_PRI_CALL_WAITING) 05375 case PRI_EVENT_CONNECT_ACK: 05376 if (sig_pri_is_cis_call(e->connect_ack.channel)) { 05377 sig_pri_handle_cis_subcmds(pri, e->e, e->connect_ack.subcmds, 05378 e->connect_ack.call); 05379 break; 05380 } 05381 chanpos = pri_find_principle(pri, e->connect_ack.channel, 05382 e->connect_ack.call); 05383 if (chanpos < 0) { 05384 ast_log(LOG_WARNING, "Connect ACK on unconfigured channel %d/%d span %d\n", 05385 PRI_SPAN(e->connect_ack.channel), 05386 PRI_CHANNEL(e->connect_ack.channel), pri->span); 05387 break; 05388 } 05389 chanpos = pri_fixup_principle(pri, chanpos, e->connect_ack.call); 05390 if (chanpos < 0) { 05391 ast_log(LOG_WARNING, "Connect ACK requested on channel %d/%d not in use on span %d\n", 05392 PRI_SPAN(e->connect_ack.channel), 05393 PRI_CHANNEL(e->connect_ack.channel), pri->span); 05394 break; 05395 } 05396 05397 sig_pri_lock_private(pri->pvts[chanpos]); 05398 sig_pri_span_devstate_changed(pri); 05399 sig_pri_handle_subcmds(pri, chanpos, e->e, e->connect_ack.channel, 05400 e->connect_ack.subcmds, e->connect_ack.call); 05401 sig_pri_open_media(pri->pvts[chanpos]); 05402 sig_pri_unlock_private(pri->pvts[chanpos]); 05403 break; 05404 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 05405 case PRI_EVENT_HANGUP: 05406 if (sig_pri_is_cis_call(e->hangup.channel)) { 05407 sig_pri_handle_cis_subcmds(pri, e->e, e->hangup.subcmds, 05408 e->hangup.call); 05409 pri_hangup(pri->pri, e->hangup.call, e->hangup.cause); 05410 break; 05411 } 05412 chanpos = pri_find_principle(pri, e->hangup.channel, e->hangup.call); 05413 if (chanpos < 0) { 05414 ast_log(LOG_WARNING, "Hangup requested on unconfigured channel %d/%d span %d\n", 05415 PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span); 05416 /* 05417 * Continue hanging up the call even though 05418 * it is on an unconfigured channel. 05419 */ 05420 pri_hangup(pri->pri, e->hangup.call, e->hangup.cause); 05421 } else { 05422 chanpos = pri_fixup_principle(pri, chanpos, e->hangup.call); 05423 if (chanpos > -1) { 05424 sig_pri_lock_private(pri->pvts[chanpos]); 05425 sig_pri_handle_subcmds(pri, chanpos, e->e, e->hangup.channel, 05426 e->hangup.subcmds, e->hangup.call); 05427 if (!pri->pvts[chanpos]->alreadyhungup) { 05428 /* we're calling here dahdi_hangup so once we get there we need to clear p->call after calling pri_hangup */ 05429 pri->pvts[chanpos]->alreadyhungup = 1; 05430 switch (e->hangup.cause) { 05431 case PRI_CAUSE_USER_BUSY: 05432 case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION: 05433 sig_pri_cc_generic_check(pri, chanpos, AST_CC_CCBS); 05434 break; 05435 default: 05436 break; 05437 } 05438 if (pri->pvts[chanpos]->owner) { 05439 int do_hangup = 0; 05440 /* Queue a BUSY instead of a hangup if our cause is appropriate */ 05441 pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause; 05442 switch (pri->pvts[chanpos]->owner->_state) { 05443 case AST_STATE_BUSY: 05444 case AST_STATE_UP: 05445 do_hangup = 1; 05446 break; 05447 default: 05448 if (!pri->pvts[chanpos]->outgoing) { 05449 /* 05450 * The incoming call leg hung up before getting 05451 * connected so just hangup the call. 05452 */ 05453 do_hangup = 1; 05454 break; 05455 } 05456 switch (e->hangup.cause) { 05457 case PRI_CAUSE_USER_BUSY: 05458 pri_queue_control(pri, chanpos, AST_CONTROL_BUSY); 05459 break; 05460 case PRI_CAUSE_CALL_REJECTED: 05461 case PRI_CAUSE_NETWORK_OUT_OF_ORDER: 05462 case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION: 05463 case PRI_CAUSE_SWITCH_CONGESTION: 05464 case PRI_CAUSE_DESTINATION_OUT_OF_ORDER: 05465 case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE: 05466 pri_queue_control(pri, chanpos, AST_CONTROL_CONGESTION); 05467 break; 05468 default: 05469 do_hangup = 1; 05470 break; 05471 } 05472 break; 05473 } 05474 05475 if (do_hangup) { 05476 #if defined(HAVE_PRI_AOC_EVENTS) 05477 if (detect_aoc_e_subcmd(e->hangup.subcmds)) { 05478 /* If a AOC-E msg was sent during the release, we must use a 05479 * AST_CONTROL_HANGUP frame to guarantee that frame gets read before hangup */ 05480 pri_queue_control(pri, chanpos, AST_CONTROL_HANGUP); 05481 } else { 05482 pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV; 05483 } 05484 #else 05485 pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV; 05486 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 05487 } 05488 } else { 05489 /* 05490 * Continue hanging up the call even though 05491 * we do not have an owner. 05492 */ 05493 pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause); 05494 pri->pvts[chanpos]->call = NULL; 05495 } 05496 ast_verb(3, "Channel %d/%d, span %d got hangup, cause %d\n", 05497 pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, e->hangup.cause); 05498 } else { 05499 /* Continue hanging up the call. */ 05500 pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause); 05501 pri->pvts[chanpos]->call = NULL; 05502 } 05503 if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL) { 05504 ast_verb(3, "Forcing restart of channel %d/%d on span %d since channel reported in use\n", 05505 PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span); 05506 pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos])); 05507 pri->pvts[chanpos]->resetting = 1; 05508 } 05509 if (e->hangup.aoc_units > -1) 05510 ast_verb(3, "Channel %d/%d, span %d received AOC-E charging %d unit%s\n", 05511 pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s"); 05512 05513 #ifdef SUPPORT_USERUSER 05514 if (!ast_strlen_zero(e->hangup.useruserinfo)) { 05515 struct ast_channel *owner; 05516 05517 sig_pri_lock_owner(pri, chanpos); 05518 owner = pri->pvts[chanpos]->owner; 05519 if (owner) { 05520 pbx_builtin_setvar_helper(owner, "USERUSERINFO", 05521 e->hangup.useruserinfo); 05522 ast_channel_unlock(owner); 05523 } 05524 } 05525 #endif 05526 05527 sig_pri_unlock_private(pri->pvts[chanpos]); 05528 } else { 05529 /* 05530 * Continue hanging up the call even though 05531 * we do not remember it (if we ever did). 05532 */ 05533 pri_hangup(pri->pri, e->hangup.call, e->hangup.cause); 05534 } 05535 } 05536 break; 05537 case PRI_EVENT_HANGUP_REQ: 05538 if (sig_pri_is_cis_call(e->hangup.channel)) { 05539 sig_pri_handle_cis_subcmds(pri, e->e, e->hangup.subcmds, 05540 e->hangup.call); 05541 pri_hangup(pri->pri, e->hangup.call, e->hangup.cause); 05542 break; 05543 } 05544 chanpos = pri_find_principle(pri, e->hangup.channel, e->hangup.call); 05545 if (chanpos < 0) { 05546 ast_log(LOG_WARNING, "Hangup REQ requested on unconfigured channel %d/%d span %d\n", 05547 PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span); 05548 /* 05549 * Continue hanging up the call even though 05550 * it is on an unconfigured channel. 05551 */ 05552 pri_hangup(pri->pri, e->hangup.call, e->hangup.cause); 05553 } else { 05554 chanpos = pri_fixup_principle(pri, chanpos, e->hangup.call); 05555 if (chanpos > -1) { 05556 sig_pri_lock_private(pri->pvts[chanpos]); 05557 sig_pri_handle_subcmds(pri, chanpos, e->e, e->hangup.channel, 05558 e->hangup.subcmds, e->hangup.call); 05559 #if defined(HAVE_PRI_CALL_HOLD) 05560 if (e->hangup.call_active && e->hangup.call_held 05561 && pri->hold_disconnect_transfer) { 05562 /* We are to transfer the call instead of simply hanging up. */ 05563 sig_pri_unlock_private(pri->pvts[chanpos]); 05564 if (!sig_pri_attempt_transfer(pri, e->hangup.call_held, 1, 05565 e->hangup.call_active, 0, NULL, NULL)) { 05566 break; 05567 } 05568 sig_pri_lock_private(pri->pvts[chanpos]); 05569 } 05570 #endif /* defined(HAVE_PRI_CALL_HOLD) */ 05571 switch (e->hangup.cause) { 05572 case PRI_CAUSE_USER_BUSY: 05573 case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION: 05574 sig_pri_cc_generic_check(pri, chanpos, AST_CC_CCBS); 05575 break; 05576 default: 05577 break; 05578 } 05579 if (pri->pvts[chanpos]->owner) { 05580 int do_hangup = 0; 05581 05582 pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause; 05583 switch (pri->pvts[chanpos]->owner->_state) { 05584 case AST_STATE_BUSY: 05585 case AST_STATE_UP: 05586 do_hangup = 1; 05587 break; 05588 default: 05589 if (!pri->pvts[chanpos]->outgoing) { 05590 /* 05591 * The incoming call leg hung up before getting 05592 * connected so just hangup the call. 05593 */ 05594 do_hangup = 1; 05595 break; 05596 } 05597 switch (e->hangup.cause) { 05598 case PRI_CAUSE_USER_BUSY: 05599 pri_queue_control(pri, chanpos, AST_CONTROL_BUSY); 05600 break; 05601 case PRI_CAUSE_CALL_REJECTED: 05602 case PRI_CAUSE_NETWORK_OUT_OF_ORDER: 05603 case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION: 05604 case PRI_CAUSE_SWITCH_CONGESTION: 05605 case PRI_CAUSE_DESTINATION_OUT_OF_ORDER: 05606 case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE: 05607 pri_queue_control(pri, chanpos, AST_CONTROL_CONGESTION); 05608 break; 05609 default: 05610 do_hangup = 1; 05611 break; 05612 } 05613 break; 05614 } 05615 05616 if (do_hangup) { 05617 #if defined(HAVE_PRI_AOC_EVENTS) 05618 if (!pri->pvts[chanpos]->holding_aoce 05619 && pri->aoce_delayhangup 05620 && ast_bridged_channel(pri->pvts[chanpos]->owner)) { 05621 sig_pri_send_aoce_termination_request(pri, chanpos, 05622 pri_get_timer(pri->pri, PRI_TIMER_T305) / 2); 05623 } else if (detect_aoc_e_subcmd(e->hangup.subcmds)) { 05624 /* If a AOC-E msg was sent during the Disconnect, we must use a AST_CONTROL_HANGUP frame 05625 * to guarantee that frame gets read before hangup */ 05626 pri_queue_control(pri, chanpos, AST_CONTROL_HANGUP); 05627 } else { 05628 pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV; 05629 } 05630 #else 05631 pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV; 05632 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 05633 } 05634 ast_verb(3, "Channel %d/%d, span %d got hangup request, cause %d\n", 05635 PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span, e->hangup.cause); 05636 } else { 05637 /* 05638 * Continue hanging up the call even though 05639 * we do not have an owner. 05640 */ 05641 pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause); 05642 pri->pvts[chanpos]->call = NULL; 05643 } 05644 if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL) { 05645 ast_verb(3, "Forcing restart of channel %d/%d span %d since channel reported in use\n", 05646 PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span); 05647 pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos])); 05648 pri->pvts[chanpos]->resetting = 1; 05649 } 05650 05651 #ifdef SUPPORT_USERUSER 05652 if (!ast_strlen_zero(e->hangup.useruserinfo)) { 05653 struct ast_channel *owner; 05654 05655 sig_pri_lock_owner(pri, chanpos); 05656 owner = pri->pvts[chanpos]->owner; 05657 if (owner) { 05658 pbx_builtin_setvar_helper(owner, "USERUSERINFO", 05659 e->hangup.useruserinfo); 05660 ast_channel_unlock(owner); 05661 } 05662 } 05663 #endif 05664 05665 sig_pri_unlock_private(pri->pvts[chanpos]); 05666 } else { 05667 /* 05668 * Continue hanging up the call even though 05669 * we do not remember it (if we ever did). 05670 */ 05671 pri_hangup(pri->pri, e->hangup.call, e->hangup.cause); 05672 } 05673 } 05674 break; 05675 case PRI_EVENT_HANGUP_ACK: 05676 if (sig_pri_is_cis_call(e->hangup.channel)) { 05677 sig_pri_handle_cis_subcmds(pri, e->e, e->hangup.subcmds, 05678 e->hangup.call); 05679 break; 05680 } 05681 chanpos = pri_find_principle(pri, e->hangup.channel, e->hangup.call); 05682 if (chanpos < 0) { 05683 ast_log(LOG_WARNING, "Hangup ACK requested on unconfigured channel number %d/%d span %d\n", 05684 PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span); 05685 } else { 05686 chanpos = pri_fixup_principle(pri, chanpos, e->hangup.call); 05687 if (chanpos > -1) { 05688 sig_pri_lock_private(pri->pvts[chanpos]); 05689 pri->pvts[chanpos]->call = NULL; 05690 pri->pvts[chanpos]->resetting = 0; 05691 if (pri->pvts[chanpos]->owner) { 05692 ast_verb(3, "Channel %d/%d, span %d got hangup ACK\n", PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span); 05693 } 05694 #ifdef SUPPORT_USERUSER 05695 if (!ast_strlen_zero(e->hangup.useruserinfo)) { 05696 struct ast_channel *owner; 05697 05698 sig_pri_lock_owner(pri, chanpos); 05699 owner = pri->pvts[chanpos]->owner; 05700 if (owner) { 05701 pbx_builtin_setvar_helper(owner, "USERUSERINFO", 05702 e->hangup.useruserinfo); 05703 ast_channel_unlock(owner); 05704 } 05705 } 05706 #endif 05707 sig_pri_unlock_private(pri->pvts[chanpos]); 05708 } 05709 } 05710 break; 05711 case PRI_EVENT_CONFIG_ERR: 05712 ast_log(LOG_WARNING, "PRI Error on span %d: %s\n", pri->span, e->err.err); 05713 break; 05714 case PRI_EVENT_RESTART_ACK: 05715 chanpos = pri_find_principle(pri, e->restartack.channel, NULL); 05716 if (chanpos < 0) { 05717 /* Sometime switches (e.g. I421 / British Telecom) don't give us the 05718 channel number, so we have to figure it out... This must be why 05719 everybody resets exactly a channel at a time. */ 05720 for (x = 0; x < pri->numchans; x++) { 05721 if (pri->pvts[x] && pri->pvts[x]->resetting) { 05722 chanpos = x; 05723 sig_pri_lock_private(pri->pvts[chanpos]); 05724 ast_debug(1, "Assuming restart ack is really for channel %d/%d span %d\n", pri->pvts[chanpos]->logicalspan, 05725 pri->pvts[chanpos]->prioffset, pri->span); 05726 if (pri->pvts[chanpos]->owner) { 05727 ast_log(LOG_WARNING, "Got restart ack on channel %d/%d with owner on span %d\n", pri->pvts[chanpos]->logicalspan, 05728 pri->pvts[chanpos]->prioffset, pri->span); 05729 pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV; 05730 } 05731 pri->pvts[chanpos]->resetting = 0; 05732 ast_verb(3, "B-channel %d/%d successfully restarted on span %d\n", pri->pvts[chanpos]->logicalspan, 05733 pri->pvts[chanpos]->prioffset, pri->span); 05734 sig_pri_unlock_private(pri->pvts[chanpos]); 05735 if (pri->resetting) 05736 pri_check_restart(pri); 05737 break; 05738 } 05739 } 05740 if (chanpos < 0) { 05741 ast_log(LOG_WARNING, "Restart ACK requested on strange channel %d/%d span %d\n", 05742 PRI_SPAN(e->restartack.channel), PRI_CHANNEL(e->restartack.channel), pri->span); 05743 } 05744 } else { 05745 if (pri->pvts[chanpos]) { 05746 sig_pri_lock_private(pri->pvts[chanpos]); 05747 if (pri->pvts[chanpos]->owner) { 05748 ast_log(LOG_WARNING, "Got restart ack on channel %d/%d span %d with owner\n", 05749 PRI_SPAN(e->restartack.channel), PRI_CHANNEL(e->restartack.channel), pri->span); 05750 pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV; 05751 } 05752 pri->pvts[chanpos]->resetting = 0; 05753 ast_verb(3, "B-channel %d/%d successfully restarted on span %d\n", pri->pvts[chanpos]->logicalspan, 05754 pri->pvts[chanpos]->prioffset, pri->span); 05755 sig_pri_unlock_private(pri->pvts[chanpos]); 05756 if (pri->resetting) 05757 pri_check_restart(pri); 05758 } 05759 } 05760 break; 05761 case PRI_EVENT_SETUP_ACK: 05762 if (sig_pri_is_cis_call(e->setup_ack.channel)) { 05763 sig_pri_handle_cis_subcmds(pri, e->e, e->setup_ack.subcmds, 05764 e->setup_ack.call); 05765 break; 05766 } 05767 chanpos = pri_find_principle(pri, e->setup_ack.channel, e->setup_ack.call); 05768 if (chanpos < 0) { 05769 ast_log(LOG_WARNING, "Received SETUP_ACKNOWLEDGE on unconfigured channel %d/%d span %d\n", 05770 PRI_SPAN(e->setup_ack.channel), PRI_CHANNEL(e->setup_ack.channel), pri->span); 05771 } else { 05772 chanpos = pri_fixup_principle(pri, chanpos, e->setup_ack.call); 05773 if (chanpos > -1) { 05774 unsigned int len; 05775 05776 sig_pri_lock_private(pri->pvts[chanpos]); 05777 sig_pri_handle_subcmds(pri, chanpos, e->e, e->setup_ack.channel, 05778 e->setup_ack.subcmds, e->setup_ack.call); 05779 if (pri->pvts[chanpos]->call_level < SIG_PRI_CALL_LEVEL_OVERLAP) { 05780 pri->pvts[chanpos]->call_level = SIG_PRI_CALL_LEVEL_OVERLAP; 05781 } 05782 05783 /* Send any queued digits */ 05784 len = strlen(pri->pvts[chanpos]->dialdest); 05785 for (x = 0; x < len; ++x) { 05786 ast_debug(1, "Sending pending digit '%c'\n", pri->pvts[chanpos]->dialdest[x]); 05787 pri_information(pri->pri, pri->pvts[chanpos]->call, 05788 pri->pvts[chanpos]->dialdest[x]); 05789 } 05790 05791 if (!pri->pvts[chanpos]->progress 05792 && (pri->overlapdial & DAHDI_OVERLAPDIAL_OUTGOING) 05793 && !pri->pvts[chanpos]->digital 05794 && !pri->pvts[chanpos]->no_b_channel) { 05795 /* 05796 * Call has a channel. 05797 * Indicate for overlap dialing that dialtone may be present. 05798 */ 05799 pri_queue_control(pri, chanpos, AST_CONTROL_PROGRESS); 05800 pri->pvts[chanpos]->progress = 1;/* Claim to have seen inband-information */ 05801 sig_pri_set_dialing(pri->pvts[chanpos], 0); 05802 sig_pri_open_media(pri->pvts[chanpos]); 05803 } 05804 sig_pri_unlock_private(pri->pvts[chanpos]); 05805 } else 05806 ast_log(LOG_WARNING, "Unable to move channel %d!\n", e->setup_ack.channel); 05807 } 05808 break; 05809 case PRI_EVENT_NOTIFY: 05810 if (sig_pri_is_cis_call(e->notify.channel)) { 05811 #if defined(HAVE_PRI_CALL_HOLD) 05812 sig_pri_handle_cis_subcmds(pri, e->e, e->notify.subcmds, 05813 e->notify.call); 05814 #else 05815 sig_pri_handle_cis_subcmds(pri, e->e, e->notify.subcmds, NULL); 05816 #endif /* !defined(HAVE_PRI_CALL_HOLD) */ 05817 break; 05818 } 05819 #if defined(HAVE_PRI_CALL_HOLD) 05820 chanpos = pri_find_principle(pri, e->notify.channel, e->notify.call); 05821 #else 05822 chanpos = pri_find_principle(pri, e->notify.channel, NULL); 05823 #endif /* !defined(HAVE_PRI_CALL_HOLD) */ 05824 if (chanpos < 0) { 05825 ast_log(LOG_WARNING, "Received NOTIFY on unconfigured channel %d/%d span %d\n", 05826 PRI_SPAN(e->notify.channel), PRI_CHANNEL(e->notify.channel), pri->span); 05827 } else { 05828 sig_pri_lock_private(pri->pvts[chanpos]); 05829 #if defined(HAVE_PRI_CALL_HOLD) 05830 sig_pri_handle_subcmds(pri, chanpos, e->e, e->notify.channel, 05831 e->notify.subcmds, e->notify.call); 05832 #else 05833 sig_pri_handle_subcmds(pri, chanpos, e->e, e->notify.channel, 05834 e->notify.subcmds, NULL); 05835 #endif /* !defined(HAVE_PRI_CALL_HOLD) */ 05836 switch (e->notify.info) { 05837 case PRI_NOTIFY_REMOTE_HOLD: 05838 if (!pri->discardremoteholdretrieval) { 05839 pri_queue_control(pri, chanpos, AST_CONTROL_HOLD); 05840 } 05841 break; 05842 case PRI_NOTIFY_REMOTE_RETRIEVAL: 05843 if (!pri->discardremoteholdretrieval) { 05844 pri_queue_control(pri, chanpos, AST_CONTROL_UNHOLD); 05845 } 05846 break; 05847 } 05848 sig_pri_unlock_private(pri->pvts[chanpos]); 05849 } 05850 break; 05851 #if defined(HAVE_PRI_CALL_HOLD) 05852 case PRI_EVENT_HOLD: 05853 /* We should not be getting any CIS calls with this message type. */ 05854 if (sig_pri_handle_hold(pri, e)) { 05855 pri_hold_rej(pri->pri, e->hold.call, 05856 PRI_CAUSE_RESOURCE_UNAVAIL_UNSPECIFIED); 05857 } else { 05858 pri_hold_ack(pri->pri, e->hold.call); 05859 } 05860 break; 05861 #endif /* defined(HAVE_PRI_CALL_HOLD) */ 05862 #if defined(HAVE_PRI_CALL_HOLD) 05863 case PRI_EVENT_HOLD_ACK: 05864 ast_debug(1, "Event: HOLD_ACK\n"); 05865 break; 05866 #endif /* defined(HAVE_PRI_CALL_HOLD) */ 05867 #if defined(HAVE_PRI_CALL_HOLD) 05868 case PRI_EVENT_HOLD_REJ: 05869 ast_debug(1, "Event: HOLD_REJ\n"); 05870 break; 05871 #endif /* defined(HAVE_PRI_CALL_HOLD) */ 05872 #if defined(HAVE_PRI_CALL_HOLD) 05873 case PRI_EVENT_RETRIEVE: 05874 /* We should not be getting any CIS calls with this message type. */ 05875 sig_pri_handle_retrieve(pri, e); 05876 break; 05877 #endif /* defined(HAVE_PRI_CALL_HOLD) */ 05878 #if defined(HAVE_PRI_CALL_HOLD) 05879 case PRI_EVENT_RETRIEVE_ACK: 05880 ast_debug(1, "Event: RETRIEVE_ACK\n"); 05881 break; 05882 #endif /* defined(HAVE_PRI_CALL_HOLD) */ 05883 #if defined(HAVE_PRI_CALL_HOLD) 05884 case PRI_EVENT_RETRIEVE_REJ: 05885 ast_debug(1, "Event: RETRIEVE_REJ\n"); 05886 break; 05887 #endif /* defined(HAVE_PRI_CALL_HOLD) */ 05888 default: 05889 ast_debug(1, "Event: %d\n", e->e); 05890 break; 05891 } 05892 } 05893 ast_mutex_unlock(&pri->lock); 05894 } 05895 /* Never reached */ 05896 return NULL; 05897 }
void pri_event_alarm | ( | struct sig_pri_span * | pri, | |
int | index, | |||
int | before_start_pri | |||
) |
Definition at line 1688 of file sig_pri.c.
References DCHAN_NOTINALARM, DCHAN_UP, sig_pri_span::dchanavail, and pri_find_dchan().
Referenced by my_handle_dchan_exception(), and prepare_pri().
01689 { 01690 pri->dchanavail[index] &= ~(DCHAN_NOTINALARM | DCHAN_UP); 01691 if (!before_start_pri) 01692 pri_find_dchan(pri); 01693 }
void pri_event_noalarm | ( | struct sig_pri_span * | pri, | |
int | index, | |||
int | before_start_pri | |||
) |
Definition at line 1695 of file sig_pri.c.
References DCHAN_NOTINALARM, sig_pri_span::dchanavail, and sig_pri_span::dchans.
Referenced by my_handle_dchan_exception(), and prepare_pri().
01696 { 01697 pri->dchanavail[index] |= DCHAN_NOTINALARM; 01698 if (!before_start_pri) 01699 pri_restart(pri->dchans[index]); 01700 }
static int pri_find_dchan | ( | struct sig_pri_span * | pri | ) | [static] |
Definition at line 970 of file sig_pri.c.
References DCHAN_AVAILABLE, sig_pri_span::dchanavail, sig_pri_span::dchans, sig_pri_span::pri, and SIG_PRI_NUM_DCHANS.
Referenced by pri_event_alarm().
00971 { 00972 int oldslot = -1; 00973 struct pri *old; 00974 int newslot = -1; 00975 int x; 00976 old = pri->pri; 00977 for (x = 0; x < SIG_PRI_NUM_DCHANS; x++) { 00978 if ((pri->dchanavail[x] == DCHAN_AVAILABLE) && (newslot < 0)) 00979 newslot = x; 00980 if (pri->dchans[x] == old) { 00981 oldslot = x; 00982 } 00983 } 00984 if (newslot < 0) { 00985 newslot = 0; 00986 /* This is annoying to see on non persistent layer 2 connections. Let's not complain in that case */ 00987 if (pri->sig != SIG_BRI_PTMP && !pri->no_d_channels) { 00988 pri->no_d_channels = 1; 00989 ast_log(LOG_WARNING, 00990 "Span %d: No D-channels available! Using Primary channel as D-channel anyway!\n", 00991 pri->span); 00992 } 00993 } else { 00994 pri->no_d_channels = 0; 00995 } 00996 if (old && (oldslot != newslot)) 00997 ast_log(LOG_NOTICE, "Switching from d-channel fd %d to fd %d!\n", 00998 pri->fds[oldslot], pri->fds[newslot]); 00999 pri->pri = pri->dchans[newslot]; 01000 return 0; 01001 }
static int pri_find_empty_chan | ( | struct sig_pri_span * | pri, | |
int | backwards | |||
) | [static] |
Definition at line 1421 of file sig_pri.c.
References ast_debug, sig_pri_chan::inalarm, sig_pri_chan::logicalspan, sig_pri_chan::no_b_channel, sig_pri_span::numchans, sig_pri_chan::owner, sig_pri_chan::pri, sig_pri_chan::prioffset, and sig_pri_span::pvts.
Referenced by sig_pri_handle_retrieve().
01422 { 01423 int x; 01424 if (backwards) 01425 x = pri->numchans; 01426 else 01427 x = 0; 01428 for (;;) { 01429 if (backwards && (x < 0)) 01430 break; 01431 if (!backwards && (x >= pri->numchans)) 01432 break; 01433 if (pri->pvts[x] 01434 && !pri->pvts[x]->no_b_channel 01435 && !pri->pvts[x]->inalarm 01436 && !pri->pvts[x]->owner) { 01437 ast_debug(1, "Found empty available channel %d/%d\n", 01438 pri->pvts[x]->logicalspan, pri->pvts[x]->prioffset); 01439 return x; 01440 } 01441 if (backwards) 01442 x--; 01443 else 01444 x++; 01445 } 01446 return -1; 01447 }
static int pri_find_empty_nobch | ( | struct sig_pri_span * | pri | ) | [static] |
Definition at line 1462 of file sig_pri.c.
References ast_debug, sig_pri_chan::inalarm, sig_pri_chan::no_b_channel, sig_pri_span::numchans, sig_pri_chan::owner, sig_pri_chan::pri, and sig_pri_span::pvts.
Referenced by sig_pri_handle_hold().
01463 { 01464 int idx; 01465 01466 for (idx = 0; idx < pri->numchans; ++idx) { 01467 if (pri->pvts[idx] 01468 && pri->pvts[idx]->no_b_channel 01469 && !pri->pvts[idx]->inalarm 01470 && !pri->pvts[idx]->owner) { 01471 ast_debug(1, "Found empty available no B channel interface\n"); 01472 return idx; 01473 } 01474 } 01475 01476 /* Need to create a new interface. */ 01477 if (pri->calls->new_nobch_intf) { 01478 idx = pri->calls->new_nobch_intf(pri); 01479 } else { 01480 idx = -1; 01481 } 01482 return idx; 01483 }
static int pri_find_pri_call | ( | struct sig_pri_span * | pri, | |
q931_call * | call | |||
) | [static] |
Definition at line 1500 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().
01501 { 01502 int idx; 01503 01504 for (idx = 0; idx < pri->numchans; ++idx) { 01505 if (pri->pvts[idx] && pri->pvts[idx]->call == call) { 01506 /* Found the channel */ 01507 return idx; 01508 } 01509 } 01510 return -1; 01511 }
static int pri_find_principle | ( | struct sig_pri_span * | pri, | |
int | channel, | |||
q931_call * | call | |||
) | [static] |
Definition at line 1097 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 sig_pri_handle_hold(), and sig_pri_handle_retrieve().
01098 { 01099 int x; 01100 int span; 01101 int principle; 01102 int prioffset; 01103 01104 if (channel < 0) { 01105 /* Channel is not picked yet. */ 01106 return -1; 01107 } 01108 01109 prioffset = PRI_CHANNEL(channel); 01110 if (!prioffset || (channel & PRI_HELD_CALL)) { 01111 if (!call) { 01112 /* Cannot find a call waiting call or held call without a call. */ 01113 return -1; 01114 } 01115 principle = -1; 01116 for (x = 0; x < pri->numchans; ++x) { 01117 if (pri->pvts[x] 01118 && pri->pvts[x]->call == call) { 01119 principle = x; 01120 break; 01121 } 01122 } 01123 return principle; 01124 } 01125 01126 span = PRI_SPAN(channel); 01127 if (!(channel & PRI_EXPLICIT)) { 01128 int index; 01129 01130 index = pri_active_dchan_index(pri); 01131 if (index == -1) { 01132 return -1; 01133 } 01134 span = pri->dchan_logical_span[index]; 01135 } 01136 01137 principle = -1; 01138 for (x = 0; x < pri->numchans; x++) { 01139 if (pri->pvts[x] 01140 && pri->pvts[x]->prioffset == prioffset 01141 && pri->pvts[x]->logicalspan == span 01142 && !pri->pvts[x]->no_b_channel) { 01143 principle = x; 01144 break; 01145 } 01146 } 01147 01148 return principle; 01149 }
static int pri_fixup_principle | ( | struct sig_pri_span * | pri, | |
int | principle, | |||
q931_call * | call | |||
) | [static] |
Definition at line 1164 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_CALL_LEVEL_IDLE, sig_pri_fixup_chans(), sig_pri_lock_owner(), sig_pri_lock_private(), sig_pri_open_media(), and sig_pri_unlock_private().
Referenced by sig_pri_handle_hold(), and sig_pri_handle_retrieve().
01165 { 01166 int x; 01167 01168 if (principle < 0 || pri->numchans <= principle) { 01169 /* Out of rannge */ 01170 return -1; 01171 } 01172 if (!call) { 01173 /* No call */ 01174 return principle; 01175 } 01176 if (pri->pvts[principle] && pri->pvts[principle]->call == call) { 01177 /* Call is already on the specified principle. */ 01178 return principle; 01179 } 01180 01181 /* Find the old principle location. */ 01182 for (x = 0; x < pri->numchans; x++) { 01183 struct sig_pri_chan *new_chan; 01184 struct sig_pri_chan *old_chan; 01185 01186 if (!pri->pvts[x] || pri->pvts[x]->call != call) { 01187 continue; 01188 } 01189 01190 /* Found our call */ 01191 new_chan = pri->pvts[principle]; 01192 old_chan = pri->pvts[x]; 01193 01194 /* Get locks to safely move to the new private structure. */ 01195 sig_pri_lock_private(old_chan); 01196 sig_pri_lock_owner(pri, x); 01197 sig_pri_lock_private(new_chan); 01198 01199 ast_verb(3, "Moving call (%s) from channel %d to %d.\n", 01200 old_chan->owner ? old_chan->owner->name : "", 01201 old_chan->channel, new_chan->channel); 01202 if (new_chan->owner) { 01203 ast_log(LOG_WARNING, 01204 "Can't move call (%s) from channel %d to %d. It is already in use.\n", 01205 old_chan->owner ? old_chan->owner->name : "", 01206 old_chan->channel, new_chan->channel); 01207 sig_pri_unlock_private(new_chan); 01208 if (old_chan->owner) { 01209 ast_channel_unlock(old_chan->owner); 01210 } 01211 sig_pri_unlock_private(old_chan); 01212 return -1; 01213 } 01214 01215 sig_pri_fixup_chans(old_chan, new_chan); 01216 01217 /* Fix it all up now */ 01218 new_chan->owner = old_chan->owner; 01219 old_chan->owner = NULL; 01220 01221 new_chan->call = old_chan->call; 01222 old_chan->call = NULL; 01223 01224 /* Transfer flags from the old channel. */ 01225 #if defined(HAVE_PRI_AOC_EVENTS) 01226 new_chan->aoc_s_request_invoke_id_valid = old_chan->aoc_s_request_invoke_id_valid; 01227 new_chan->waiting_for_aoce = old_chan->waiting_for_aoce; 01228 new_chan->holding_aoce = old_chan->holding_aoce; 01229 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 01230 new_chan->alreadyhungup = old_chan->alreadyhungup; 01231 new_chan->isidlecall = old_chan->isidlecall; 01232 new_chan->progress = old_chan->progress; 01233 new_chan->outgoing = old_chan->outgoing; 01234 new_chan->digital = old_chan->digital; 01235 #if defined(HAVE_PRI_CALL_WAITING) 01236 new_chan->is_call_waiting = old_chan->is_call_waiting; 01237 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 01238 01239 #if defined(HAVE_PRI_AOC_EVENTS) 01240 old_chan->aoc_s_request_invoke_id_valid = 0; 01241 old_chan->waiting_for_aoce = 0; 01242 old_chan->holding_aoce = 0; 01243 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 01244 old_chan->alreadyhungup = 0; 01245 old_chan->isidlecall = 0; 01246 old_chan->progress = 0; 01247 old_chan->outgoing = 0; 01248 old_chan->digital = 0; 01249 #if defined(HAVE_PRI_CALL_WAITING) 01250 old_chan->is_call_waiting = 0; 01251 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 01252 01253 /* More stuff to transfer to the new channel. */ 01254 new_chan->call_level = old_chan->call_level; 01255 old_chan->call_level = SIG_PRI_CALL_LEVEL_IDLE; 01256 #if defined(HAVE_PRI_REVERSE_CHARGE) 01257 new_chan->reverse_charging_indication = old_chan->reverse_charging_indication; 01258 #endif /* defined(HAVE_PRI_REVERSE_CHARGE) */ 01259 #if defined(HAVE_PRI_SETUP_KEYPAD) 01260 strcpy(new_chan->keypad_digits, old_chan->keypad_digits); 01261 #endif /* defined(HAVE_PRI_SETUP_KEYPAD) */ 01262 #if defined(HAVE_PRI_AOC_EVENTS) 01263 new_chan->aoc_s_request_invoke_id = old_chan->aoc_s_request_invoke_id; 01264 new_chan->aoc_e = old_chan->aoc_e; 01265 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 01266 strcpy(new_chan->user_tag, old_chan->user_tag); 01267 01268 if (new_chan->no_b_channel) { 01269 /* Copy the real channel configuration to the no B channel interface. */ 01270 new_chan->hidecallerid = old_chan->hidecallerid; 01271 new_chan->hidecalleridname = old_chan->hidecalleridname; 01272 new_chan->immediate = old_chan->immediate; 01273 new_chan->priexclusive = old_chan->priexclusive; 01274 new_chan->priindication_oob = old_chan->priindication_oob; 01275 new_chan->use_callerid = old_chan->use_callerid; 01276 new_chan->use_callingpres = old_chan->use_callingpres; 01277 new_chan->stripmsd = old_chan->stripmsd; 01278 strcpy(new_chan->context, old_chan->context); 01279 strcpy(new_chan->mohinterpret, old_chan->mohinterpret); 01280 01281 /* Become a member of the old channel span/trunk-group. */ 01282 new_chan->logicalspan = old_chan->logicalspan; 01283 new_chan->mastertrunkgroup = old_chan->mastertrunkgroup; 01284 } else if (old_chan->no_b_channel) { 01285 /* 01286 * We are transitioning from a held/call-waiting channel to a 01287 * real channel so we need to make sure that the media path is 01288 * open. (Needed especially if the channel is natively 01289 * bridged.) 01290 */ 01291 sig_pri_open_media(new_chan); 01292 } 01293 01294 sig_pri_unlock_private(old_chan); 01295 if (new_chan->owner) { 01296 ast_channel_unlock(new_chan->owner); 01297 } 01298 sig_pri_unlock_private(new_chan); 01299 01300 return principle; 01301 } 01302 ast_verb(3, "Call specified, but not found.\n"); 01303 return -1; 01304 }
static int pri_grab | ( | struct sig_pri_chan * | p, | |
struct sig_pri_span * | pri | |||
) | [inline, static] |
Definition at line 283 of file sig_pri.c.
References ast_mutex_trylock, sig_pri_span::lock, sig_pri_span::master, and PRI_DEADLOCK_AVOIDANCE.
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().
00284 { 00285 int res; 00286 /* Grab the lock first */ 00287 do { 00288 res = ast_mutex_trylock(&pri->lock); 00289 if (res) { 00290 PRI_DEADLOCK_AVOIDANCE(p); 00291 } 00292 } while (res); 00293 /* Then break the poll */ 00294 pthread_kill(pri->master, SIGURG); 00295 return 0; 00296 }
int pri_is_up | ( | struct sig_pri_span * | pri | ) |
Definition at line 930 of file sig_pri.c.
References DCHAN_AVAILABLE, sig_pri_span::dchanavail, and SIG_PRI_NUM_DCHANS.
Referenced by pri_dchannel().
00931 { 00932 int x; 00933 for (x = 0; x < SIG_PRI_NUM_DCHANS; x++) { 00934 if (pri->dchanavail[x] == DCHAN_AVAILABLE) 00935 return 1; 00936 } 00937 return 0; 00938 }
int pri_maintenance_bservice | ( | struct pri * | pri, | |
struct sig_pri_chan * | p, | |||
int | changestatus | |||
) |
Definition at line 7463 of file sig_pri.c.
References sig_pri_chan::channel, PRI_SPAN, and PVT_TO_CHANNEL().
07464 { 07465 int channel = PVT_TO_CHANNEL(p); 07466 int span = PRI_SPAN(channel); 07467 07468 return pri_maintenance_service(pri, span, channel, changestatus); 07469 }
static char* pri_order | ( | int | level | ) | [static] |
Definition at line 940 of file sig_pri.c.
Referenced by pri_dchannel(), and sig_pri_cli_show_span().
00941 { 00942 switch (level) { 00943 case 0: 00944 return "Primary"; 00945 case 1: 00946 return "Secondary"; 00947 case 2: 00948 return "Tertiary"; 00949 case 3: 00950 return "Quaternary"; 00951 default: 00952 return "<Unknown>"; 00953 } 00954 }
static void pri_queue_control | ( | struct sig_pri_span * | pri, | |
int | chanpos, | |||
int | subclass | |||
) | [static] |
Definition at line 1071 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().
01072 { 01073 struct ast_frame f = {AST_FRAME_CONTROL, }; 01074 struct sig_pri_chan *p = pri->pvts[chanpos]; 01075 01076 if (p->calls->queue_control) { 01077 p->calls->queue_control(p->chan_pvt, subclass); 01078 } 01079 01080 f.subclass.integer = subclass; 01081 pri_queue_frame(pri, chanpos, &f); 01082 }
static void pri_queue_frame | ( | struct sig_pri_span * | pri, | |
int | chanpos, | |||
struct ast_frame * | frame | |||
) | [static] |
Definition at line 1048 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().
01049 { 01050 sig_pri_lock_owner(pri, chanpos); 01051 if (pri->pvts[chanpos]->owner) { 01052 ast_queue_frame(pri->pvts[chanpos]->owner, frame); 01053 ast_channel_unlock(pri->pvts[chanpos]->owner); 01054 } 01055 }
static void pri_rel | ( | struct sig_pri_span * | pri | ) | [inline, static] |
Definition at line 112 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().
00113 { 00114 ast_mutex_unlock(&pri->lock); 00115 }
int pri_send_callrerouting_facility_exec | ( | struct sig_pri_chan * | p, | |
enum ast_channel_state | chanstate, | |||
const char * | destination, | |||
const char * | original, | |||
const char * | reason | |||
) |
Definition at line 7438 of file sig_pri.c.
References ast_log(), sig_pri_chan::call, LOG_DEBUG, sig_pri_chan::pri, sig_pri_span::pri, pri_grab(), pri_rel(), sig_pri_lock_private(), sig_pri_unlock_private(), and sig_pri_span::span.
Referenced by dahdi_send_callrerouting_facility_exec().
07439 { 07440 int res = -1; 07441 07442 sig_pri_lock_private(p); 07443 07444 if (!p->pri || !p->call) { 07445 ast_log(LOG_DEBUG, "Unable to find pri or call on channel!\n"); 07446 sig_pri_unlock_private(p); 07447 return -1; 07448 } 07449 07450 if (!pri_grab(p, p->pri)) { 07451 res = pri_callrerouting_facility(p->pri->pri, p->call, destination, original, reason); 07452 pri_rel(p->pri); 07453 } else { 07454 ast_log(LOG_DEBUG, "Unable to grab pri to send callrerouting facility on span %d!\n", p->pri->span); 07455 } 07456 07457 sig_pri_unlock_private(p); 07458 07459 return res; 07460 }
int pri_send_keypad_facility_exec | ( | struct sig_pri_chan * | p, | |
const char * | digits | |||
) |
Definition at line 7414 of file sig_pri.c.
References ast_debug, sig_pri_chan::call, sig_pri_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().
07415 { 07416 sig_pri_lock_private(p); 07417 07418 if (!p->pri || !p->call) { 07419 ast_debug(1, "Unable to find pri or call on channel!\n"); 07420 sig_pri_unlock_private(p); 07421 return -1; 07422 } 07423 07424 if (!pri_grab(p, p->pri)) { 07425 pri_keypad_facility(p->pri->pri, p->call, digits); 07426 pri_rel(p->pri); 07427 } else { 07428 ast_debug(1, "Unable to grab pri to send keypad facility!\n"); 07429 sig_pri_unlock_private(p); 07430 return -1; 07431 } 07432 07433 sig_pri_unlock_private(p); 07434 07435 return 0; 07436 }
static void* pri_ss_thread | ( | void * | data | ) | [static] |
Definition at line 1563 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_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(), 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_TONE_DIALTONE, sig_pri_unlock_private(), sig_pri_span::span, ast_party_dialed::str, ast_party_id::tag, ast_channel::tech_pvt, and sig_pri_chan::user_tag.
01564 { 01565 struct sig_pri_chan *p = data; 01566 struct ast_channel *chan = p->owner; 01567 char exten[AST_MAX_EXTENSION]; 01568 int res; 01569 int len; 01570 int timeout; 01571 01572 if (!chan) { 01573 /* We lost the owner before we could get started. */ 01574 return NULL; 01575 } 01576 01577 /* 01578 * In the bizarre case where the channel has become a zombie before we 01579 * even get started here, abort safely. 01580 */ 01581 if (!chan->tech_pvt) { 01582 ast_log(LOG_WARNING, "Channel became a zombie before simple switch could be started (%s)\n", chan->name); 01583 ast_hangup(chan); 01584 return NULL; 01585 } 01586 01587 ast_verb(3, "Starting simple switch on '%s'\n", chan->name); 01588 01589 sig_pri_dsp_reset_and_flush_digits(p); 01590 01591 /* Now loop looking for an extension */ 01592 ast_copy_string(exten, p->exten, sizeof(exten)); 01593 len = strlen(exten); 01594 res = 0; 01595 while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) { 01596 if (len && !ast_ignore_pattern(chan->context, exten)) 01597 sig_pri_play_tone(p, -1); 01598 else 01599 sig_pri_play_tone(p, SIG_PRI_TONE_DIALTONE); 01600 if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num)) 01601 timeout = pri_matchdigittimeout; 01602 else 01603 timeout = pri_gendigittimeout; 01604 res = ast_waitfordigit(chan, timeout); 01605 if (res < 0) { 01606 ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n"); 01607 ast_hangup(chan); 01608 return NULL; 01609 } else if (res) { 01610 exten[len++] = res; 01611 exten[len] = '\0'; 01612 } else 01613 break; 01614 } 01615 /* if no extension was received ('unspecified') on overlap call, use the 's' extension */ 01616 if (ast_strlen_zero(exten)) { 01617 ast_verb(3, "Going to extension s|1 because of empty extension received on overlap call\n"); 01618 exten[0] = 's'; 01619 exten[1] = '\0'; 01620 } else { 01621 ast_free(chan->dialed.number.str); 01622 chan->dialed.number.str = ast_strdup(exten); 01623 01624 if (p->pri->append_msn_to_user_tag && p->pri->nodetype != PRI_NETWORK) { 01625 /* 01626 * Update the user tag for party id's from this device for this call 01627 * now that we have a complete MSN from the network. 01628 */ 01629 snprintf(p->user_tag, sizeof(p->user_tag), "%s_%s", p->pri->initial_user_tag, 01630 exten); 01631 ast_free(chan->caller.id.tag); 01632 chan->caller.id.tag = ast_strdup(p->user_tag); 01633 } 01634 } 01635 sig_pri_play_tone(p, -1); 01636 if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num)) { 01637 /* Start the real PBX */ 01638 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 01639 sig_pri_dsp_reset_and_flush_digits(p); 01640 #if defined(ISSUE_16789) 01641 /* 01642 * Conditionaled out this code to effectively revert the Mantis 01643 * issue 16789 change. It breaks overlap dialing through 01644 * Asterisk. There is not enough information available at this 01645 * point to know if dialing is complete. The 01646 * ast_exists_extension(), ast_matchmore_extension(), and 01647 * ast_canmatch_extension() calls are not adequate to detect a 01648 * dial through extension pattern of "_9!". 01649 * 01650 * Workaround is to use the dialplan Proceeding() application 01651 * early on non-dial through extensions. 01652 */ 01653 if ((p->pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING) 01654 && !ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) { 01655 sig_pri_lock_private(p); 01656 if (p->pri->pri) { 01657 if (!pri_grab(p, p->pri)) { 01658 if (p->call_level < SIG_PRI_CALL_LEVEL_PROCEEDING) { 01659 p->call_level = SIG_PRI_CALL_LEVEL_PROCEEDING; 01660 } 01661 pri_proceeding(p->pri->pri, p->call, PVT_TO_CHANNEL(p), 0); 01662 pri_rel(p->pri); 01663 } else { 01664 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->pri->span); 01665 } 01666 } 01667 sig_pri_unlock_private(p); 01668 } 01669 #endif /* defined(ISSUE_16789) */ 01670 01671 sig_pri_set_echocanceller(p, 1); 01672 ast_setstate(chan, AST_STATE_RING); 01673 res = ast_pbx_run(chan); 01674 if (res) { 01675 ast_log(LOG_WARNING, "PBX exited non-zero!\n"); 01676 } 01677 } else { 01678 ast_log(LOG_DEBUG, "No such possible extension '%s' in context '%s'\n", exten, chan->context); 01679 chan->hangupcause = AST_CAUSE_UNALLOCATED; 01680 ast_hangup(chan); 01681 p->exten[0] = '\0'; 01682 /* Since we send release complete here, we won't get one */ 01683 p->call = NULL; 01684 } 01685 return NULL; 01686 }
static enum AST_PARTY_CHAR_SET pri_to_ast_char_set | ( | int | pri_char_set | ) | [static] |
Definition at line 475 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().
00476 { 00477 enum AST_PARTY_CHAR_SET ast_char_set; 00478 00479 switch (pri_char_set) { 00480 default: 00481 case PRI_CHAR_SET_UNKNOWN: 00482 ast_char_set = AST_PARTY_CHAR_SET_UNKNOWN; 00483 break; 00484 case PRI_CHAR_SET_ISO8859_1: 00485 ast_char_set = AST_PARTY_CHAR_SET_ISO8859_1; 00486 break; 00487 case PRI_CHAR_SET_WITHDRAWN: 00488 ast_char_set = AST_PARTY_CHAR_SET_WITHDRAWN; 00489 break; 00490 case PRI_CHAR_SET_ISO8859_2: 00491 ast_char_set = AST_PARTY_CHAR_SET_ISO8859_2; 00492 break; 00493 case PRI_CHAR_SET_ISO8859_3: 00494 ast_char_set = AST_PARTY_CHAR_SET_ISO8859_3; 00495 break; 00496 case PRI_CHAR_SET_ISO8859_4: 00497 ast_char_set = AST_PARTY_CHAR_SET_ISO8859_4; 00498 break; 00499 case PRI_CHAR_SET_ISO8859_5: 00500 ast_char_set = AST_PARTY_CHAR_SET_ISO8859_5; 00501 break; 00502 case PRI_CHAR_SET_ISO8859_7: 00503 ast_char_set = AST_PARTY_CHAR_SET_ISO8859_7; 00504 break; 00505 case PRI_CHAR_SET_ISO10646_BMPSTRING: 00506 ast_char_set = AST_PARTY_CHAR_SET_ISO10646_BMPSTRING; 00507 break; 00508 case PRI_CHAR_SET_ISO10646_UTF_8STRING: 00509 ast_char_set = AST_PARTY_CHAR_SET_ISO10646_UTF_8STRING; 00510 break; 00511 } 00512 00513 return ast_char_set; 00514 }
static int pri_to_ast_presentation | ( | int | pri_presentation | ) | [static] |
Definition at line 377 of file sig_pri.c.
References AST_PRES_ALLOWED_NETWORK_NUMBER, AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN, AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, AST_PRES_NUMBER_NOT_AVAILABLE, AST_PRES_PROHIB_NETWORK_NUMBER, AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN, AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED, and AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN.
Referenced by sig_pri_party_name_convert(), and sig_pri_party_number_convert().
00378 { 00379 int ast_presentation; 00380 00381 switch (pri_presentation) { 00382 case PRES_ALLOWED_USER_NUMBER_NOT_SCREENED: 00383 ast_presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; 00384 break; 00385 case PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN: 00386 ast_presentation = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN; 00387 break; 00388 case PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN: 00389 ast_presentation = AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN; 00390 break; 00391 case PRES_ALLOWED_NETWORK_NUMBER: 00392 ast_presentation = AST_PRES_ALLOWED_NETWORK_NUMBER; 00393 break; 00394 case PRES_PROHIB_USER_NUMBER_NOT_SCREENED: 00395 ast_presentation = AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED; 00396 break; 00397 case PRES_PROHIB_USER_NUMBER_PASSED_SCREEN: 00398 ast_presentation = AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN; 00399 break; 00400 case PRES_PROHIB_USER_NUMBER_FAILED_SCREEN: 00401 ast_presentation = AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN; 00402 break; 00403 case PRES_PROHIB_NETWORK_NUMBER: 00404 ast_presentation = AST_PRES_PROHIB_NETWORK_NUMBER; 00405 break; 00406 case PRES_NUMBER_NOT_AVAILABLE: 00407 ast_presentation = AST_PRES_NUMBER_NOT_AVAILABLE; 00408 break; 00409 default: 00410 ast_presentation = AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED; 00411 break; 00412 } 00413 00414 return ast_presentation; 00415 }
static enum AST_REDIRECTING_REASON pri_to_ast_reason | ( | int | pri_reason | ) | [static] |
Definition at line 307 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().
00308 { 00309 enum AST_REDIRECTING_REASON ast_reason; 00310 00311 switch (pri_reason) { 00312 case PRI_REDIR_FORWARD_ON_BUSY: 00313 ast_reason = AST_REDIRECTING_REASON_USER_BUSY; 00314 break; 00315 case PRI_REDIR_FORWARD_ON_NO_REPLY: 00316 ast_reason = AST_REDIRECTING_REASON_NO_ANSWER; 00317 break; 00318 case PRI_REDIR_DEFLECTION: 00319 ast_reason = AST_REDIRECTING_REASON_DEFLECTION; 00320 break; 00321 case PRI_REDIR_UNCONDITIONAL: 00322 ast_reason = AST_REDIRECTING_REASON_UNCONDITIONAL; 00323 break; 00324 case PRI_REDIR_UNKNOWN: 00325 default: 00326 ast_reason = AST_REDIRECTING_REASON_UNKNOWN; 00327 break; 00328 } 00329 00330 return ast_reason; 00331 }
static unsigned int PVT_TO_CHANNEL | ( | struct sig_pri_chan * | p | ) | [static] |
Definition at line 117 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().
00118 { 00119 int res = (((p)->prioffset) | ((p)->logicalspan << 8) | (p->mastertrunkgroup ? PRI_EXPLICIT : 0)); 00120 ast_debug(5, "prioffset: %d mastertrunkgroup: %d logicalspan: %d result: %d\n", 00121 p->prioffset, p->mastertrunkgroup, p->logicalspan, res); 00122 00123 return res; 00124 }
static char* redirectingreason2str | ( | int | redirectingreason | ) | [static] |
Definition at line 1306 of file sig_pri.c.
01307 { 01308 switch (redirectingreason) { 01309 case 0: 01310 return "UNKNOWN"; 01311 case 1: 01312 return "BUSY"; 01313 case 2: 01314 return "NO_REPLY"; 01315 case 0xF: 01316 return "UNCONDITIONAL"; 01317 default: 01318 return "NOREDIRECT"; 01319 } 01320 }
int sig_pri_answer | ( | struct sig_pri_chan * | p, | |
struct ast_channel * | ast | |||
) |
Definition at line 6763 of file sig_pri.c.
References ast_setstate(), AST_STATE_UP, sig_pri_chan::call, sig_pri_chan::call_level, sig_pri_chan::digital, sig_pri_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().
06764 { 06765 int res = 0; 06766 /* Send a pri acknowledge */ 06767 if (!pri_grab(p, p->pri)) { 06768 #if defined(HAVE_PRI_AOC_EVENTS) 06769 if (p->aoc_s_request_invoke_id_valid) { 06770 /* if AOC-S was requested and the invoke id is still present on answer. That means 06771 * no AOC-S rate list was provided, so send a NULL response which will indicate that 06772 * AOC-S is not available */ 06773 pri_aoc_s_request_response_send(p->pri->pri, p->call, 06774 p->aoc_s_request_invoke_id, NULL); 06775 p->aoc_s_request_invoke_id_valid = 0; 06776 } 06777 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 06778 if (p->call_level < SIG_PRI_CALL_LEVEL_CONNECT) { 06779 p->call_level = SIG_PRI_CALL_LEVEL_CONNECT; 06780 } 06781 sig_pri_set_dialing(p, 0); 06782 sig_pri_open_media(p); 06783 res = pri_answer(p->pri->pri, p->call, 0, !p->digital); 06784 pri_rel(p->pri); 06785 } else { 06786 res = -1; 06787 } 06788 ast_setstate(ast, AST_STATE_UP); 06789 return res; 06790 }
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 2019 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_pri_call(), sig_pri_span::pvts, sig_pri_lock_owner(), sig_pri_lock_private(), and sig_pri_unlock_private().
Referenced by sig_pri_handle_subcmds().
02020 { 02021 struct attempt_xfer_call { 02022 q931_call *pri; 02023 struct ast_channel *ast; 02024 int held; 02025 int chanpos; 02026 }; 02027 int retval; 02028 struct ast_channel *transferee; 02029 struct attempt_xfer_call *call_1; 02030 struct attempt_xfer_call *call_2; 02031 struct attempt_xfer_call *swap_call; 02032 struct attempt_xfer_call c1; 02033 struct attempt_xfer_call c2; 02034 02035 c1.pri = call_1_pri; 02036 c1.held = call_1_held; 02037 call_1 = &c1; 02038 02039 c2.pri = call_2_pri; 02040 c2.held = call_2_held; 02041 call_2 = &c2; 02042 02043 call_1->chanpos = pri_find_pri_call(pri, call_1->pri); 02044 call_2->chanpos = pri_find_pri_call(pri, call_2->pri); 02045 if (call_1->chanpos < 0 || call_2->chanpos < 0) { 02046 /* Calls not found in span control. */ 02047 if (rsp_callback) { 02048 /* Transfer failed. */ 02049 rsp_callback(data, 0); 02050 } 02051 return -1; 02052 } 02053 02054 /* Attempt to make transferee and target consistent. */ 02055 if (!call_1->held && call_2->held) { 02056 /* 02057 * Swap call_1 and call_2 to make call_1 the transferee(held call) 02058 * and call_2 the target(active call). 02059 */ 02060 swap_call = call_1; 02061 call_1 = call_2; 02062 call_2 = swap_call; 02063 } 02064 02065 /* Deadlock avoidance is attempted. */ 02066 sig_pri_lock_private(pri->pvts[call_1->chanpos]); 02067 sig_pri_lock_owner(pri, call_1->chanpos); 02068 sig_pri_lock_private(pri->pvts[call_2->chanpos]); 02069 sig_pri_lock_owner(pri, call_2->chanpos); 02070 02071 call_1->ast = pri->pvts[call_1->chanpos]->owner; 02072 call_2->ast = pri->pvts[call_2->chanpos]->owner; 02073 if (!call_1->ast || !call_2->ast) { 02074 /* At least one owner is not present. */ 02075 if (call_1->ast) { 02076 ast_channel_unlock(call_1->ast); 02077 } 02078 if (call_2->ast) { 02079 ast_channel_unlock(call_2->ast); 02080 } 02081 sig_pri_unlock_private(pri->pvts[call_1->chanpos]); 02082 sig_pri_unlock_private(pri->pvts[call_2->chanpos]); 02083 if (rsp_callback) { 02084 /* Transfer failed. */ 02085 rsp_callback(data, 0); 02086 } 02087 return -1; 02088 } 02089 02090 for (;;) { 02091 transferee = ast_bridged_channel(call_1->ast); 02092 if (transferee) { 02093 break; 02094 } 02095 02096 /* Try masquerading the other way. */ 02097 swap_call = call_1; 02098 call_1 = call_2; 02099 call_2 = swap_call; 02100 02101 transferee = ast_bridged_channel(call_1->ast); 02102 if (transferee) { 02103 break; 02104 } 02105 02106 /* Could not transfer. Neither call is bridged. */ 02107 ast_channel_unlock(call_1->ast); 02108 ast_channel_unlock(call_2->ast); 02109 sig_pri_unlock_private(pri->pvts[call_1->chanpos]); 02110 sig_pri_unlock_private(pri->pvts[call_2->chanpos]); 02111 02112 if (rsp_callback) { 02113 /* Transfer failed. */ 02114 rsp_callback(data, 0); 02115 } 02116 return -1; 02117 } 02118 02119 ast_verb(3, "TRANSFERRING %s to %s\n", call_1->ast->name, call_2->ast->name); 02120 02121 /* 02122 * Setup transfer masquerade. 02123 * 02124 * Note: There is an extremely nasty deadlock avoidance issue 02125 * with ast_channel_transfer_masquerade(). Deadlock may be possible if 02126 * the channels involved are proxies (chan_agent channels) and 02127 * it is called with locks. Unfortunately, there is no simple 02128 * or even merely difficult way to guarantee deadlock avoidance 02129 * and still be able to send an ECT success response without the 02130 * possibility of the bridged channel hanging up on us. 02131 */ 02132 ast_mutex_unlock(&pri->lock); 02133 retval = ast_channel_transfer_masquerade( 02134 call_2->ast, 02135 &call_2->ast->connected, 02136 call_2->held, 02137 transferee, 02138 &call_1->ast->connected, 02139 call_1->held); 02140 02141 /* Reacquire the pri->lock to hold off completion of the transfer masquerade. */ 02142 ast_mutex_lock(&pri->lock); 02143 02144 ast_channel_unlock(call_1->ast); 02145 ast_channel_unlock(call_2->ast); 02146 sig_pri_unlock_private(pri->pvts[call_1->chanpos]); 02147 sig_pri_unlock_private(pri->pvts[call_2->chanpos]); 02148 02149 if (rsp_callback) { 02150 /* 02151 * Report transfer status. 02152 * 02153 * Must do the callback before the masquerade completes to ensure 02154 * that the protocol message goes out before the call leg is 02155 * disconnected. 02156 */ 02157 rsp_callback(data, retval ? 0 : 1); 02158 } 02159 return retval; 02160 }
int sig_pri_available | ( | struct sig_pri_chan ** | pvt, | |
int | is_specific_channel | |||
) |
Definition at line 6867 of file sig_pri.c.
References sig_pri_chan::pri, and sig_pri_available_check().
Referenced by available().
06868 { 06869 struct sig_pri_chan *p = *pvt; 06870 06871 if (!p->pri) { 06872 /* Something is wrong here. A PRI channel without the pri pointer? */ 06873 return 0; 06874 } 06875 06876 if ( 06877 #if defined(HAVE_PRI_CALL_WAITING) 06878 /* 06879 * Only do call waiting calls if we have any 06880 * call waiting call outstanding. We do not 06881 * want new calls to steal a B channel 06882 * freed for an earlier call waiting call. 06883 */ 06884 !p->pri->num_call_waiting_calls && 06885 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 06886 sig_pri_available_check(p)) { 06887 return 1; 06888 } 06889 06890 #if defined(HAVE_PRI_CALL_WAITING) 06891 if (!is_specific_channel) { 06892 struct sig_pri_chan *cw; 06893 06894 cw = sig_pri_cw_available(p->pri); 06895 if (cw) { 06896 /* We have a call waiting interface to use instead. */ 06897 *pvt = cw; 06898 return 1; 06899 } 06900 } 06901 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 06902 return 0; 06903 }
static int sig_pri_available_check | ( | struct sig_pri_chan * | pvt | ) | [static] |
Definition at line 6802 of file sig_pri.c.
References sig_pri_chan::call, sig_pri_chan::inalarm, sig_pri_chan::no_b_channel, sig_pri_chan::owner, sig_pri_chan::resetting, and sig_pri_chan::service_status.
Referenced by sig_pri_available().
06803 { 06804 /* 06805 * If no owner, interface has a B channel, not resetting, not already with call, 06806 * not in alarm, and in-service then available. 06807 */ 06808 if (!pvt->owner && !pvt->no_b_channel && !pvt->resetting && !pvt->call 06809 && !pvt->inalarm) { 06810 #if defined(HAVE_PRI_SERVICE_MESSAGES) 06811 if (pvt->service_status) { 06812 return 0; 06813 } 06814 #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */ 06815 return 1; 06816 } 06817 return 0; 06818 }
int sig_pri_call | ( | struct sig_pri_chan * | p, | |
struct ast_channel * | ast, | |||
char * | rdest, | |||
int | timeout, | |||
int | layer1 | |||
) |
Definition at line 6091 of file sig_pri.c.
References ast_channel::_state, ao2_ref, sig_pri_span::append_msn_to_user_tag, args, AST_APP_ARG, ast_app_parse_options(), ast_assert, ast_cc_get_monitor_by_recall_core_id(), ast_cc_is_recall(), ast_channel_get_device_name(), AST_CHANNEL_NAME, ast_copy_string(), AST_DECLARE_APP_ARGS, ast_free, ast_log(), AST_NONSTANDARD_APP_ARGS, ast_party_subaddress_init(), ast_setstate(), AST_STATE_DIALING, AST_STATE_DOWN, AST_STATE_RESERVED, ast_strdup, ast_strlen_zero(), ast_test_flag, ast_transfercapability2str(), ast_verb, sig_pri_chan::call, sig_pri_chan::call_level, ast_channel::caller, sig_pri_chan::channel, ast_channel::connected, sig_pri_chan::dialdest, sig_pri_span::dialplan, dialplan2str(), sig_pri_chan::digital, ext, sig_pri_span::facilityenable, sig_pri_chan::hidecallerid, sig_pri_chan::hidecalleridname, ast_party_connected_line::id, ast_party_caller::id, sig_pri_span::initial_user_tag, sig_pri_span::internationalprefix, IS_DIGITAL, sig_pri_span::localdialplan, LOG_DEBUG, LOG_ERROR, LOG_WARNING, monitor, ast_party_id::name, ast_channel::name, sig_pri_span::nationalprefix, sig_pri_span::nodetype, ast_party_id::number, ast_party_subaddress::odd_even_indicator, OPT_AOC_REQUEST, OPT_ARG_AOC_REQUEST, OPT_ARG_ARRAY_SIZE, OPT_ARG_KEYPAD, OPT_KEYPAD, OPT_REVERSE_CHARGE, sig_pri_chan::outgoing, sig_pri_chan::owner, pbx_builtin_getvar_helper(), ast_party_number::presentation, sig_pri_chan::pri, sig_pri_span::pri, pri_grab(), pri_rel(), PRI_TRANS_CAP_DIGITAL, sig_pri_chan::priexclusive, PVT_TO_CHANNEL(), S_COR, SIG_PRI_CALL_LEVEL_SETUP, sig_pri_call_opts, sig_pri_party_subaddress_from_ast(), sig_pri_redirecting_update(), sig_pri_set_dialing(), sig_pri_set_digital(), ast_party_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().
06092 { 06093 char dest[256]; /* must be same length as p->dialdest */ 06094 struct ast_party_subaddress dialed_subaddress; /* Called subaddress */ 06095 struct pri_sr *sr; 06096 char *c, *l, *n, *s; 06097 #ifdef SUPPORT_USERUSER 06098 const char *useruser; 06099 #endif 06100 int core_id; 06101 int pridialplan; 06102 int dp_strip; 06103 int prilocaldialplan; 06104 int ldp_strip; 06105 int exclusive; 06106 #if defined(HAVE_PRI_SETUP_KEYPAD) 06107 const char *keypad; 06108 #endif /* defined(HAVE_PRI_SETUP_KEYPAD) */ 06109 AST_DECLARE_APP_ARGS(args, 06110 AST_APP_ARG(group); /* channel/group token */ 06111 AST_APP_ARG(ext); /* extension token */ 06112 AST_APP_ARG(opts); /* options token */ 06113 AST_APP_ARG(other); /* Any remining unused arguments */ 06114 ); 06115 struct ast_flags opts; 06116 char *opt_args[OPT_ARG_ARRAY_SIZE]; 06117 06118 ast_log(LOG_DEBUG, "CALLER NAME: %s NUM: %s\n", 06119 S_COR(ast->connected.id.name.valid, ast->connected.id.name.str, ""), 06120 S_COR(ast->connected.id.number.valid, ast->connected.id.number.str, "")); 06121 06122 if (!p->pri) { 06123 ast_log(LOG_ERROR, "Could not find pri on channel %d\n", p->channel); 06124 return -1; 06125 } 06126 06127 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { 06128 ast_log(LOG_WARNING, "sig_pri_call called on %s, neither down nor reserved\n", ast->name); 06129 return -1; 06130 } 06131 06132 p->dialdest[0] = '\0'; 06133 p->outgoing = 1; 06134 06135 ast_copy_string(dest, rdest, sizeof(dest)); 06136 AST_NONSTANDARD_APP_ARGS(args, dest, '/'); 06137 if (ast_app_parse_options(sig_pri_call_opts, &opts, opt_args, args.opts)) { 06138 /* General invalid option syntax. */ 06139 return -1; 06140 } 06141 06142 c = args.ext; 06143 if (!c) { 06144 c = ""; 06145 } 06146 06147 /* setup dialed_subaddress if found */ 06148 ast_party_subaddress_init(&dialed_subaddress); 06149 s = strchr(c, ':'); 06150 if (s) { 06151 *s = '\0'; 06152 s++; 06153 /* prefix */ 06154 /* 'n' = NSAP */ 06155 /* 'U' = odd, 'u'= even */ 06156 /* Default = NSAP */ 06157 switch (*s) { 06158 case 'U': 06159 dialed_subaddress.odd_even_indicator = 1; 06160 /* fall through */ 06161 case 'u': 06162 s++; 06163 dialed_subaddress.type = 2; 06164 break; 06165 case 'N': 06166 case 'n': 06167 s++; 06168 /* default already covered with ast_party_subaddress_init */ 06169 break; 06170 } 06171 dialed_subaddress.str = s; 06172 dialed_subaddress.valid = 1; 06173 s = NULL; 06174 } 06175 06176 l = NULL; 06177 n = NULL; 06178 if (!p->hidecallerid) { 06179 if (ast->connected.id.number.valid) { 06180 /* If we get to the end of this loop without breaking, there's no 06181 * calleridnum. This is done instead of testing for "unknown" or 06182 * the thousands of other ways that the calleridnum could be 06183 * invalid. */ 06184 for (l = ast->connected.id.number.str; l && *l; l++) { 06185 if (strchr("0123456789", *l)) { 06186 l = ast->connected.id.number.str; 06187 break; 06188 } 06189 } 06190 } else { 06191 l = NULL; 06192 } 06193 if (!p->hidecalleridname) { 06194 n = ast->connected.id.name.valid ? ast->connected.id.name.str : NULL; 06195 } 06196 } 06197 06198 if (strlen(c) < p->stripmsd) { 06199 ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd); 06200 return -1; 06201 } 06202 if (pri_grab(p, p->pri)) { 06203 ast_log(LOG_WARNING, "Failed to grab PRI!\n"); 06204 return -1; 06205 } 06206 if (!(p->call = pri_new_call(p->pri->pri))) { 06207 ast_log(LOG_WARNING, "Unable to create call on channel %d\n", p->channel); 06208 pri_rel(p->pri); 06209 return -1; 06210 } 06211 if (!(sr = pri_sr_new())) { 06212 ast_log(LOG_WARNING, "Failed to allocate setup request channel %d\n", p->channel); 06213 pri_destroycall(p->pri->pri, p->call); 06214 p->call = NULL; 06215 pri_rel(p->pri); 06216 return -1; 06217 } 06218 06219 sig_pri_set_digital(p, IS_DIGITAL(ast->transfercapability)); /* push up to parent for EC */ 06220 06221 #if defined(HAVE_PRI_CALL_WAITING) 06222 if (p->is_call_waiting) { 06223 /* 06224 * Indicate that this is a call waiting call. 06225 * i.e., Normal call but with no B channel. 06226 */ 06227 pri_sr_set_channel(sr, 0, 0, 1); 06228 } else 06229 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 06230 { 06231 /* Should the picked channel be used exclusively? */ 06232 if (p->priexclusive || p->pri->nodetype == PRI_NETWORK) { 06233 exclusive = 1; 06234 } else { 06235 exclusive = 0; 06236 } 06237 pri_sr_set_channel(sr, PVT_TO_CHANNEL(p), exclusive, 1); 06238 } 06239 06240 pri_sr_set_bearer(sr, p->digital ? PRI_TRANS_CAP_DIGITAL : ast->transfercapability, 06241 (p->digital ? -1 : layer1)); 06242 06243 if (p->pri->facilityenable) 06244 pri_facility_enable(p->pri->pri); 06245 06246 ast_verb(3, "Requested transfer capability: 0x%.2x - %s\n", ast->transfercapability, ast_transfercapability2str(ast->transfercapability)); 06247 dp_strip = 0; 06248 pridialplan = p->pri->dialplan - 1; 06249 if (pridialplan == -2 || pridialplan == -3) { /* compute dynamically */ 06250 if (strncmp(c + p->stripmsd, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) { 06251 if (pridialplan == -2) { 06252 dp_strip = strlen(p->pri->internationalprefix); 06253 } 06254 pridialplan = PRI_INTERNATIONAL_ISDN; 06255 } else if (strncmp(c + p->stripmsd, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) { 06256 if (pridialplan == -2) { 06257 dp_strip = strlen(p->pri->nationalprefix); 06258 } 06259 pridialplan = PRI_NATIONAL_ISDN; 06260 } else { 06261 pridialplan = PRI_LOCAL_ISDN; 06262 } 06263 } 06264 while (c[p->stripmsd] > '9' && c[p->stripmsd] != '*' && c[p->stripmsd] != '#') { 06265 switch (c[p->stripmsd]) { 06266 case 'U': 06267 pridialplan = (PRI_TON_UNKNOWN << 4) | (pridialplan & 0xf); 06268 break; 06269 case 'I': 06270 pridialplan = (PRI_TON_INTERNATIONAL << 4) | (pridialplan & 0xf); 06271 break; 06272 case 'N': 06273 pridialplan = (PRI_TON_NATIONAL << 4) | (pridialplan & 0xf); 06274 break; 06275 case 'L': 06276 pridialplan = (PRI_TON_NET_SPECIFIC << 4) | (pridialplan & 0xf); 06277 break; 06278 case 'S': 06279 pridialplan = (PRI_TON_SUBSCRIBER << 4) | (pridialplan & 0xf); 06280 break; 06281 case 'V': 06282 pridialplan = (PRI_TON_ABBREVIATED << 4) | (pridialplan & 0xf); 06283 break; 06284 case 'R': 06285 pridialplan = (PRI_TON_RESERVED << 4) | (pridialplan & 0xf); 06286 break; 06287 case 'u': 06288 pridialplan = PRI_NPI_UNKNOWN | (pridialplan & 0xf0); 06289 break; 06290 case 'e': 06291 pridialplan = PRI_NPI_E163_E164 | (pridialplan & 0xf0); 06292 break; 06293 case 'x': 06294 pridialplan = PRI_NPI_X121 | (pridialplan & 0xf0); 06295 break; 06296 case 'f': 06297 pridialplan = PRI_NPI_F69 | (pridialplan & 0xf0); 06298 break; 06299 case 'n': 06300 pridialplan = PRI_NPI_NATIONAL | (pridialplan & 0xf0); 06301 break; 06302 case 'p': 06303 pridialplan = PRI_NPI_PRIVATE | (pridialplan & 0xf0); 06304 break; 06305 case 'r': 06306 pridialplan = PRI_NPI_RESERVED | (pridialplan & 0xf0); 06307 break; 06308 default: 06309 if (isalpha(c[p->stripmsd])) { 06310 ast_log(LOG_WARNING, "Unrecognized pridialplan %s modifier: %c\n", 06311 c[p->stripmsd] > 'Z' ? "NPI" : "TON", c[p->stripmsd]); 06312 } 06313 break; 06314 } 06315 c++; 06316 } 06317 #if defined(HAVE_PRI_SETUP_KEYPAD) 06318 if (ast_test_flag(&opts, OPT_KEYPAD) 06319 && !ast_strlen_zero(opt_args[OPT_ARG_KEYPAD])) { 06320 /* We have a keypad facility digits option with digits. */ 06321 keypad = opt_args[OPT_ARG_KEYPAD]; 06322 pri_sr_set_keypad_digits(sr, keypad); 06323 } else { 06324 keypad = NULL; 06325 } 06326 if (!keypad || !ast_strlen_zero(c + p->stripmsd + dp_strip)) 06327 #endif /* defined(HAVE_PRI_SETUP_KEYPAD) */ 06328 { 06329 pri_sr_set_called(sr, c + p->stripmsd + dp_strip, pridialplan, s ? 1 : 0); 06330 } 06331 06332 #if defined(HAVE_PRI_SUBADDR) 06333 if (dialed_subaddress.valid) { 06334 struct pri_party_subaddress subaddress; 06335 06336 memset(&subaddress, 0, sizeof(subaddress)); 06337 sig_pri_party_subaddress_from_ast(&subaddress, &dialed_subaddress); 06338 pri_sr_set_called_subaddress(sr, &subaddress); 06339 } 06340 #endif /* defined(HAVE_PRI_SUBADDR) */ 06341 #if defined(HAVE_PRI_REVERSE_CHARGE) 06342 if (ast_test_flag(&opts, OPT_REVERSE_CHARGE)) { 06343 pri_sr_set_reversecharge(sr, PRI_REVERSECHARGE_REQUESTED); 06344 } 06345 #endif /* defined(HAVE_PRI_REVERSE_CHARGE) */ 06346 #if defined(HAVE_PRI_AOC_EVENTS) 06347 if (ast_test_flag(&opts, OPT_AOC_REQUEST) 06348 && !ast_strlen_zero(opt_args[OPT_ARG_AOC_REQUEST])) { 06349 if (strchr(opt_args[OPT_ARG_AOC_REQUEST], 's')) { 06350 pri_sr_set_aoc_charging_request(sr, PRI_AOC_REQUEST_S); 06351 } 06352 if (strchr(opt_args[OPT_ARG_AOC_REQUEST], 'd')) { 06353 pri_sr_set_aoc_charging_request(sr, PRI_AOC_REQUEST_D); 06354 } 06355 if (strchr(opt_args[OPT_ARG_AOC_REQUEST], 'e')) { 06356 pri_sr_set_aoc_charging_request(sr, PRI_AOC_REQUEST_E); 06357 } 06358 } 06359 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 06360 06361 /* Setup the user tag for party id's from this device for this call. */ 06362 if (p->pri->append_msn_to_user_tag) { 06363 snprintf(p->user_tag, sizeof(p->user_tag), "%s_%s", p->pri->initial_user_tag, 06364 p->pri->nodetype == PRI_NETWORK 06365 ? c + p->stripmsd + dp_strip 06366 : S_COR(ast->connected.id.number.valid, 06367 ast->connected.id.number.str, "")); 06368 } else { 06369 ast_copy_string(p->user_tag, p->pri->initial_user_tag, sizeof(p->user_tag)); 06370 } 06371 06372 /* 06373 * Replace the caller id tag from the channel creation 06374 * with the actual tag value. 06375 */ 06376 ast_free(ast->caller.id.tag); 06377 ast->caller.id.tag = ast_strdup(p->user_tag); 06378 06379 ldp_strip = 0; 06380 prilocaldialplan = p->pri->localdialplan - 1; 06381 if ((l != NULL) && (prilocaldialplan == -2 || prilocaldialplan == -3)) { /* compute dynamically */ 06382 if (strncmp(l, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) { 06383 if (prilocaldialplan == -2) { 06384 ldp_strip = strlen(p->pri->internationalprefix); 06385 } 06386 prilocaldialplan = PRI_INTERNATIONAL_ISDN; 06387 } else if (strncmp(l, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) { 06388 if (prilocaldialplan == -2) { 06389 ldp_strip = strlen(p->pri->nationalprefix); 06390 } 06391 prilocaldialplan = PRI_NATIONAL_ISDN; 06392 } else { 06393 prilocaldialplan = PRI_LOCAL_ISDN; 06394 } 06395 } 06396 if (l != NULL) { 06397 while (*l > '9' && *l != '*' && *l != '#') { 06398 switch (*l) { 06399 case 'U': 06400 prilocaldialplan = (PRI_TON_UNKNOWN << 4) | (prilocaldialplan & 0xf); 06401 break; 06402 case 'I': 06403 prilocaldialplan = (PRI_TON_INTERNATIONAL << 4) | (prilocaldialplan & 0xf); 06404 break; 06405 case 'N': 06406 prilocaldialplan = (PRI_TON_NATIONAL << 4) | (prilocaldialplan & 0xf); 06407 break; 06408 case 'L': 06409 prilocaldialplan = (PRI_TON_NET_SPECIFIC << 4) | (prilocaldialplan & 0xf); 06410 break; 06411 case 'S': 06412 prilocaldialplan = (PRI_TON_SUBSCRIBER << 4) | (prilocaldialplan & 0xf); 06413 break; 06414 case 'V': 06415 prilocaldialplan = (PRI_TON_ABBREVIATED << 4) | (prilocaldialplan & 0xf); 06416 break; 06417 case 'R': 06418 prilocaldialplan = (PRI_TON_RESERVED << 4) | (prilocaldialplan & 0xf); 06419 break; 06420 case 'u': 06421 prilocaldialplan = PRI_NPI_UNKNOWN | (prilocaldialplan & 0xf0); 06422 break; 06423 case 'e': 06424 prilocaldialplan = PRI_NPI_E163_E164 | (prilocaldialplan & 0xf0); 06425 break; 06426 case 'x': 06427 prilocaldialplan = PRI_NPI_X121 | (prilocaldialplan & 0xf0); 06428 break; 06429 case 'f': 06430 prilocaldialplan = PRI_NPI_F69 | (prilocaldialplan & 0xf0); 06431 break; 06432 case 'n': 06433 prilocaldialplan = PRI_NPI_NATIONAL | (prilocaldialplan & 0xf0); 06434 break; 06435 case 'p': 06436 prilocaldialplan = PRI_NPI_PRIVATE | (prilocaldialplan & 0xf0); 06437 break; 06438 case 'r': 06439 prilocaldialplan = PRI_NPI_RESERVED | (prilocaldialplan & 0xf0); 06440 break; 06441 default: 06442 if (isalpha(*l)) { 06443 ast_log(LOG_WARNING, 06444 "Unrecognized prilocaldialplan %s modifier: %c\n", 06445 *l > 'Z' ? "NPI" : "TON", *l); 06446 } 06447 break; 06448 } 06449 l++; 06450 } 06451 } 06452 pri_sr_set_caller(sr, l ? (l + ldp_strip) : NULL, n, prilocaldialplan, 06453 p->use_callingpres ? ast->connected.id.number.presentation : (l ? PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN : PRES_NUMBER_NOT_AVAILABLE)); 06454 06455 #if defined(HAVE_PRI_SUBADDR) 06456 if (ast->connected.id.subaddress.valid) { 06457 struct pri_party_subaddress subaddress; 06458 06459 memset(&subaddress, 0, sizeof(subaddress)); 06460 sig_pri_party_subaddress_from_ast(&subaddress, &ast->connected.id.subaddress); 06461 pri_sr_set_caller_subaddress(sr, &subaddress); 06462 } 06463 #endif /* defined(HAVE_PRI_SUBADDR) */ 06464 06465 sig_pri_redirecting_update(p, ast); 06466 06467 #ifdef SUPPORT_USERUSER 06468 /* User-user info */ 06469 useruser = pbx_builtin_getvar_helper(p->owner, "USERUSERINFO"); 06470 if (useruser) 06471 pri_sr_set_useruser(sr, useruser); 06472 #endif 06473 06474 #if defined(HAVE_PRI_CCSS) 06475 if (ast_cc_is_recall(ast, &core_id, sig_pri_cc_type_name)) { 06476 struct ast_cc_monitor *monitor; 06477 char device_name[AST_CHANNEL_NAME]; 06478 06479 /* This is a CC recall call. */ 06480 ast_channel_get_device_name(ast, device_name, sizeof(device_name)); 06481 monitor = ast_cc_get_monitor_by_recall_core_id(core_id, device_name); 06482 if (monitor) { 06483 struct sig_pri_cc_monitor_instance *instance; 06484 06485 instance = monitor->private_data; 06486 06487 /* If this fails then we have monitor instance ambiguity. */ 06488 ast_assert(p->pri == instance->pri); 06489 06490 if (pri_cc_call(p->pri->pri, instance->cc_id, p->call, sr)) { 06491 /* The CC recall call failed for some reason. */ 06492 ast_log(LOG_WARNING, "Unable to setup CC recall call to device %s\n", 06493 device_name); 06494 ao2_ref(monitor, -1); 06495 pri_destroycall(p->pri->pri, p->call); 06496 p->call = NULL; 06497 pri_rel(p->pri); 06498 pri_sr_free(sr); 06499 return -1; 06500 } 06501 ao2_ref(monitor, -1); 06502 } else { 06503 core_id = -1; 06504 } 06505 } else 06506 #endif /* defined(HAVE_PRI_CCSS) */ 06507 { 06508 core_id = -1; 06509 } 06510 if (core_id == -1 && pri_setup(p->pri->pri, p->call, sr)) { 06511 ast_log(LOG_WARNING, "Unable to setup call to %s (using %s)\n", 06512 c + p->stripmsd + dp_strip, dialplan2str(p->pri->dialplan)); 06513 pri_destroycall(p->pri->pri, p->call); 06514 p->call = NULL; 06515 pri_rel(p->pri); 06516 pri_sr_free(sr); 06517 return -1; 06518 } 06519 p->call_level = SIG_PRI_CALL_LEVEL_SETUP; 06520 pri_sr_free(sr); 06521 ast_setstate(ast, AST_STATE_DIALING); 06522 sig_pri_set_dialing(p, 1); 06523 pri_rel(p->pri); 06524 return 0; 06525 }
static void sig_pri_cc_generic_check | ( | struct sig_pri_span * | pri, | |
int | chanpos, | |||
enum ast_cc_service_type | service | |||
) | [static] |
Definition at line 2424 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(), 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().
02425 { 02426 struct ast_channel *owner; 02427 struct ast_cc_config_params *cc_params; 02428 #if defined(HAVE_PRI_CCSS) 02429 struct ast_cc_monitor *monitor; 02430 char device_name[AST_CHANNEL_NAME]; 02431 #endif /* defined(HAVE_PRI_CCSS) */ 02432 enum ast_cc_monitor_policies monitor_policy; 02433 int core_id; 02434 02435 if (!pri->pvts[chanpos]->outgoing) { 02436 /* This is not an outgoing call so it cannot be CC monitor. */ 02437 return; 02438 } 02439 02440 sig_pri_lock_owner(pri, chanpos); 02441 owner = pri->pvts[chanpos]->owner; 02442 if (!owner) { 02443 return; 02444 } 02445 core_id = ast_cc_get_current_core_id(owner); 02446 if (core_id == -1) { 02447 /* No CC core setup */ 02448 goto done; 02449 } 02450 02451 cc_params = ast_channel_get_cc_config_params(owner); 02452 if (!cc_params) { 02453 /* Could not get CC config parameters. */ 02454 goto done; 02455 } 02456 02457 #if defined(HAVE_PRI_CCSS) 02458 ast_channel_get_device_name(owner, device_name, sizeof(device_name)); 02459 monitor = ast_cc_get_monitor_by_recall_core_id(core_id, device_name); 02460 if (monitor) { 02461 /* CC monitor is already present so no need for generic CC. */ 02462 ao2_ref(monitor, -1); 02463 goto done; 02464 } 02465 #endif /* defined(HAVE_PRI_CCSS) */ 02466 02467 monitor_policy = ast_get_cc_monitor_policy(cc_params); 02468 switch (monitor_policy) { 02469 case AST_CC_MONITOR_NEVER: 02470 /* CCSS is not enabled. */ 02471 break; 02472 case AST_CC_MONITOR_NATIVE: 02473 if (pri->sig == SIG_BRI_PTMP && pri->nodetype == PRI_NETWORK) { 02474 /* Request generic CC monitor. */ 02475 ast_queue_cc_frame(owner, AST_CC_GENERIC_MONITOR_TYPE, 02476 sig_pri_get_orig_dialstring(pri->pvts[chanpos]), service, NULL); 02477 } 02478 break; 02479 case AST_CC_MONITOR_ALWAYS: 02480 if (pri->sig == SIG_BRI_PTMP && pri->nodetype != PRI_NETWORK) { 02481 /* 02482 * Cannot monitor PTMP TE side since this is not defined. 02483 * We are playing the roll of a phone in this case and 02484 * a phone cannot monitor a party over the network without 02485 * protocol help. 02486 */ 02487 break; 02488 } 02489 /* 02490 * We are either falling back or this is a PTMP NT span. 02491 * Request generic CC monitor. 02492 */ 02493 ast_queue_cc_frame(owner, AST_CC_GENERIC_MONITOR_TYPE, 02494 sig_pri_get_orig_dialstring(pri->pvts[chanpos]), service, NULL); 02495 break; 02496 case AST_CC_MONITOR_GENERIC: 02497 if (pri->sig == SIG_BRI_PTMP && pri->nodetype == PRI_NETWORK) { 02498 /* Request generic CC monitor. */ 02499 ast_queue_cc_frame(owner, AST_CC_GENERIC_MONITOR_TYPE, 02500 sig_pri_get_orig_dialstring(pri->pvts[chanpos]), service, NULL); 02501 } 02502 break; 02503 } 02504 02505 done: 02506 ast_channel_unlock(owner); 02507 }
void sig_pri_chan_alarm_notify | ( | struct sig_pri_chan * | p, | |
int | noalarm | |||
) |
Definition at line 7296 of file sig_pri.c.
References ast_channel::_softhangup, ast_log(), AST_SOFTHANGUP_DEV, sig_pri_chan::call, LOG_WARNING, sig_pri_chan::owner, sig_pri_chan::pri, sig_pri_span::pri, pri_grab(), pri_rel(), and sig_pri_set_alarm().
Referenced by dahdi_handle_event(), and handle_init_event().
07297 { 07298 sig_pri_set_alarm(p, !noalarm); 07299 if (!noalarm) { 07300 if (!p->pri || !p->pri->pri || (pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0)) { 07301 /* T309 is not enabled : hangup calls when alarm occurs */ 07302 if (p->call) { 07303 if (p->pri && p->pri->pri) { 07304 if (!pri_grab(p, p->pri)) { 07305 pri_hangup(p->pri->pri, p->call, -1); 07306 pri_destroycall(p->pri->pri, p->call); 07307 p->call = NULL; 07308 pri_rel(p->pri); 07309 } else 07310 ast_log(LOG_WARNING, "Failed to grab PRI!\n"); 07311 } else 07312 ast_log(LOG_WARNING, "The PRI Call has not been destroyed\n"); 07313 } 07314 if (p->owner) 07315 p->owner->_softhangup |= AST_SOFTHANGUP_DEV; 07316 } 07317 } 07318 }
void sig_pri_chan_delete | ( | struct sig_pri_chan * | doomed | ) |
Delete the sig_pri private channel structure.
doomed | sig_pri private channel structure to delete. |
Definition at line 7348 of file sig_pri.c.
References ast_free.
Referenced by destroy_dahdi_pvt().
07349 { 07350 ast_free(doomed); 07351 }
struct sig_pri_chan* sig_pri_chan_new | ( | void * | pvt_data, | |
struct sig_pri_callback * | callback, | |||
struct sig_pri_span * | pri, | |||
int | logicalspan, | |||
int | channo, | |||
int | trunkgroup | |||
) |
Definition at line 7320 of file sig_pri.c.
References ast_calloc, and sig_pri_chan::pri.
07321 { 07322 struct sig_pri_chan *p; 07323 07324 p = ast_calloc(1, sizeof(*p)); 07325 if (!p) 07326 return p; 07327 07328 p->logicalspan = logicalspan; 07329 p->prioffset = channo; 07330 p->mastertrunkgroup = trunkgroup; 07331 07332 p->calls = callback; 07333 p->chan_pvt = pvt_data; 07334 07335 p->pri = pri; 07336 07337 return p; 07338 }
void sig_pri_cli_show_span | ( | int | fd, | |
int * | dchannels, | |||
struct sig_pri_span * | pri | |||
) |
Definition at line 7384 of file sig_pri.c.
References ast_cli(), ast_mutex_lock, ast_mutex_unlock, build_status(), DAHDI_OVERLAPDIAL_INCOMING, sig_pri_span::dchanavail, sig_pri_span::dchans, free, sig_pri_span::lock, sig_pri_span::overlapdial, sig_pri_chan::pri, sig_pri_span::pri, pri_order(), and status.
Referenced by handle_pri_show_span().
07385 { 07386 int x; 07387 char status[256]; 07388 07389 for (x = 0; x < SIG_PRI_NUM_DCHANS; x++) { 07390 if (pri->dchans[x]) { 07391 #ifdef PRI_DUMP_INFO_STR 07392 char *info_str = NULL; 07393 #endif 07394 ast_cli(fd, "%s D-channel: %d\n", pri_order(x), dchannels[x]); 07395 build_status(status, sizeof(status), pri->dchanavail[x], pri->dchans[x] == pri->pri); 07396 ast_cli(fd, "Status: %s\n", status); 07397 ast_mutex_lock(&pri->lock); 07398 #ifdef PRI_DUMP_INFO_STR 07399 info_str = pri_dump_info_str(pri->pri); 07400 if (info_str) { 07401 ast_cli(fd, "%s", info_str); 07402 free(info_str); 07403 } 07404 #else 07405 pri_dump_info(pri->pri); 07406 #endif 07407 ast_mutex_unlock(&pri->lock); 07408 ast_cli(fd, "Overlap Recv: %s\n\n", (pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)?"Yes":"No"); 07409 ast_cli(fd, "\n"); 07410 } 07411 } 07412 }
void sig_pri_cli_show_spans | ( | int | fd, | |
int | span, | |||
struct sig_pri_span * | pri | |||
) |
Definition at line 7372 of file sig_pri.c.
References ast_cli(), build_status(), sig_pri_span::dchanavail, sig_pri_span::dchans, sig_pri_chan::pri, sig_pri_span::pri, and status.
Referenced by handle_pri_show_spans().
07373 { 07374 char status[256]; 07375 int x; 07376 for (x = 0; x < SIG_PRI_NUM_DCHANS; x++) { 07377 if (pri->dchans[x]) { 07378 build_status(status, sizeof(status), pri->dchanavail[x], pri->dchans[x] == pri->pri); 07379 ast_cli(fd, "PRI span %d/%d: %s\n", span, x, status); 07380 } 07381 } 07382 }
static int sig_pri_cmp_pri_chans | ( | const void * | left, | |
const void * | right | |||
) | [static] |
Definition at line 7080 of file sig_pri.c.
References sig_pri_chan::channel.
Referenced by sig_pri_sort_pri_chans().
07081 { 07082 const struct sig_pri_chan *pvt_left; 07083 const struct sig_pri_chan *pvt_right; 07084 07085 pvt_left = *(struct sig_pri_chan **) left; 07086 pvt_right = *(struct sig_pri_chan **) right; 07087 if (!pvt_left) { 07088 if (!pvt_right) { 07089 return 0; 07090 } 07091 return 1; 07092 } 07093 if (!pvt_right) { 07094 return -1; 07095 } 07096 07097 return pvt_left->channel - pvt_right->channel; 07098 }
int sig_pri_digit_begin | ( | struct sig_pri_chan * | pvt, | |
struct ast_channel * | ast, | |||
char | digit | |||
) |
Definition at line 6907 of file sig_pri.c.
References ast_channel::_state, ast_debug, ast_log(), AST_STATE_DIALING, sig_pri_chan::call, sig_pri_chan::call_level, sig_pri_chan::dialdest, LOG_WARNING, sig_pri_chan::pri, sig_pri_span::pri, pri_grab(), pri_rel(), SIG_PRI_CALL_LEVEL_CONNECT, SIG_PRI_CALL_LEVEL_OVERLAP, SIG_PRI_CALL_LEVEL_PROCEEDING, and sig_pri_span::span.
Referenced by dahdi_digit_begin().
06908 { 06909 if (ast->_state == AST_STATE_DIALING) { 06910 if (pvt->call_level < SIG_PRI_CALL_LEVEL_OVERLAP) { 06911 unsigned int len; 06912 06913 len = strlen(pvt->dialdest); 06914 if (len < sizeof(pvt->dialdest) - 1) { 06915 ast_debug(1, "Queueing digit '%c' since setup_ack not yet received\n", 06916 digit); 06917 pvt->dialdest[len++] = digit; 06918 pvt->dialdest[len] = '\0'; 06919 } else { 06920 ast_log(LOG_WARNING, 06921 "Span %d: Deferred digit buffer overflow for digit '%c'.\n", 06922 pvt->pri->span, digit); 06923 } 06924 return 0; 06925 } 06926 if (pvt->call_level < SIG_PRI_CALL_LEVEL_PROCEEDING) { 06927 if (!pri_grab(pvt, pvt->pri)) { 06928 pri_information(pvt->pri->pri, pvt->call, digit); 06929 pri_rel(pvt->pri); 06930 } else { 06931 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", pvt->pri->span); 06932 } 06933 return 0; 06934 } 06935 if (pvt->call_level < SIG_PRI_CALL_LEVEL_CONNECT) { 06936 ast_log(LOG_WARNING, 06937 "Span %d: Digit '%c' may be ignored by peer. (Call level:%d)\n", 06938 pvt->pri->span, digit, pvt->call_level); 06939 } 06940 } 06941 return 1; 06942 }
static void sig_pri_dsp_reset_and_flush_digits | ( | struct sig_pri_chan * | p | ) | [static] |
Definition at line 835 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().
00836 { 00837 if (p->calls->dsp_reset_and_flush_digits) { 00838 p->calls->dsp_reset_and_flush_digits(p->chan_pvt); 00839 } 00840 }
void sig_pri_extract_called_num_subaddr | ( | struct sig_pri_chan * | p, | |
const char * | rdest, | |||
char * | called, | |||
size_t | called_buff_size | |||
) |
Extract the called number and subaddress from the dial string.
p | sig_pri channel structure. | |
rdest | Dial string buffer to extract called number and subaddress. | |
called | Buffer to fill with extracted <number>[:<subaddress>] | |
called_buff_size | Size of buffer to fill. |
Definition at line 6012 of file sig_pri.c.
References args, AST_APP_ARG, AST_DECLARE_APP_ARGS, AST_NONSTANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), ext, and sig_pri_chan::stripmsd.
Referenced by dahdi_request().
06013 { 06014 char *dial; 06015 char *number; 06016 char *subaddr; 06017 AST_DECLARE_APP_ARGS(args, 06018 AST_APP_ARG(group); /* channel/group token */ 06019 AST_APP_ARG(ext); /* extension token */ 06020 //AST_APP_ARG(opts); /* options token */ 06021 AST_APP_ARG(other); /* Any remining unused arguments */ 06022 ); 06023 06024 /* Get private copy of dial string and break it up. */ 06025 dial = ast_strdupa(rdest); 06026 AST_NONSTANDARD_APP_ARGS(args, dial, '/'); 06027 06028 number = args.ext; 06029 if (!number) { 06030 number = ""; 06031 } 06032 06033 /* Find and extract dialed_subaddress */ 06034 subaddr = strchr(number, ':'); 06035 if (subaddr) { 06036 *subaddr++ = '\0'; 06037 06038 /* Skip subaddress type prefix. */ 06039 switch (*subaddr) { 06040 case 'U': 06041 case 'u': 06042 case 'N': 06043 case 'n': 06044 ++subaddr; 06045 break; 06046 default: 06047 break; 06048 } 06049 } 06050 06051 /* Skip type-of-number/dial-plan prefix characters. */ 06052 if (strlen(number) < p->stripmsd) { 06053 number = ""; 06054 } else { 06055 number += p->stripmsd; 06056 while (isalpha(*number)) { 06057 ++number; 06058 } 06059 } 06060 06061 /* Fill buffer with extracted number and subaddress. */ 06062 if (ast_strlen_zero(subaddr)) { 06063 /* Put in called number only since there is no subaddress. */ 06064 snprintf(called, called_buff_size, "%s", number); 06065 } else { 06066 /* Put in called number and subaddress. */ 06067 snprintf(called, called_buff_size, "%s:%s", number, subaddr); 06068 } 06069 }
void sig_pri_fixup | ( | struct ast_channel * | oldchan, | |
struct ast_channel * | newchan, | |||
struct sig_pri_chan * | pchan | |||
) |
static void sig_pri_fixup_chans | ( | struct sig_pri_chan * | old_chan, | |
struct sig_pri_chan * | new_chan | |||
) | [static] |
Definition at line 850 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().
00851 { 00852 if (old_chan->calls->fixup_chans) 00853 old_chan->calls->fixup_chans(old_chan->chan_pvt, new_chan->chan_pvt); 00854 }
static const char* sig_pri_get_orig_dialstring | ( | struct sig_pri_chan * | p | ) | [static] |
Definition at line 155 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_generic_check().
00156 { 00157 if (p->calls->get_orig_dialstring) { 00158 return p->calls->get_orig_dialstring(p->chan_pvt); 00159 } 00160 ast_log(LOG_ERROR, "get_orig_dialstring callback not defined\n"); 00161 return ""; 00162 }
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 3523 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, ast_cc_agent::core_id, monitor, sig_pri_span::pri, ast_cc_agent::private_data, and sig_pri_span::span.
03525 { 03526 int index; 03527 #if defined(HAVE_PRI_CCSS) 03528 struct ast_cc_agent *agent; 03529 struct sig_pri_cc_agent_prv *agent_prv; 03530 struct sig_pri_cc_monitor_instance *monitor; 03531 #endif /* defined(HAVE_PRI_CCSS) */ 03532 03533 if (!subcmds) { 03534 return; 03535 } 03536 for (index = 0; index < subcmds->counter_subcmd; ++index) { 03537 const struct pri_subcommand *subcmd = &subcmds->subcmd[index]; 03538 03539 switch (subcmd->cmd) { 03540 #if defined(STATUS_REQUEST_PLACE_HOLDER) 03541 case PRI_SUBCMD_STATUS_REQ: 03542 case PRI_SUBCMD_STATUS_REQ_RSP: 03543 /* Ignore for now. */ 03544 break; 03545 #endif /* defined(STATUS_REQUEST_PLACE_HOLDER) */ 03546 #if defined(HAVE_PRI_CCSS) 03547 case PRI_SUBCMD_CC_REQ: 03548 agent = sig_pri_find_cc_agent_by_cc_id(pri, subcmd->u.cc_request.cc_id); 03549 if (!agent) { 03550 pri_cc_cancel(pri->pri, subcmd->u.cc_request.cc_id); 03551 break; 03552 } 03553 if (!ast_cc_request_is_within_limits()) { 03554 if (pri_cc_req_rsp(pri->pri, subcmd->u.cc_request.cc_id, 03555 5/* queue_full */)) { 03556 pri_cc_cancel(pri->pri, subcmd->u.cc_request.cc_id); 03557 } 03558 ast_cc_failed(agent->core_id, "%s agent system CC queue full", 03559 sig_pri_cc_type_name); 03560 ao2_ref(agent, -1); 03561 break; 03562 } 03563 agent_prv = agent->private_data; 03564 agent_prv->cc_request_response_pending = 1; 03565 if (ast_cc_agent_accept_request(agent->core_id, 03566 "%s caller accepted CC offer.", sig_pri_cc_type_name)) { 03567 agent_prv->cc_request_response_pending = 0; 03568 if (pri_cc_req_rsp(pri->pri, subcmd->u.cc_request.cc_id, 03569 2/* short_term_denial */)) { 03570 pri_cc_cancel(pri->pri, subcmd->u.cc_request.cc_id); 03571 } 03572 ast_cc_failed(agent->core_id, "%s agent CC core request accept failed", 03573 sig_pri_cc_type_name); 03574 } 03575 ao2_ref(agent, -1); 03576 break; 03577 #endif /* defined(HAVE_PRI_CCSS) */ 03578 #if defined(HAVE_PRI_CCSS) 03579 case PRI_SUBCMD_CC_REQ_RSP: 03580 monitor = sig_pri_find_cc_monitor_by_cc_id(pri, 03581 subcmd->u.cc_request_rsp.cc_id); 03582 if (!monitor) { 03583 pri_cc_cancel(pri->pri, subcmd->u.cc_request_rsp.cc_id); 03584 break; 03585 } 03586 switch (subcmd->u.cc_request_rsp.status) { 03587 case 0:/* success */ 03588 ast_cc_monitor_request_acked(monitor->core_id, 03589 "%s far end accepted CC request", sig_pri_cc_type_name); 03590 break; 03591 case 1:/* timeout */ 03592 ast_verb(2, "core_id:%d %s CC request timeout\n", monitor->core_id, 03593 sig_pri_cc_type_name); 03594 ast_cc_monitor_failed(monitor->core_id, monitor->name, 03595 "%s CC request timeout", sig_pri_cc_type_name); 03596 break; 03597 case 2:/* error */ 03598 ast_verb(2, "core_id:%d %s CC request error: %s\n", monitor->core_id, 03599 sig_pri_cc_type_name, 03600 pri_facility_error2str(subcmd->u.cc_request_rsp.fail_code)); 03601 ast_cc_monitor_failed(monitor->core_id, monitor->name, 03602 "%s CC request error", sig_pri_cc_type_name); 03603 break; 03604 case 3:/* reject */ 03605 ast_verb(2, "core_id:%d %s CC request reject: %s\n", monitor->core_id, 03606 sig_pri_cc_type_name, 03607 pri_facility_reject2str(subcmd->u.cc_request_rsp.fail_code)); 03608 ast_cc_monitor_failed(monitor->core_id, monitor->name, 03609 "%s CC request reject", sig_pri_cc_type_name); 03610 break; 03611 default: 03612 ast_verb(2, "core_id:%d %s CC request unknown status %d\n", 03613 monitor->core_id, sig_pri_cc_type_name, 03614 subcmd->u.cc_request_rsp.status); 03615 ast_cc_monitor_failed(monitor->core_id, monitor->name, 03616 "%s CC request unknown status", sig_pri_cc_type_name); 03617 break; 03618 } 03619 ao2_ref(monitor, -1); 03620 break; 03621 #endif /* defined(HAVE_PRI_CCSS) */ 03622 #if defined(HAVE_PRI_CCSS) 03623 case PRI_SUBCMD_CC_REMOTE_USER_FREE: 03624 monitor = sig_pri_find_cc_monitor_by_cc_id(pri, 03625 subcmd->u.cc_remote_user_free.cc_id); 03626 if (!monitor) { 03627 pri_cc_cancel(pri->pri, subcmd->u.cc_remote_user_free.cc_id); 03628 break; 03629 } 03630 ast_cc_monitor_callee_available(monitor->core_id, 03631 "%s callee has become available", sig_pri_cc_type_name); 03632 ao2_ref(monitor, -1); 03633 break; 03634 #endif /* defined(HAVE_PRI_CCSS) */ 03635 #if defined(HAVE_PRI_CCSS) 03636 case PRI_SUBCMD_CC_B_FREE: 03637 monitor = sig_pri_find_cc_monitor_by_cc_id(pri, 03638 subcmd->u.cc_b_free.cc_id); 03639 if (!monitor) { 03640 pri_cc_cancel(pri->pri, subcmd->u.cc_b_free.cc_id); 03641 break; 03642 } 03643 ast_cc_monitor_party_b_free(monitor->core_id); 03644 ao2_ref(monitor, -1); 03645 break; 03646 #endif /* defined(HAVE_PRI_CCSS) */ 03647 #if defined(HAVE_PRI_CCSS) 03648 case PRI_SUBCMD_CC_STATUS_REQ: 03649 monitor = sig_pri_find_cc_monitor_by_cc_id(pri, 03650 subcmd->u.cc_status_req.cc_id); 03651 if (!monitor) { 03652 pri_cc_cancel(pri->pri, subcmd->u.cc_status_req.cc_id); 03653 break; 03654 } 03655 ast_cc_monitor_status_request(monitor->core_id); 03656 ao2_ref(monitor, -1); 03657 break; 03658 #endif /* defined(HAVE_PRI_CCSS) */ 03659 #if defined(HAVE_PRI_CCSS) 03660 case PRI_SUBCMD_CC_STATUS_REQ_RSP: 03661 agent = sig_pri_find_cc_agent_by_cc_id(pri, subcmd->u.cc_status_req_rsp.cc_id); 03662 if (!agent) { 03663 pri_cc_cancel(pri->pri, subcmd->u.cc_status_req_rsp.cc_id); 03664 break; 03665 } 03666 ast_cc_agent_status_response(agent->core_id, 03667 subcmd->u.cc_status_req_rsp.status ? AST_DEVICE_INUSE 03668 : AST_DEVICE_NOT_INUSE); 03669 ao2_ref(agent, -1); 03670 break; 03671 #endif /* defined(HAVE_PRI_CCSS) */ 03672 #if defined(HAVE_PRI_CCSS) 03673 case PRI_SUBCMD_CC_STATUS: 03674 agent = sig_pri_find_cc_agent_by_cc_id(pri, subcmd->u.cc_status.cc_id); 03675 if (!agent) { 03676 pri_cc_cancel(pri->pri, subcmd->u.cc_status.cc_id); 03677 break; 03678 } 03679 if (subcmd->u.cc_status.status) { 03680 ast_cc_agent_caller_busy(agent->core_id, "%s agent caller is busy", 03681 sig_pri_cc_type_name); 03682 } else { 03683 ast_cc_agent_caller_available(agent->core_id, 03684 "%s agent caller is available", sig_pri_cc_type_name); 03685 } 03686 ao2_ref(agent, -1); 03687 break; 03688 #endif /* defined(HAVE_PRI_CCSS) */ 03689 #if defined(HAVE_PRI_CCSS) 03690 case PRI_SUBCMD_CC_CANCEL: 03691 sig_pri_cc_link_canceled(pri, subcmd->u.cc_cancel.cc_id, 03692 subcmd->u.cc_cancel.is_agent); 03693 break; 03694 #endif /* defined(HAVE_PRI_CCSS) */ 03695 #if defined(HAVE_PRI_CCSS) 03696 case PRI_SUBCMD_CC_STOP_ALERTING: 03697 monitor = sig_pri_find_cc_monitor_by_cc_id(pri, 03698 subcmd->u.cc_stop_alerting.cc_id); 03699 if (!monitor) { 03700 pri_cc_cancel(pri->pri, subcmd->u.cc_stop_alerting.cc_id); 03701 break; 03702 } 03703 ast_cc_monitor_stop_ringing(monitor->core_id); 03704 ao2_ref(monitor, -1); 03705 break; 03706 #endif /* defined(HAVE_PRI_CCSS) */ 03707 #if defined(HAVE_PRI_AOC_EVENTS) 03708 case PRI_SUBCMD_AOC_E: 03709 /* Queue AST_CONTROL_AOC frame */ 03710 sig_pri_aoc_e_from_pri(&subcmd->u.aoc_e, NULL, 0); 03711 break; 03712 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 03713 default: 03714 ast_debug(2, 03715 "Unknown CIS subcommand(%d) in %s event on span %d.\n", 03716 subcmd->cmd, pri_event2str(event_id), pri->span); 03717 break; 03718 } 03719 } 03720 }
static void sig_pri_handle_dchan_exception | ( | struct sig_pri_span * | pri, | |
int | index | |||
) | [static] |
Definition at line 126 of file sig_pri.c.
References sig_pri_span::calls, and sig_pri_callback::handle_dchan_exception.
Referenced by pri_dchannel().
00127 { 00128 if (pri->calls->handle_dchan_exception) 00129 pri->calls->handle_dchan_exception(pri, index); 00130 }
static int sig_pri_handle_hold | ( | struct sig_pri_span * | pri, | |
pri_event * | ev | |||
) | [static] |
Definition at line 4120 of file sig_pri.c.
References ast_bridged_channel(), ast_channel_unlock, AST_CONTROL_HOLD, AST_FRAME_CONTROL, ast_log(), ast_queue_frame(), f, LOG_WARNING, sig_pri_chan::no_b_channel, sig_pri_chan::owner, PRI_CHANNEL, pri_find_empty_nobch(), pri_find_principle(), pri_fixup_principle(), PRI_SPAN, sig_pri_span::pvts, 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.
04121 { 04122 int retval; 04123 int chanpos_old; 04124 int chanpos_new; 04125 struct ast_channel *bridged; 04126 struct ast_channel *owner; 04127 04128 chanpos_old = pri_find_principle(pri, ev->hold.channel, ev->hold.call); 04129 if (chanpos_old < 0) { 04130 ast_log(LOG_WARNING, 04131 "Received HOLD on unconfigured channel %d/%d span %d\n", 04132 PRI_SPAN(ev->hold.channel), PRI_CHANNEL(ev->hold.channel), pri->span); 04133 return -1; 04134 } 04135 if (pri->pvts[chanpos_old]->no_b_channel) { 04136 /* Call is already on hold or is call waiting call. */ 04137 return -1; 04138 } 04139 04140 sig_pri_lock_private(pri->pvts[chanpos_old]); 04141 sig_pri_lock_owner(pri, chanpos_old); 04142 owner = pri->pvts[chanpos_old]->owner; 04143 if (!owner) { 04144 retval = -1; 04145 goto done_with_private; 04146 } 04147 bridged = ast_bridged_channel(owner); 04148 if (!bridged) { 04149 /* Cannot hold a call that is not bridged. */ 04150 retval = -1; 04151 goto done_with_owner; 04152 } 04153 chanpos_new = pri_find_empty_nobch(pri); 04154 if (chanpos_new < 0) { 04155 /* No hold channel available. */ 04156 retval = -1; 04157 goto done_with_owner; 04158 } 04159 sig_pri_handle_subcmds(pri, chanpos_old, ev->e, ev->hold.channel, ev->hold.subcmds, 04160 ev->hold.call); 04161 chanpos_new = pri_fixup_principle(pri, chanpos_new, ev->hold.call); 04162 if (chanpos_new < 0) { 04163 /* Should never happen. */ 04164 retval = -1; 04165 } else { 04166 struct ast_frame f = { AST_FRAME_CONTROL, }; 04167 04168 /* 04169 * Things are in an odd state here so we cannot use pri_queue_control(). 04170 * However, we already have the owner lock so we can simply queue the frame. 04171 */ 04172 f.subclass.integer = AST_CONTROL_HOLD; 04173 ast_queue_frame(owner, &f); 04174 04175 sig_pri_span_devstate_changed(pri); 04176 retval = 0; 04177 } 04178 04179 done_with_owner:; 04180 ast_channel_unlock(owner); 04181 done_with_private:; 04182 sig_pri_unlock_private(pri->pvts[chanpos_old]); 04183 04184 return retval; 04185 }
static void sig_pri_handle_retrieve | ( | struct sig_pri_span * | pri, | |
pri_event * | ev | |||
) | [static] |
Definition at line 4201 of file sig_pri.c.
References AST_CONTROL_UNHOLD, sig_pri_span::pri, PRI_CHANNEL, pri_find_empty_chan(), pri_find_principle(), pri_fixup_principle(), PRI_HELD_CALL, pri_queue_control(), PVT_TO_CHANNEL(), sig_pri_span::pvts, pvts, sig_pri_handle_subcmds(), sig_pri_lock_private(), sig_pri_span_devstate_changed(), and sig_pri_unlock_private().
04202 { 04203 int chanpos; 04204 04205 if (!(ev->retrieve.channel & PRI_HELD_CALL) 04206 || pri_find_principle(pri, ev->retrieve.channel, ev->retrieve.call) < 0) { 04207 /* The call is not currently held. */ 04208 pri_retrieve_rej(pri->pri, ev->retrieve.call, 04209 PRI_CAUSE_RESOURCE_UNAVAIL_UNSPECIFIED); 04210 return; 04211 } 04212 if (PRI_CHANNEL(ev->retrieve.channel) == 0xFF) { 04213 chanpos = pri_find_empty_chan(pri, 1); 04214 } else { 04215 chanpos = pri_find_principle(pri, 04216 ev->retrieve.channel & ~PRI_HELD_CALL, ev->retrieve.call); 04217 if (ev->retrieve.flexible 04218 && (chanpos < 0 || pri->pvts[chanpos]->owner)) { 04219 /* 04220 * Channel selection is flexible and the requested channel 04221 * is bad or already in use. Pick another channel. 04222 */ 04223 chanpos = pri_find_empty_chan(pri, 1); 04224 } 04225 } 04226 if (chanpos < 0) { 04227 pri_retrieve_rej(pri->pri, ev->retrieve.call, 04228 ev->retrieve.flexible ? PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION 04229 : PRI_CAUSE_REQUESTED_CHAN_UNAVAIL); 04230 return; 04231 } 04232 chanpos = pri_fixup_principle(pri, chanpos, ev->retrieve.call); 04233 if (chanpos < 0) { 04234 /* Channel is already in use. */ 04235 pri_retrieve_rej(pri->pri, ev->retrieve.call, 04236 PRI_CAUSE_REQUESTED_CHAN_UNAVAIL); 04237 return; 04238 } 04239 sig_pri_lock_private(pri->pvts[chanpos]); 04240 sig_pri_handle_subcmds(pri, chanpos, ev->e, ev->retrieve.channel, 04241 ev->retrieve.subcmds, ev->retrieve.call); 04242 pri_queue_control(pri, chanpos, AST_CONTROL_UNHOLD); 04243 sig_pri_unlock_private(pri->pvts[chanpos]); 04244 sig_pri_span_devstate_changed(pri); 04245 pri_retrieve_ack(pri->pri, ev->retrieve.call, 04246 PVT_TO_CHANNEL(pri->pvts[chanpos])); 04247 }
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 3779 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_CONTROL_BUSY, ast_copy_string(), ast_debug, ast_log(), 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_control(), ast_setup_cc_recall_datastore(), ast_strdup, ast_string_field_set, ast_channel::caller, ast_cc_agent::core_id, ast_party_redirecting::from, ast_party_caller::id, LOG_ERROR, LOG_WARNING, PRI_CHANNEL, PRI_SPAN, ast_channel::redirecting, SIG_PRI_AOC_GRANT_D, SIG_PRI_AOC_GRANT_E, SIG_PRI_AOC_GRANT_S, sig_pri_attempt_transfer(), sig_pri_lock_owner(), sig_pri_lock_private(), sig_pri_party_id_convert(), sig_pri_redirecting_convert(), sig_pri_set_caller_id(), 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().
03781 { 03782 int index; 03783 struct ast_channel *owner; 03784 struct ast_party_redirecting ast_redirecting; 03785 #if defined(HAVE_PRI_TRANSFER) 03786 struct xfer_rsp_data xfer_rsp; 03787 #endif /* defined(HAVE_PRI_TRANSFER) */ 03788 03789 if (!subcmds) { 03790 return; 03791 } 03792 for (index = 0; index < subcmds->counter_subcmd; ++index) { 03793 const struct pri_subcommand *subcmd = &subcmds->subcmd[index]; 03794 03795 switch (subcmd->cmd) { 03796 case PRI_SUBCMD_CONNECTED_LINE: 03797 sig_pri_lock_owner(pri, chanpos); 03798 owner = pri->pvts[chanpos]->owner; 03799 if (owner) { 03800 struct ast_party_connected_line ast_connected; 03801 int caller_id_update; 03802 03803 /* Extract the connected line information */ 03804 ast_party_connected_line_init(&ast_connected); 03805 sig_pri_party_id_convert(&ast_connected.id, &subcmd->u.connected_line.id, 03806 pri); 03807 ast_connected.id.tag = ast_strdup(pri->pvts[chanpos]->user_tag); 03808 03809 caller_id_update = 0; 03810 if (ast_connected.id.name.str) { 03811 /* Save name for Caller-ID update */ 03812 ast_copy_string(pri->pvts[chanpos]->cid_name, 03813 ast_connected.id.name.str, sizeof(pri->pvts[chanpos]->cid_name)); 03814 caller_id_update = 1; 03815 } 03816 if (ast_connected.id.number.str) { 03817 /* Save number for Caller-ID update */ 03818 ast_copy_string(pri->pvts[chanpos]->cid_num, 03819 ast_connected.id.number.str, sizeof(pri->pvts[chanpos]->cid_num)); 03820 pri->pvts[chanpos]->cid_ton = ast_connected.id.number.plan; 03821 caller_id_update = 1; 03822 } 03823 ast_connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER; 03824 03825 pri->pvts[chanpos]->cid_subaddr[0] = '\0'; 03826 #if defined(HAVE_PRI_SUBADDR) 03827 if (ast_connected.id.subaddress.valid) { 03828 ast_party_subaddress_set(&owner->caller.id.subaddress, 03829 &ast_connected.id.subaddress); 03830 if (ast_connected.id.subaddress.str) { 03831 ast_copy_string(pri->pvts[chanpos]->cid_subaddr, 03832 ast_connected.id.subaddress.str, 03833 sizeof(pri->pvts[chanpos]->cid_subaddr)); 03834 } 03835 } 03836 #endif /* defined(HAVE_PRI_SUBADDR) */ 03837 if (caller_id_update) { 03838 struct ast_party_caller ast_caller; 03839 03840 pri->pvts[chanpos]->callingpres = 03841 ast_party_id_presentation(&ast_connected.id); 03842 sig_pri_set_caller_id(pri->pvts[chanpos]); 03843 03844 ast_party_caller_set_init(&ast_caller, &owner->caller); 03845 ast_caller.id = ast_connected.id; 03846 ast_caller.ani = ast_connected.id; 03847 ast_channel_set_caller_event(owner, &ast_caller, NULL); 03848 } 03849 03850 /* Update the connected line information on the other channel */ 03851 if (event_id != PRI_EVENT_RING) { 03852 /* This connected_line update was not from a SETUP message. */ 03853 ast_channel_queue_connected_line_update(owner, &ast_connected, NULL); 03854 } 03855 03856 ast_party_connected_line_free(&ast_connected); 03857 ast_channel_unlock(owner); 03858 } 03859 break; 03860 case PRI_SUBCMD_REDIRECTING: 03861 sig_pri_lock_owner(pri, chanpos); 03862 owner = pri->pvts[chanpos]->owner; 03863 if (owner) { 03864 sig_pri_redirecting_convert(&ast_redirecting, &subcmd->u.redirecting, 03865 &owner->redirecting, pri); 03866 ast_redirecting.from.tag = ast_strdup(pri->pvts[chanpos]->user_tag); 03867 ast_redirecting.to.tag = ast_strdup(pri->pvts[chanpos]->user_tag); 03868 03869 /*! \todo XXX Original called data can be put in a channel data store that is inherited. */ 03870 03871 ast_channel_set_redirecting(owner, &ast_redirecting, NULL); 03872 if (event_id != PRI_EVENT_RING) { 03873 /* This redirection was not from a SETUP message. */ 03874 ast_channel_queue_redirecting_update(owner, &ast_redirecting, NULL); 03875 } 03876 ast_party_redirecting_free(&ast_redirecting); 03877 03878 ast_channel_unlock(owner); 03879 } 03880 break; 03881 #if defined(HAVE_PRI_CALL_REROUTING) 03882 case PRI_SUBCMD_REROUTING: 03883 sig_pri_lock_owner(pri, chanpos); 03884 owner = pri->pvts[chanpos]->owner; 03885 if (owner) { 03886 struct pri_party_redirecting pri_deflection; 03887 03888 if (!call_rsp) { 03889 ast_channel_unlock(owner); 03890 ast_log(LOG_WARNING, 03891 "CallRerouting/CallDeflection to '%s' without call!\n", 03892 subcmd->u.rerouting.deflection.to.number.str); 03893 break; 03894 } 03895 03896 pri_deflection = subcmd->u.rerouting.deflection; 03897 03898 ast_string_field_set(owner, call_forward, pri_deflection.to.number.str); 03899 03900 /* Adjust the deflecting to number based upon the subscription option. */ 03901 switch (subcmd->u.rerouting.subscription_option) { 03902 case 0: /* noNotification */ 03903 case 1: /* notificationWithoutDivertedToNr */ 03904 /* Delete the number because the far end is not supposed to see it. */ 03905 pri_deflection.to.number.presentation = 03906 PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_UNSCREENED; 03907 pri_deflection.to.number.plan = 03908 (PRI_TON_UNKNOWN << 4) | PRI_NPI_E163_E164; 03909 pri_deflection.to.number.str[0] = '\0'; 03910 break; 03911 case 2: /* notificationWithDivertedToNr */ 03912 break; 03913 case 3: /* notApplicable */ 03914 default: 03915 break; 03916 } 03917 sig_pri_redirecting_convert(&ast_redirecting, &pri_deflection, 03918 &owner->redirecting, pri); 03919 ast_redirecting.from.tag = ast_strdup(pri->pvts[chanpos]->user_tag); 03920 ast_redirecting.to.tag = ast_strdup(pri->pvts[chanpos]->user_tag); 03921 ast_channel_set_redirecting(owner, &ast_redirecting, NULL); 03922 ast_party_redirecting_free(&ast_redirecting); 03923 03924 /* 03925 * Send back positive ACK to CallRerouting/CallDeflection. 03926 * 03927 * Note: This call will be hungup by the dial application when 03928 * it processes the call_forward string set above. 03929 */ 03930 pri_rerouting_rsp(pri->pri, call_rsp, subcmd->u.rerouting.invoke_id, 03931 PRI_REROUTING_RSP_OK_CLEAR); 03932 03933 /* This line is BUSY to further attempts by this dialing attempt. */ 03934 ast_queue_control(owner, AST_CONTROL_BUSY); 03935 03936 ast_channel_unlock(owner); 03937 } 03938 break; 03939 #endif /* defined(HAVE_PRI_CALL_REROUTING) */ 03940 #if defined(HAVE_PRI_CCSS) 03941 case PRI_SUBCMD_CC_AVAILABLE: 03942 sig_pri_lock_owner(pri, chanpos); 03943 owner = pri->pvts[chanpos]->owner; 03944 if (owner) { 03945 enum ast_cc_service_type service; 03946 03947 switch (event_id) { 03948 case PRI_EVENT_RINGING: 03949 service = AST_CC_CCNR; 03950 break; 03951 case PRI_EVENT_HANGUP_REQ: 03952 /* We will assume that the cause was busy/congestion. */ 03953 service = AST_CC_CCBS; 03954 break; 03955 default: 03956 service = AST_CC_NONE; 03957 break; 03958 } 03959 if (service == AST_CC_NONE 03960 || sig_pri_cc_available(pri, chanpos, subcmd->u.cc_available.cc_id, 03961 service)) { 03962 pri_cc_cancel(pri->pri, subcmd->u.cc_available.cc_id); 03963 } 03964 ast_channel_unlock(owner); 03965 } else { 03966 /* No asterisk channel. */ 03967 pri_cc_cancel(pri->pri, subcmd->u.cc_available.cc_id); 03968 } 03969 break; 03970 #endif /* defined(HAVE_PRI_CCSS) */ 03971 #if defined(HAVE_PRI_CCSS) 03972 case PRI_SUBCMD_CC_CALL: 03973 sig_pri_lock_owner(pri, chanpos); 03974 owner = pri->pvts[chanpos]->owner; 03975 if (owner) { 03976 struct ast_cc_agent *agent; 03977 03978 agent = sig_pri_find_cc_agent_by_cc_id(pri, subcmd->u.cc_call.cc_id); 03979 if (agent) { 03980 ast_setup_cc_recall_datastore(owner, agent->core_id); 03981 ast_cc_agent_set_interfaces_chanvar(owner); 03982 ast_cc_agent_recalling(agent->core_id, 03983 "%s caller is attempting recall", sig_pri_cc_type_name); 03984 ao2_ref(agent, -1); 03985 } 03986 03987 ast_channel_unlock(owner); 03988 } 03989 break; 03990 #endif /* defined(HAVE_PRI_CCSS) */ 03991 #if defined(HAVE_PRI_CCSS) 03992 case PRI_SUBCMD_CC_CANCEL: 03993 sig_pri_cc_link_canceled(pri, subcmd->u.cc_cancel.cc_id, 03994 subcmd->u.cc_cancel.is_agent); 03995 break; 03996 #endif /* defined(HAVE_PRI_CCSS) */ 03997 #if defined(HAVE_PRI_TRANSFER) 03998 case PRI_SUBCMD_TRANSFER_CALL: 03999 if (!call_rsp) { 04000 /* Should never happen. */ 04001 ast_log(LOG_ERROR, 04002 "Call transfer subcommand without call to send response!\n"); 04003 break; 04004 } 04005 04006 sig_pri_unlock_private(pri->pvts[chanpos]); 04007 xfer_rsp.pri = pri; 04008 xfer_rsp.call = call_rsp; 04009 xfer_rsp.invoke_id = subcmd->u.transfer.invoke_id; 04010 sig_pri_attempt_transfer(pri, 04011 subcmd->u.transfer.call_1, subcmd->u.transfer.is_call_1_held, 04012 subcmd->u.transfer.call_2, subcmd->u.transfer.is_call_2_held, 04013 sig_pri_transfer_rsp, &xfer_rsp); 04014 sig_pri_lock_private(pri->pvts[chanpos]); 04015 break; 04016 #endif /* defined(HAVE_PRI_TRANSFER) */ 04017 #if defined(HAVE_PRI_AOC_EVENTS) 04018 case PRI_SUBCMD_AOC_S: 04019 sig_pri_lock_owner(pri, chanpos); 04020 owner = pri->pvts[chanpos]->owner; 04021 if (owner) { 04022 sig_pri_aoc_s_from_pri(&subcmd->u.aoc_s, owner, 04023 (pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_S)); 04024 ast_channel_unlock(owner); 04025 } 04026 break; 04027 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 04028 #if defined(HAVE_PRI_AOC_EVENTS) 04029 case PRI_SUBCMD_AOC_D: 04030 sig_pri_lock_owner(pri, chanpos); 04031 owner = pri->pvts[chanpos]->owner; 04032 if (owner) { 04033 /* Queue AST_CONTROL_AOC frame on channel */ 04034 sig_pri_aoc_d_from_pri(&subcmd->u.aoc_d, owner, 04035 (pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_D)); 04036 ast_channel_unlock(owner); 04037 } 04038 break; 04039 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 04040 #if defined(HAVE_PRI_AOC_EVENTS) 04041 case PRI_SUBCMD_AOC_E: 04042 sig_pri_lock_owner(pri, chanpos); 04043 owner = pri->pvts[chanpos]->owner; 04044 /* Queue AST_CONTROL_AOC frame */ 04045 sig_pri_aoc_e_from_pri(&subcmd->u.aoc_e, owner, 04046 (pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_E)); 04047 if (owner) { 04048 ast_channel_unlock(owner); 04049 } 04050 break; 04051 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 04052 #if defined(HAVE_PRI_AOC_EVENTS) 04053 case PRI_SUBCMD_AOC_CHARGING_REQ: 04054 sig_pri_lock_owner(pri, chanpos); 04055 owner = pri->pvts[chanpos]->owner; 04056 if (owner) { 04057 sig_pri_aoc_request_from_pri(&subcmd->u.aoc_request, pri->pvts[chanpos], 04058 call_rsp); 04059 ast_channel_unlock(owner); 04060 } 04061 break; 04062 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 04063 #if defined(HAVE_PRI_AOC_EVENTS) 04064 case PRI_SUBCMD_AOC_CHARGING_REQ_RSP: 04065 /* 04066 * An AOC request response may contain an AOC-S rate list. 04067 * If this is the case handle this just like we 04068 * would an incoming AOC-S msg. 04069 */ 04070 if (subcmd->u.aoc_request_response.valid_aoc_s) { 04071 sig_pri_lock_owner(pri, chanpos); 04072 owner = pri->pvts[chanpos]->owner; 04073 if (owner) { 04074 sig_pri_aoc_s_from_pri(&subcmd->u.aoc_request_response.aoc_s, owner, 04075 (pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_S)); 04076 ast_channel_unlock(owner); 04077 } 04078 } 04079 break; 04080 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 04081 #if defined(HAVE_PRI_MCID) 04082 case PRI_SUBCMD_MCID_REQ: 04083 sig_pri_lock_owner(pri, chanpos); 04084 owner = pri->pvts[chanpos]->owner; 04085 sig_pri_mcid_event(pri, &subcmd->u.mcid_req, owner); 04086 if (owner) { 04087 ast_channel_unlock(owner); 04088 } 04089 break; 04090 #endif /* defined(HAVE_PRI_MCID) */ 04091 #if defined(HAVE_PRI_MCID) 04092 case PRI_SUBCMD_MCID_RSP: 04093 /* Ignore for now. */ 04094 break; 04095 #endif /* defined(HAVE_PRI_MCID) */ 04096 default: 04097 ast_debug(2, 04098 "Unknown call subcommand(%d) in %s event on channel %d/%d on span %d.\n", 04099 subcmd->cmd, pri_event2str(event_id), PRI_SPAN(channel), 04100 PRI_CHANNEL(channel), pri->span); 04101 break; 04102 } 04103 } 04104 }
int sig_pri_hangup | ( | struct sig_pri_chan * | p, | |
struct ast_channel * | ast | |||
) |
Definition at line 5912 of file sig_pri.c.
References sig_pri_chan::alreadyhungup, ast_atomic_fetchadd_int(), ast_log(), sig_pri_chan::call, sig_pri_chan::call_level, cause, sig_pri_chan::channel, sig_pri_chan::cid_name, sig_pri_chan::cid_num, sig_pri_chan::cid_subaddr, sig_pri_chan::exten, ast_channel::hangupcause, LOG_DEBUG, LOG_WARNING, sig_pri_chan::outgoing, sig_pri_chan::owner, pbx_builtin_getvar_helper(), sig_pri_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_span_devstate_changed(), sig_pri_span::span, ast_channel::tech_pvt, and sig_pri_chan::user_tag.
Referenced by dahdi_hangup().
05913 { 05914 int res; 05915 #ifdef SUPPORT_USERUSER 05916 const char *useruser = pbx_builtin_getvar_helper(ast, "USERUSERINFO"); 05917 #endif 05918 05919 ast_log(LOG_DEBUG, "%s %d\n", __FUNCTION__, p->channel); 05920 if (!ast->tech_pvt) { 05921 ast_log(LOG_WARNING, "Asked to hangup channel not connected\n"); 05922 return 0; 05923 } 05924 05925 p->owner = NULL; 05926 p->outgoing = 0; 05927 sig_pri_set_digital(p, 0); /* push up to parent for EC*/ 05928 #if defined(HAVE_PRI_CALL_WAITING) 05929 if (p->is_call_waiting) { 05930 p->is_call_waiting = 0; 05931 ast_atomic_fetchadd_int(&p->pri->num_call_waiting_calls, -1); 05932 } 05933 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 05934 p->call_level = SIG_PRI_CALL_LEVEL_IDLE; 05935 p->progress = 0; 05936 p->cid_num[0] = '\0'; 05937 p->cid_subaddr[0] = '\0'; 05938 p->cid_name[0] = '\0'; 05939 p->user_tag[0] = '\0'; 05940 p->exten[0] = '\0'; 05941 sig_pri_set_dialing(p, 0); 05942 05943 /* Make sure we have a call (or REALLY have a call in the case of a PRI) */ 05944 if (!pri_grab(p, p->pri)) { 05945 if (p->call) { 05946 if (p->alreadyhungup) { 05947 ast_log(LOG_DEBUG, "Already hungup... Calling hangup once, and clearing call\n"); 05948 05949 #ifdef SUPPORT_USERUSER 05950 pri_call_set_useruser(p->call, useruser); 05951 #endif 05952 05953 #if defined(HAVE_PRI_AOC_EVENTS) 05954 if (p->holding_aoce) { 05955 pri_aoc_e_send(p->pri->pri, p->call, &p->aoc_e); 05956 } 05957 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 05958 pri_hangup(p->pri->pri, p->call, -1); 05959 p->call = NULL; 05960 } else { 05961 const char *cause = pbx_builtin_getvar_helper(ast,"PRI_CAUSE"); 05962 int icause = ast->hangupcause ? ast->hangupcause : -1; 05963 ast_log(LOG_DEBUG, "Not yet hungup... Calling hangup once with icause, and clearing call\n"); 05964 05965 #ifdef SUPPORT_USERUSER 05966 pri_call_set_useruser(p->call, useruser); 05967 #endif 05968 05969 p->alreadyhungup = 1; 05970 if (cause) { 05971 if (atoi(cause)) 05972 icause = atoi(cause); 05973 } 05974 #if defined(HAVE_PRI_AOC_EVENTS) 05975 if (p->holding_aoce) { 05976 pri_aoc_e_send(p->pri->pri, p->call, &p->aoc_e); 05977 } 05978 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 05979 pri_hangup(p->pri->pri, p->call, icause); 05980 } 05981 } 05982 sig_pri_span_devstate_changed(p->pri); 05983 pri_rel(p->pri); 05984 res = 0; 05985 } else { 05986 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->pri->span); 05987 res = -1; 05988 } 05989 05990 #if defined(HAVE_PRI_AOC_EVENTS) 05991 p->aoc_s_request_invoke_id_valid = 0; 05992 p->holding_aoce = 0; 05993 p->waiting_for_aoce = 0; 05994 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 05995 ast->tech_pvt = NULL; 05996 return res; 05997 }
int sig_pri_indicate | ( | struct sig_pri_chan * | p, | |
struct ast_channel * | chan, | |||
int | condition, | |||
const void * | data, | |||
size_t | datalen | |||
) |
Definition at line 6527 of file sig_pri.c.
References ast_channel::_softhangup, ast_channel::_state, AST_AOC_D, ast_aoc_decode(), ast_aoc_destroy_decoded(), AST_AOC_E, ast_aoc_get_msg_type(), ast_aoc_get_termination_request(), AST_AOC_REQUEST, AST_AOC_S, AST_CAUSE_NORMAL_CLEARING, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_USER_BUSY, AST_CONTROL_AOC, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HOLD, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_REDIRECTING, AST_CONTROL_RINGING, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, ast_debug, ast_log(), ast_moh_start(), ast_moh_stop(), ast_setstate(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, sig_pri_chan::call, sig_pri_chan::call_level, ast_channel::connected, sig_pri_chan::digital, ast_channel::hangupcause, ast_party_connected_line::id, LOG_DEBUG, LOG_WARNING, sig_pri_chan::mohinterpret, ast_channel::name, sig_pri_chan::no_b_channel, sig_pri_chan::outgoing, sig_pri_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_GRANT_D, SIG_PRI_AOC_GRANT_E, SIG_PRI_AOC_GRANT_S, SIG_PRI_CALL_LEVEL_ALERTING, SIG_PRI_CALL_LEVEL_PROCEEDING, sig_pri_party_id_from_ast(), sig_pri_play_tone(), sig_pri_redirecting_update(), sig_pri_set_dialing(), sig_pri_set_digital(), SIG_PRI_TONE_BUSY, SIG_PRI_TONE_CONGESTION, SIG_PRI_TONE_RINGTONE, and sig_pri_span::span.
Referenced by dahdi_indicate().
06528 { 06529 int res = -1; 06530 06531 switch (condition) { 06532 case AST_CONTROL_BUSY: 06533 if (p->priindication_oob || p->no_b_channel) { 06534 chan->hangupcause = AST_CAUSE_USER_BUSY; 06535 chan->_softhangup |= AST_SOFTHANGUP_DEV; 06536 res = 0; 06537 break; 06538 } 06539 res = sig_pri_play_tone(p, SIG_PRI_TONE_BUSY); 06540 if (p->call_level < SIG_PRI_CALL_LEVEL_ALERTING && !p->outgoing) { 06541 chan->hangupcause = AST_CAUSE_USER_BUSY; 06542 p->progress = 1;/* No need to send plain PROGRESS after this. */ 06543 if (p->pri && p->pri->pri) { 06544 if (!pri_grab(p, p->pri)) { 06545 #ifdef HAVE_PRI_PROG_W_CAUSE 06546 pri_progress_with_cause(p->pri->pri, p->call, PVT_TO_CHANNEL(p), 1, chan->hangupcause); 06547 #else 06548 pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1); 06549 #endif 06550 pri_rel(p->pri); 06551 } else { 06552 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->pri->span); 06553 } 06554 } 06555 } 06556 break; 06557 case AST_CONTROL_RINGING: 06558 if (p->call_level < SIG_PRI_CALL_LEVEL_ALERTING && !p->outgoing) { 06559 p->call_level = SIG_PRI_CALL_LEVEL_ALERTING; 06560 if (p->pri && p->pri->pri) { 06561 if (!pri_grab(p, p->pri)) { 06562 pri_acknowledge(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 06563 p->no_b_channel || p->digital ? 0 : 1); 06564 pri_rel(p->pri); 06565 } else { 06566 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->pri->span); 06567 } 06568 } 06569 } 06570 res = sig_pri_play_tone(p, SIG_PRI_TONE_RINGTONE); 06571 if (chan->_state != AST_STATE_UP) { 06572 if (chan->_state != AST_STATE_RING) 06573 ast_setstate(chan, AST_STATE_RINGING); 06574 } 06575 break; 06576 case AST_CONTROL_PROCEEDING: 06577 ast_debug(1,"Received AST_CONTROL_PROCEEDING on %s\n",chan->name); 06578 if (p->call_level < SIG_PRI_CALL_LEVEL_PROCEEDING && !p->outgoing) { 06579 p->call_level = SIG_PRI_CALL_LEVEL_PROCEEDING; 06580 if (p->pri && p->pri->pri) { 06581 if (!pri_grab(p, p->pri)) { 06582 pri_proceeding(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 06583 p->no_b_channel || p->digital ? 0 : 1); 06584 if (!p->no_b_channel && !p->digital) { 06585 sig_pri_set_dialing(p, 0); 06586 } 06587 pri_rel(p->pri); 06588 } else { 06589 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->pri->span); 06590 } 06591 } 06592 } 06593 /* don't continue in ast_indicate */ 06594 res = 0; 06595 break; 06596 case AST_CONTROL_PROGRESS: 06597 ast_debug(1,"Received AST_CONTROL_PROGRESS on %s\n",chan->name); 06598 sig_pri_set_digital(p, 0); /* Digital-only calls isn't allowing any inband progress messages */ 06599 if (!p->progress && p->call_level < SIG_PRI_CALL_LEVEL_ALERTING && !p->outgoing 06600 && !p->no_b_channel) { 06601 p->progress = 1;/* No need to send plain PROGRESS again. */ 06602 if (p->pri && p->pri->pri) { 06603 if (!pri_grab(p, p->pri)) { 06604 #ifdef HAVE_PRI_PROG_W_CAUSE 06605 pri_progress_with_cause(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1, -1); /* no cause at all */ 06606 #else 06607 pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1); 06608 #endif 06609 pri_rel(p->pri); 06610 } else { 06611 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->pri->span); 06612 } 06613 } 06614 } 06615 /* don't continue in ast_indicate */ 06616 res = 0; 06617 break; 06618 case AST_CONTROL_CONGESTION: 06619 if (p->priindication_oob || p->no_b_channel) { 06620 /* There are many cause codes that generate an AST_CONTROL_CONGESTION. */ 06621 switch (chan->hangupcause) { 06622 case AST_CAUSE_USER_BUSY: 06623 case AST_CAUSE_NORMAL_CLEARING: 06624 case 0:/* Cause has not been set. */ 06625 /* Supply a more appropriate cause. */ 06626 chan->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 06627 break; 06628 default: 06629 break; 06630 } 06631 chan->_softhangup |= AST_SOFTHANGUP_DEV; 06632 res = 0; 06633 break; 06634 } 06635 res = sig_pri_play_tone(p, SIG_PRI_TONE_CONGESTION); 06636 if (p->call_level < SIG_PRI_CALL_LEVEL_ALERTING && !p->outgoing) { 06637 /* There are many cause codes that generate an AST_CONTROL_CONGESTION. */ 06638 switch (chan->hangupcause) { 06639 case AST_CAUSE_USER_BUSY: 06640 case AST_CAUSE_NORMAL_CLEARING: 06641 case 0:/* Cause has not been set. */ 06642 /* Supply a more appropriate cause. */ 06643 chan->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 06644 break; 06645 default: 06646 break; 06647 } 06648 p->progress = 1;/* No need to send plain PROGRESS after this. */ 06649 if (p->pri && p->pri->pri) { 06650 if (!pri_grab(p, p->pri)) { 06651 #ifdef HAVE_PRI_PROG_W_CAUSE 06652 pri_progress_with_cause(p->pri->pri, p->call, PVT_TO_CHANNEL(p), 1, chan->hangupcause); 06653 #else 06654 pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1); 06655 #endif 06656 pri_rel(p->pri); 06657 } else { 06658 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->pri->span); 06659 } 06660 } 06661 } 06662 break; 06663 case AST_CONTROL_HOLD: 06664 if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) { 06665 if (!pri_grab(p, p->pri)) { 06666 res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_HOLD); 06667 pri_rel(p->pri); 06668 } else { 06669 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->pri->span); 06670 } 06671 } else 06672 ast_moh_start(chan, data, p->mohinterpret); 06673 break; 06674 case AST_CONTROL_UNHOLD: 06675 if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) { 06676 if (!pri_grab(p, p->pri)) { 06677 res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_RETRIEVAL); 06678 pri_rel(p->pri); 06679 } 06680 } else 06681 ast_moh_stop(chan); 06682 break; 06683 case AST_CONTROL_SRCUPDATE: 06684 res = 0; 06685 break; 06686 case -1: 06687 res = sig_pri_play_tone(p, -1); 06688 break; 06689 case AST_CONTROL_CONNECTED_LINE: 06690 ast_debug(1, "Received AST_CONTROL_CONNECTED_LINE on %s\n", chan->name); 06691 if (p->pri && !pri_grab(p, p->pri)) { 06692 struct pri_party_connected_line connected; 06693 06694 memset(&connected, 0, sizeof(connected)); 06695 sig_pri_party_id_from_ast(&connected.id, &chan->connected.id); 06696 06697 pri_connected_line_update(p->pri->pri, p->call, &connected); 06698 pri_rel(p->pri); 06699 } 06700 break; 06701 case AST_CONTROL_REDIRECTING: 06702 ast_debug(1, "Received AST_CONTROL_REDIRECTING on %s\n", chan->name); 06703 if (p->pri && !pri_grab(p, p->pri)) { 06704 sig_pri_redirecting_update(p, chan); 06705 pri_rel(p->pri); 06706 } 06707 break; 06708 case AST_CONTROL_AOC: 06709 #if defined(HAVE_PRI_AOC_EVENTS) 06710 { 06711 struct ast_aoc_decoded *decoded 06712 = ast_aoc_decode((struct ast_aoc_encoded *) data, datalen, chan); 06713 ast_debug(1, "Received AST_CONTROL_AOC on %s\n", chan->name); 06714 if (decoded && p->pri && !pri_grab(p, p->pri)) { 06715 switch (ast_aoc_get_msg_type(decoded)) { 06716 case AST_AOC_S: 06717 if (p->pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_S) { 06718 sig_pri_aoc_s_from_ast(p, decoded); 06719 } 06720 break; 06721 case AST_AOC_D: 06722 if (p->pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_D) { 06723 sig_pri_aoc_d_from_ast(p, decoded); 06724 } 06725 break; 06726 case AST_AOC_E: 06727 if (p->pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_E) { 06728 sig_pri_aoc_e_from_ast(p, decoded); 06729 } 06730 /* if hangup was delayed for this AOC-E msg, waiting_for_aoc 06731 * will be set. A hangup is already occuring via a timeout during 06732 * this delay. Instead of waiting for that timeout to occur, go ahead 06733 * and initiate the softhangup since the delay is no longer necessary */ 06734 if (p->waiting_for_aoce) { 06735 p->waiting_for_aoce = 0; 06736 ast_log(LOG_DEBUG, 06737 "Received final AOC-E msg, continue with hangup on %s\n", 06738 chan->name); 06739 ast_softhangup_nolock(chan, AST_SOFTHANGUP_DEV); 06740 } 06741 break; 06742 case AST_AOC_REQUEST: 06743 /* We do not pass through AOC requests, So unless this 06744 * is an AOC termination request it will be ignored */ 06745 if (ast_aoc_get_termination_request(decoded)) { 06746 pri_hangup(p->pri->pri, p->call, -1); 06747 } 06748 break; 06749 default: 06750 break; 06751 } 06752 pri_rel(p->pri); 06753 } 06754 ast_aoc_destroy_decoded(decoded); 06755 } 06756 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 06757 break; 06758 } 06759 06760 return res; 06761 }
void sig_pri_init_pri | ( | struct sig_pri_span * | pri | ) |
Definition at line 5899 of file sig_pri.c.
References ast_mutex_init, AST_PTHREADT_NULL, and SIG_PRI_NUM_DCHANS.
Referenced by load_module().
05900 { 05901 int i; 05902 05903 memset(pri, 0, sizeof(*pri)); 05904 05905 ast_mutex_init(&pri->lock); 05906 05907 pri->master = AST_PTHREADT_NULL; 05908 for (i = 0; i < SIG_PRI_NUM_DCHANS; i++) 05909 pri->fds[i] = -1; 05910 }
static int sig_pri_is_cis_call | ( | int | channel | ) | [static] |
Definition at line 3501 of file sig_pri.c.
References PRI_CIS_CALL.
03502 { 03503 return channel != -1 && (channel & PRI_CIS_CALL); 03504 }
int sig_pri_load | ( | const char * | cc_type_name | ) |
Load the sig_pri submodule.
cc_type_name | CC type name to use when looking up agent/monitor. |
0 | on success. | |
-1 | on error. |
Definition at line 8084 of file sig_pri.c.
References ao2_container_alloc.
Referenced by load_module().
08085 { 08086 #if defined(HAVE_PRI_CCSS) 08087 sig_pri_cc_type_name = cc_type_name; 08088 sig_pri_cc_monitors = ao2_container_alloc(37, sig_pri_cc_monitor_instance_hash_fn, 08089 sig_pri_cc_monitor_instance_cmp_fn); 08090 if (!sig_pri_cc_monitors) { 08091 return -1; 08092 } 08093 #endif /* defined(HAVE_PRI_CCSS) */ 08094 return 0; 08095 }
static void sig_pri_lock_owner | ( | struct sig_pri_span * | pri, | |
int | chanpos | |||
) | [static] |
Definition at line 1016 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_handle_hold(), and sig_pri_handle_subcmds().
01017 { 01018 for (;;) { 01019 if (!pri->pvts[chanpos]->owner) { 01020 /* There is no owner lock to get. */ 01021 break; 01022 } 01023 if (!ast_channel_trylock(pri->pvts[chanpos]->owner)) { 01024 /* We got the lock */ 01025 break; 01026 } 01027 /* We must unlock the PRI to avoid the possibility of a deadlock */ 01028 ast_mutex_unlock(&pri->lock); 01029 PRI_DEADLOCK_AVOIDANCE(pri->pvts[chanpos]); 01030 ast_mutex_lock(&pri->lock); 01031 } 01032 }
static void sig_pri_lock_private | ( | struct sig_pri_chan * | p | ) | [static] |
Definition at line 277 of file sig_pri.c.
References sig_pri_chan::calls, sig_pri_chan::chan_pvt, and sig_pri_callback::lock_private.
Referenced by pri_fixup_principle(), pri_send_callrerouting_facility_exec(), pri_send_keypad_facility_exec(), pri_ss_thread(), sig_pri_attempt_transfer(), sig_pri_handle_hold(), sig_pri_handle_retrieve(), and sig_pri_handle_subcmds().
00278 { 00279 if (p->calls->lock_private) 00280 p->calls->lock_private(p->chan_pvt); 00281 }
static int sig_pri_msn_match | ( | const char * | msn_patterns, | |
const char * | exten | |||
) | [static] |
Definition at line 1816 of file sig_pri.c.
References ast_extension_match(), ast_strdupa, ast_strip(), and ast_strlen_zero().
01817 { 01818 char *pattern; 01819 char *msn_list; 01820 char *list_tail; 01821 01822 msn_list = ast_strdupa(msn_patterns); 01823 01824 list_tail = NULL; 01825 pattern = strtok_r(msn_list, ",", &list_tail); 01826 while (pattern) { 01827 pattern = ast_strip(pattern); 01828 if (!ast_strlen_zero(pattern) && ast_extension_match(pattern, exten)) { 01829 /* Extension matched the pattern. */ 01830 return 1; 01831 } 01832 pattern = strtok_r(NULL, ",", &list_tail); 01833 } 01834 /* Did not match any pattern in the list. */ 01835 return 0; 01836 }
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 864 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().
00865 { 00866 struct ast_channel *c; 00867 00868 if (p->calls->new_ast_channel) { 00869 c = p->calls->new_ast_channel(p->chan_pvt, state, ulaw, exten, requestor); 00870 } else { 00871 return NULL; 00872 } 00873 if (!c) { 00874 return NULL; 00875 } 00876 00877 if (!p->owner) 00878 p->owner = c; 00879 p->isidlecall = 0; 00880 p->alreadyhungup = 0; 00881 c->transfercapability = transfercapability; 00882 pbx_builtin_setvar_helper(c, "TRANSFERCAPABILITY", 00883 ast_transfercapability2str(transfercapability)); 00884 if (transfercapability & AST_TRANS_CAP_DIGITAL) { 00885 sig_pri_set_digital(p, 1); 00886 } 00887 if (p->pri) { 00888 ast_mutex_lock(&p->pri->lock); 00889 sig_pri_span_devstate_changed(p->pri); 00890 ast_mutex_unlock(&p->pri->lock); 00891 } 00892 00893 return c; 00894 }
static void sig_pri_open_media | ( | struct sig_pri_chan * | p | ) | [static] |
Definition at line 905 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(), and sig_pri_answer().
00906 { 00907 if (p->no_b_channel) { 00908 return; 00909 } 00910 00911 if (p->calls->open_media) { 00912 p->calls->open_media(p->chan_pvt); 00913 } 00914 }
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 1762 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(), and sig_pri_redirecting_convert().
01763 { 01764 if (pri_id->name.valid) { 01765 sig_pri_party_name_convert(&ast_id->name, &pri_id->name); 01766 } 01767 if (pri_id->number.valid) { 01768 sig_pri_party_number_convert(&ast_id->number, &pri_id->number, pri); 01769 } 01770 #if defined(HAVE_PRI_SUBADDR) 01771 if (pri_id->subaddress.valid) { 01772 sig_pri_set_subaddress(&ast_id->subaddress, &pri_id->subaddress); 01773 } 01774 #endif /* defined(HAVE_PRI_SUBADDR) */ 01775 }
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 790 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().
00791 { 00792 sig_pri_party_name_from_ast(&pri_id->name, &ast_id->name); 00793 sig_pri_party_number_from_ast(&pri_id->number, &ast_id->number); 00794 #if defined(HAVE_PRI_SUBADDR) 00795 sig_pri_party_subaddress_from_ast(&pri_id->subaddress, &ast_id->subaddress); 00796 #endif /* defined(HAVE_PRI_SUBADDR) */ 00797 }
static void sig_pri_party_name_convert | ( | struct ast_party_name * | ast_name, | |
const struct pri_party_name * | pri_name | |||
) | [static] |
Definition at line 1715 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().
01716 { 01717 ast_name->str = ast_strdup(pri_name->str); 01718 ast_name->char_set = pri_to_ast_char_set(pri_name->char_set); 01719 ast_name->presentation = pri_to_ast_presentation(pri_name->presentation); 01720 ast_name->valid = 1; 01721 }
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 740 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().
00741 { 00742 if (!ast_name->valid) { 00743 return; 00744 } 00745 pri_name->valid = 1; 00746 pri_name->presentation = ast_to_pri_presentation(ast_name->presentation); 00747 pri_name->char_set = ast_to_pri_char_set(ast_name->char_set); 00748 if (!ast_strlen_zero(ast_name->str)) { 00749 ast_copy_string(pri_name->str, ast_name->str, sizeof(pri_name->str)); 00750 } 00751 }
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 1737 of file sig_pri.c.
References apply_plan_to_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().
01738 { 01739 char number[AST_MAX_EXTENSION]; 01740 01741 apply_plan_to_number(number, sizeof(number), pri, pri_number->str, pri_number->plan); 01742 ast_number->str = ast_strdup(number); 01743 ast_number->plan = pri_number->plan; 01744 ast_number->presentation = pri_to_ast_presentation(pri_number->presentation); 01745 ast_number->valid = 1; 01746 }
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 765 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().
00766 { 00767 if (!ast_number->valid) { 00768 return; 00769 } 00770 pri_number->valid = 1; 00771 pri_number->presentation = ast_to_pri_presentation(ast_number->presentation); 00772 pri_number->plan = ast_number->plan; 00773 if (!ast_strlen_zero(ast_number->str)) { 00774 ast_copy_string(pri_number->str, ast_number->str, sizeof(pri_number->str)); 00775 } 00776 }
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 700 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().
00701 { 00702 if (ast_subaddress->valid && !ast_strlen_zero(ast_subaddress->str)) { 00703 pri_subaddress->type = ast_subaddress->type; 00704 if (!ast_subaddress->type) { 00705 /* 0 = NSAP */ 00706 ast_copy_string((char *) pri_subaddress->data, ast_subaddress->str, 00707 sizeof(pri_subaddress->data)); 00708 pri_subaddress->length = strlen((char *) pri_subaddress->data); 00709 pri_subaddress->odd_even_indicator = 0; 00710 pri_subaddress->valid = 1; 00711 } else { 00712 /* 2 = User Specified */ 00713 /* 00714 * Copy HexString to packed HexData, 00715 * if odd length then right pad trailing byte with 0 00716 */ 00717 int length = ast_pri_pack_hex_string(pri_subaddress->data, 00718 ast_subaddress->str, sizeof(pri_subaddress->data)); 00719 00720 pri_subaddress->length = length; 00721 pri_subaddress->odd_even_indicator = (length & 1); 00722 pri_subaddress->valid = 1; 00723 } 00724 } 00725 }
static int sig_pri_play_tone | ( | struct sig_pri_chan * | p, | |
enum sig_pri_tone | tone | |||
) | [static] |
Definition at line 856 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().
00857 { 00858 if (p->calls->play_tone) 00859 return p->calls->play_tone(p->chan_pvt, tone); 00860 else 00861 return -1; 00862 }
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 1792 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().
01796 { 01797 ast_party_redirecting_set_init(ast_redirecting, ast_guide); 01798 01799 sig_pri_party_id_convert(&ast_redirecting->from, &pri_redirecting->from, pri); 01800 sig_pri_party_id_convert(&ast_redirecting->to, &pri_redirecting->to, pri); 01801 ast_redirecting->count = pri_redirecting->count; 01802 ast_redirecting->reason = pri_to_ast_reason(pri_redirecting->reason); 01803 }
static void sig_pri_redirecting_update | ( | struct sig_pri_chan * | pvt, | |
struct ast_channel * | ast | |||
) | [static] |
Definition at line 811 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().
00812 { 00813 struct pri_party_redirecting pri_redirecting; 00814 00815 /*! \todo XXX Original called data can be put in a channel data store that is inherited. */ 00816 00817 memset(&pri_redirecting, 0, sizeof(pri_redirecting)); 00818 sig_pri_party_id_from_ast(&pri_redirecting.from, &ast->redirecting.from); 00819 sig_pri_party_id_from_ast(&pri_redirecting.to, &ast->redirecting.to); 00820 pri_redirecting.count = ast->redirecting.count; 00821 pri_redirecting.reason = ast_to_pri_reason(ast->redirecting.reason); 00822 00823 pri_redirecting_update(pvt->pri->pri, pvt->call, &pri_redirecting); 00824 }
struct ast_channel* sig_pri_request | ( | struct sig_pri_chan * | p, | |
enum sig_pri_law | law, | |||
const struct ast_channel * | requestor, | |||
int | transfercapability | |||
) |
Definition at line 916 of file sig_pri.c.
References ast_log(), AST_STATE_RESERVED, sig_pri_chan::channel, sig_pri_chan::exten, LOG_DEBUG, sig_pri_chan::outgoing, and sig_pri_new_ast_channel().
Referenced by dahdi_request(), and pri_dchannel().
00917 { 00918 struct ast_channel *ast; 00919 00920 ast_log(LOG_DEBUG, "%s %d\n", __FUNCTION__, p->channel); 00921 00922 p->outgoing = 1; 00923 ast = sig_pri_new_ast_channel(p, AST_STATE_RESERVED, law, transfercapability, p->exten, requestor); 00924 if (!ast) { 00925 p->outgoing = 0; 00926 } 00927 return ast; 00928 }
static void sig_pri_set_alarm | ( | struct sig_pri_chan * | p, | |
int | in_alarm | |||
) | [static] |
Definition at line 147 of file sig_pri.c.
References sig_pri_chan::calls, sig_pri_chan::chan_pvt, sig_pri_chan::inalarm, and sig_pri_callback::set_alarm.
Referenced by sig_pri_chan_alarm_notify().
00148 { 00149 p->inalarm = in_alarm; 00150 if (p->calls->set_alarm) { 00151 p->calls->set_alarm(p->chan_pvt, in_alarm); 00152 } 00153 }
static void sig_pri_set_caller_id | ( | struct sig_pri_chan * | p | ) | [static] |
Definition at line 203 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().
00204 { 00205 struct ast_party_caller caller; 00206 00207 if (p->calls->set_callerid) { 00208 ast_party_caller_init(&caller); 00209 00210 caller.id.name.str = p->cid_name; 00211 caller.id.name.presentation = p->callingpres; 00212 caller.id.name.valid = 1; 00213 00214 caller.id.number.str = p->cid_num; 00215 caller.id.number.plan = p->cid_ton; 00216 caller.id.number.presentation = p->callingpres; 00217 caller.id.number.valid = 1; 00218 00219 if (!ast_strlen_zero(p->cid_subaddr)) { 00220 caller.id.subaddress.valid = 1; 00221 //caller.id.subaddress.type = 0;/* nsap */ 00222 //caller.id.subaddress.odd_even_indicator = 0; 00223 caller.id.subaddress.str = p->cid_subaddr; 00224 } 00225 caller.id.tag = p->user_tag; 00226 00227 caller.ani.number.str = p->cid_ani; 00228 //caller.ani.number.plan = p->xxx; 00229 //caller.ani.number.presentation = p->xxx; 00230 caller.ani.number.valid = 1; 00231 00232 caller.ani2 = p->cid_ani2; 00233 p->calls->set_callerid(p->chan_pvt, &caller); 00234 } 00235 }
static void sig_pri_set_dialing | ( | struct sig_pri_chan * | p, | |
int | is_dialing | |||
) | [static] |
Definition at line 132 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_hangup(), and sig_pri_indicate().
00133 { 00134 if (p->calls->set_dialing) { 00135 p->calls->set_dialing(p->chan_pvt, is_dialing); 00136 } 00137 }
static void sig_pri_set_digital | ( | struct sig_pri_chan * | p, | |
int | is_digital | |||
) | [static] |
Definition at line 139 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().
00140 { 00141 p->digital = is_digital; 00142 if (p->calls->set_digital) { 00143 p->calls->set_digital(p->chan_pvt, is_digital); 00144 } 00145 }
static void sig_pri_set_dnid | ( | struct sig_pri_chan * | p, | |
const char * | dnid | |||
) | [static] |
Definition at line 247 of file sig_pri.c.
References sig_pri_chan::calls, sig_pri_chan::chan_pvt, and sig_pri_callback::set_dnid.
00248 { 00249 if (p->calls->set_dnid) { 00250 p->calls->set_dnid(p->chan_pvt, dnid); 00251 } 00252 }
static int sig_pri_set_echocanceller | ( | struct sig_pri_chan * | p, | |
int | enable | |||
) | [static] |
Definition at line 842 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().
00843 { 00844 if (p->calls->set_echocanceller) 00845 return p->calls->set_echocanceller(p->chan_pvt, enable); 00846 else 00847 return -1; 00848 }
static void sig_pri_set_rdnis | ( | struct sig_pri_chan * | p, | |
const char * | rdnis | |||
) | [static] |
Definition at line 264 of file sig_pri.c.
References sig_pri_chan::calls, sig_pri_chan::chan_pvt, and sig_pri_callback::set_rdnis.
00265 { 00266 if (p->calls->set_rdnis) { 00267 p->calls->set_rdnis(p->chan_pvt, rdnis); 00268 } 00269 }
static void sig_pri_set_subaddress | ( | struct ast_party_subaddress * | ast_subaddress, | |
const struct pri_party_subaddress * | pri_subaddress | |||
) | [static] |
Definition at line 578 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().
00579 { 00580 char *cnum, *ptr; 00581 int x, len; 00582 00583 if (ast_subaddress->str) { 00584 ast_free(ast_subaddress->str); 00585 } 00586 if (pri_subaddress->length <= 0) { 00587 ast_party_subaddress_init(ast_subaddress); 00588 return; 00589 } 00590 00591 if (!pri_subaddress->type) { 00592 /* NSAP */ 00593 ast_subaddress->str = ast_strdup((char *) pri_subaddress->data); 00594 } else { 00595 /* User Specified */ 00596 if (!(cnum = ast_malloc(2 * pri_subaddress->length + 1))) { 00597 ast_party_subaddress_init(ast_subaddress); 00598 return; 00599 } 00600 00601 ptr = cnum; 00602 len = pri_subaddress->length - 1; /* -1 account for zero based indexing */ 00603 for (x = 0; x < len; ++x) { 00604 ptr += sprintf(ptr, "%02x", pri_subaddress->data[x]); 00605 } 00606 00607 if (pri_subaddress->odd_even_indicator) { 00608 /* ODD */ 00609 sprintf(ptr, "%01x", (pri_subaddress->data[len]) >> 4); 00610 } else { 00611 /* EVEN */ 00612 sprintf(ptr, "%02x", pri_subaddress->data[len]); 00613 } 00614 ast_subaddress->str = cnum; 00615 } 00616 ast_subaddress->type = pri_subaddress->type; 00617 ast_subaddress->odd_even_indicator = pri_subaddress->odd_even_indicator; 00618 ast_subaddress->valid = 1; 00619 }
static void sig_pri_sort_pri_chans | ( | struct sig_pri_span * | pri | ) | [static] |
Definition at line 7113 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().
07114 { 07115 qsort(&pri->pvts, pri->numchans, sizeof(pri->pvts[0]), sig_pri_cmp_pri_chans); 07116 }
static void sig_pri_span_devstate_changed | ( | struct sig_pri_span * | pri | ) | [static] |
Definition at line 187 of file sig_pri.c.
References sig_pri_span::calls, and sig_pri_callback::update_span_devstate.
Referenced by sig_pri_handle_hold(), sig_pri_handle_retrieve(), sig_pri_hangup(), and sig_pri_new_ast_channel().
00188 { 00189 if (pri->calls->update_span_devstate) { 00190 pri->calls->update_span_devstate(pri); 00191 } 00192 }
int sig_pri_start_pri | ( | struct sig_pri_span * | pri | ) |
Definition at line 7118 of file sig_pri.c.
References ARRAY_LEN, AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_MWI, ast_event_subscribe(), ast_event_unsubscribe(), ast_log(), ast_mutex_init, ast_str_alloca, ast_str_buffer(), ast_str_set(), ast_strip(), ast_strlen_zero(), sig_pri_span::dchans, sig_pri_span::enable_service_message_support, sig_pri_span::fds, HAVE_PRI_SERVICE_MESSAGES, sig_pri_span::lock, LOG_ERROR, sig_pri_span::nodetype, sig_pri_span::sig, SIG_BRI, SIG_BRI_PTMP, SIG_PRI_NUM_DCHANS, sig_pri_sort_pri_chans(), sig_pri_span::span, strsep(), and sig_pri_span::switchtype.
Referenced by setup_dahdi_int().
07119 { 07120 int x; 07121 int i; 07122 #if defined(HAVE_PRI_MWI) 07123 char *saveptr; 07124 char *mbox_number; 07125 char *mbox_context; 07126 struct ast_str *mwi_description = ast_str_alloca(64); 07127 #endif /* defined(HAVE_PRI_MWI) */ 07128 07129 #if defined(HAVE_PRI_MWI) 07130 /* Prepare the mbox[] for use. */ 07131 for (i = 0; i < ARRAY_LEN(pri->mbox); ++i) { 07132 if (pri->mbox[i].sub) { 07133 pri->mbox[i].sub = ast_event_unsubscribe(pri->mbox[i].sub); 07134 } 07135 } 07136 #endif /* defined(HAVE_PRI_MWI) */ 07137 07138 ast_mutex_init(&pri->lock); 07139 sig_pri_sort_pri_chans(pri); 07140 07141 #if defined(HAVE_PRI_MWI) 07142 /* 07143 * Split the mwi_mailboxes configuration string into the mbox[]: 07144 * mailbox_number[@context]{,mailbox_number[@context]} 07145 */ 07146 i = 0; 07147 saveptr = pri->mwi_mailboxes; 07148 while (i < ARRAY_LEN(pri->mbox)) { 07149 mbox_number = strsep(&saveptr, ","); 07150 if (!mbox_number) { 07151 break; 07152 } 07153 /* Split the mailbox_number and context */ 07154 mbox_context = strchr(mbox_number, '@'); 07155 if (mbox_context) { 07156 *mbox_context++ = '\0'; 07157 mbox_context = ast_strip(mbox_context); 07158 } 07159 mbox_number = ast_strip(mbox_number); 07160 if (ast_strlen_zero(mbox_number)) { 07161 /* There is no mailbox number. Skip it. */ 07162 continue; 07163 } 07164 if (ast_strlen_zero(mbox_context)) { 07165 /* There was no context so use the default. */ 07166 mbox_context = "default"; 07167 } 07168 07169 /* Fill the mbox[] element. */ 07170 ast_str_set(&mwi_description, -1, "%s span %d[%d] MWI mailbox %s@%s", 07171 sig_pri_cc_type_name, pri->span, i, mbox_number, mbox_context); 07172 pri->mbox[i].sub = ast_event_subscribe(AST_EVENT_MWI, sig_pri_mwi_event_cb, 07173 ast_str_buffer(mwi_description), pri, 07174 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mbox_number, 07175 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, mbox_context, 07176 AST_EVENT_IE_END); 07177 if (!pri->mbox[i].sub) { 07178 ast_log(LOG_ERROR, "%s span %d could not subscribe to MWI events for %s@%s.", 07179 sig_pri_cc_type_name, pri->span, mbox_number, mbox_context); 07180 continue; 07181 } 07182 pri->mbox[i].number = mbox_number; 07183 pri->mbox[i].context = mbox_context; 07184 ++i; 07185 } 07186 #endif /* defined(HAVE_PRI_MWI) */ 07187 07188 for (i = 0; i < SIG_PRI_NUM_DCHANS; i++) { 07189 if (pri->fds[i] == -1) { 07190 break; 07191 } 07192 07193 switch (pri->sig) { 07194 case SIG_BRI: 07195 pri->dchans[i] = pri_new_bri(pri->fds[i], 1, pri->nodetype, pri->switchtype); 07196 break; 07197 case SIG_BRI_PTMP: 07198 pri->dchans[i] = pri_new_bri(pri->fds[i], 0, pri->nodetype, pri->switchtype); 07199 break; 07200 default: 07201 pri->dchans[i] = pri_new(pri->fds[i], pri->nodetype, pri->switchtype); 07202 #if defined(HAVE_PRI_SERVICE_MESSAGES) 07203 if (pri->enable_service_message_support) { 07204 pri_set_service_message_support(pri->dchans[i], 1); 07205 } 07206 #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */ 07207 break; 07208 } 07209 07210 pri_set_overlapdial(pri->dchans[i], (pri->overlapdial & DAHDI_OVERLAPDIAL_OUTGOING) ? 1 : 0); 07211 #ifdef HAVE_PRI_PROG_W_CAUSE 07212 pri_set_chan_mapping_logical(pri->dchans[i], pri->qsigchannelmapping == DAHDI_CHAN_MAPPING_LOGICAL); 07213 #endif 07214 #ifdef HAVE_PRI_INBANDDISCONNECT 07215 pri_set_inbanddisconnect(pri->dchans[i], pri->inbanddisconnect); 07216 #endif 07217 /* Enslave to master if appropriate */ 07218 if (i) 07219 pri_enslave(pri->dchans[0], pri->dchans[i]); 07220 if (!pri->dchans[i]) { 07221 if (pri->fds[i] > 0) 07222 close(pri->fds[i]); 07223 pri->fds[i] = -1; 07224 ast_log(LOG_ERROR, "Unable to create PRI structure\n"); 07225 return -1; 07226 } 07227 pri_set_debug(pri->dchans[i], SIG_PRI_DEBUG_DEFAULT); 07228 pri_set_nsf(pri->dchans[i], pri->nsf); 07229 #ifdef PRI_GETSET_TIMERS 07230 for (x = 0; x < PRI_MAX_TIMERS; x++) { 07231 if (pri->pritimers[x] != 0) 07232 pri_set_timer(pri->dchans[i], x, pri->pritimers[x]); 07233 } 07234 #endif 07235 } 07236 07237 /* Assume primary is the one we use */ 07238 pri->pri = pri->dchans[0]; 07239 07240 #if defined(HAVE_PRI_CALL_HOLD) 07241 pri_hold_enable(pri->pri, 1); 07242 #endif /* defined(HAVE_PRI_CALL_HOLD) */ 07243 #if defined(HAVE_PRI_CALL_REROUTING) 07244 pri_reroute_enable(pri->pri, 1); 07245 #endif /* defined(HAVE_PRI_CALL_REROUTING) */ 07246 #if defined(HAVE_PRI_HANGUP_FIX) 07247 pri_hangup_fix_enable(pri->pri, 1); 07248 #endif /* defined(HAVE_PRI_HANGUP_FIX) */ 07249 #if defined(HAVE_PRI_CCSS) 07250 pri_cc_enable(pri->pri, 1); 07251 pri_cc_recall_mode(pri->pri, pri->cc_ptmp_recall_mode); 07252 pri_cc_retain_signaling_req(pri->pri, pri->cc_qsig_signaling_link_req); 07253 pri_cc_retain_signaling_rsp(pri->pri, pri->cc_qsig_signaling_link_rsp); 07254 #endif /* defined(HAVE_PRI_CCSS) */ 07255 #if defined(HAVE_PRI_TRANSFER) 07256 pri_transfer_enable(pri->pri, 1); 07257 #endif /* defined(HAVE_PRI_TRANSFER) */ 07258 #if defined(HAVE_PRI_AOC_EVENTS) 07259 pri_aoc_events_enable(pri->pri, 1); 07260 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 07261 #if defined(HAVE_PRI_CALL_WAITING) 07262 pri_connect_ack_enable(pri->pri, 1); 07263 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 07264 #if defined(HAVE_PRI_MCID) 07265 pri_mcid_enable(pri->pri, 1); 07266 #endif /* defined(HAVE_PRI_MCID) */ 07267 07268 pri->resetpos = -1; 07269 if (ast_pthread_create_background(&pri->master, NULL, pri_dchannel, pri)) { 07270 for (i = 0; i < SIG_PRI_NUM_DCHANS; i++) { 07271 if (!pri->dchans[i]) 07272 break; 07273 if (pri->fds[i] > 0) 07274 close(pri->fds[i]); 07275 pri->fds[i] = -1; 07276 } 07277 ast_log(LOG_ERROR, "Unable to spawn D-channel: %s\n", strerror(errno)); 07278 return -1; 07279 } 07280 07281 #if defined(HAVE_PRI_MWI) 07282 /* 07283 * Send the initial MWI indications from the event cache for this span. 07284 * 07285 * If we were loaded after app_voicemail the event would already be in 07286 * the cache. If we were loaded before app_voicemail the event would not 07287 * be in the cache yet and app_voicemail will send the event when it 07288 * gets loaded. 07289 */ 07290 sig_pri_mwi_cache_update(pri); 07291 #endif /* defined(HAVE_PRI_MWI) */ 07292 07293 return 0; 07294 }
void sig_pri_stop_pri | ( | struct sig_pri_span * | pri | ) |
Stop PRI span.
pri | Asterisk D channel control structure. |
Definition at line 7053 of file sig_pri.c.
References ARRAY_LEN, and ast_event_unsubscribe().
Referenced by __unload_module().
07054 { 07055 #if defined(HAVE_PRI_MWI) 07056 int idx; 07057 #endif /* defined(HAVE_PRI_MWI) */ 07058 07059 #if defined(HAVE_PRI_MWI) 07060 for (idx = 0; idx < ARRAY_LEN(pri->mbox); ++idx) { 07061 if (pri->mbox[idx].sub) { 07062 pri->mbox[idx].sub = ast_event_unsubscribe(pri->mbox[idx].sub); 07063 } 07064 } 07065 #endif /* defined(HAVE_PRI_MWI) */ 07066 }
void sig_pri_unload | ( | void | ) |
Unload the sig_pri submodule.
Definition at line 8103 of file sig_pri.c.
References ao2_ref.
Referenced by __unload_module().
08104 { 08105 #if defined(HAVE_PRI_CCSS) 08106 if (sig_pri_cc_monitors) { 08107 ao2_ref(sig_pri_cc_monitors, -1); 08108 sig_pri_cc_monitors = NULL; 08109 } 08110 #endif /* defined(HAVE_PRI_CCSS) */ 08111 }
static void sig_pri_unlock_private | ( | struct sig_pri_chan * | p | ) | [static] |
Definition at line 271 of file sig_pri.c.
References sig_pri_chan::calls, sig_pri_chan::chan_pvt, and sig_pri_callback::unlock_private.
Referenced by pri_fixup_principle(), pri_send_callrerouting_facility_exec(), pri_send_keypad_facility_exec(), pri_ss_thread(), sig_pri_attempt_transfer(), sig_pri_handle_hold(), sig_pri_handle_retrieve(), and sig_pri_handle_subcmds().
00272 { 00273 if (p->calls->unlock_private) 00274 p->calls->unlock_private(p->chan_pvt); 00275 }
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] |