#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 6021 of file sig_pri.c.
06021 { 06022 OPT_ARG_KEYPAD = 0, 06023 OPT_ARG_AOC_REQUEST, 06024 06025 /* note: this entry _MUST_ be the last one in the enum */ 06026 OPT_ARG_ARRAY_SIZE, 06027 };
Definition at line 6016 of file sig_pri.c.
06016 { 06017 OPT_KEYPAD = (1 << 0), 06018 OPT_REVERSE_CHARGE = (1 << 1), /* Collect call */ 06019 OPT_AOC_REQUEST = (1 << 2), /* AOC Request */ 06020 };
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 7250 of file sig_pri.c.
References DCHAN_NOTINALARM.
Referenced by sig_pri_cli_show_span(), and sig_pri_cli_show_spans().
07251 { 07252 if (!s || len < 1) { 07253 return; 07254 } 07255 s[0] = '\0'; 07256 if (!(status & DCHAN_NOTINALARM)) 07257 strncat(s, "In Alarm, ", len - strlen(s) - 1); 07258 if (status & DCHAN_UP) 07259 strncat(s, "Up", len - strlen(s) - 1); 07260 else 07261 strncat(s, "Down", len - strlen(s) - 1); 07262 if (active) 07263 strncat(s, ", Active", len - strlen(s) - 1); 07264 else 07265 strncat(s, ", Standby", len - strlen(s) - 1); 07266 s[len - 1] = '\0'; 07267 }
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 953 of file sig_pri.c.
References ast_log(), sig_pri_span::dchans, LOG_WARNING, sig_pri_span::pri, and SIG_PRI_NUM_DCHANS.
00954 { 00955 int x; 00956 00957 for (x = 0; x < SIG_PRI_NUM_DCHANS; x++) { 00958 if ((pri->dchans[x] == pri->pri)) 00959 return x; 00960 } 00961 00962 ast_log(LOG_WARNING, "No active dchan found!\n"); 00963 return -1; 00964 }
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 4233 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.
04234 { 04235 struct sig_pri_span *pri = vpri; 04236 pri_event *e; 04237 struct pollfd fds[SIG_PRI_NUM_DCHANS]; 04238 int res; 04239 int chanpos = 0; 04240 int x; 04241 struct ast_channel *c; 04242 struct timeval tv, lowest, *next; 04243 int doidling=0; 04244 char *cc; 04245 time_t t; 04246 int i, which=-1; 04247 int numdchans; 04248 pthread_t threadid; 04249 char ani2str[6]; 04250 char plancallingnum[AST_MAX_EXTENSION]; 04251 char plancallingani[AST_MAX_EXTENSION]; 04252 char calledtonstr[10]; 04253 struct timeval lastidle = { 0, 0 }; 04254 pthread_t p; 04255 struct ast_channel *idle; 04256 char idlen[80]; 04257 int nextidle = -1; 04258 int haveidles; 04259 int activeidles; 04260 04261 gettimeofday(&lastidle, NULL); 04262 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); 04263 04264 if (!ast_strlen_zero(pri->idledial) && !ast_strlen_zero(pri->idleext)) { 04265 /* Need to do idle dialing, check to be sure though */ 04266 cc = strchr(pri->idleext, '@'); 04267 if (cc) { 04268 *cc = '\0'; 04269 cc++; 04270 ast_copy_string(pri->idlecontext, cc, sizeof(pri->idlecontext)); 04271 #if 0 04272 /* Extensions may not be loaded yet */ 04273 if (!ast_exists_extension(NULL, pri->idlecontext, pri->idleext, 1, NULL)) 04274 ast_log(LOG_WARNING, "Extension '%s @ %s' does not exist\n", pri->idleext, pri->idlecontext); 04275 else 04276 #endif 04277 doidling = 1; 04278 } else 04279 ast_log(LOG_WARNING, "Idle dial string '%s' lacks '@context'\n", pri->idleext); 04280 } 04281 for (;;) { 04282 for (i = 0; i < SIG_PRI_NUM_DCHANS; i++) { 04283 if (!pri->dchans[i]) 04284 break; 04285 fds[i].fd = pri->fds[i]; 04286 fds[i].events = POLLIN | POLLPRI; 04287 fds[i].revents = 0; 04288 } 04289 numdchans = i; 04290 time(&t); 04291 ast_mutex_lock(&pri->lock); 04292 if (pri->switchtype != PRI_SWITCH_GR303_TMC && (pri->sig != SIG_BRI_PTMP) && (pri->resetinterval > 0)) { 04293 if (pri->resetting && pri_is_up(pri)) { 04294 if (pri->resetpos < 0) 04295 pri_check_restart(pri); 04296 } else { 04297 if (!pri->resetting && (t - pri->lastreset) >= pri->resetinterval) { 04298 pri->resetting = 1; 04299 pri->resetpos = -1; 04300 } 04301 } 04302 } 04303 /* Look for any idle channels if appropriate */ 04304 if (doidling && pri_is_up(pri)) { 04305 nextidle = -1; 04306 haveidles = 0; 04307 activeidles = 0; 04308 for (x = pri->numchans; x >= 0; x--) { 04309 if (pri->pvts[x] 04310 && !pri->pvts[x]->owner 04311 && !pri->pvts[x]->call 04312 && !pri->pvts[x]->no_b_channel) { 04313 if (haveidles < pri->minunused) { 04314 haveidles++; 04315 } else if (!pri->pvts[x]->resetting) { 04316 nextidle = x; 04317 break; 04318 } 04319 } else if (pri->pvts[x] && pri->pvts[x]->owner && pri->pvts[x]->isidlecall) 04320 activeidles++; 04321 } 04322 if (nextidle > -1) { 04323 if (ast_tvdiff_ms(ast_tvnow(), lastidle) > 1000) { 04324 /* Don't create a new idle call more than once per second */ 04325 snprintf(idlen, sizeof(idlen), "%d/%s", pri->pvts[nextidle]->channel, pri->idledial); 04326 idle = sig_pri_request(pri->pvts[nextidle], AST_FORMAT_ULAW, NULL, 0); 04327 if (idle) { 04328 pri->pvts[nextidle]->isidlecall = 1; 04329 if (ast_pthread_create_background(&p, NULL, do_idle_thread, pri->pvts[nextidle])) { 04330 ast_log(LOG_WARNING, "Unable to start new thread for idle channel '%s'\n", idle->name); 04331 ast_hangup(idle); 04332 } 04333 } else 04334 ast_log(LOG_WARNING, "Unable to request channel 'DAHDI/%s' for idle call\n", idlen); 04335 gettimeofday(&lastidle, NULL); 04336 } 04337 } else if ((haveidles < pri->minunused) && 04338 (activeidles > pri->minidle)) { 04339 /* Mark something for hangup if there is something 04340 that can be hungup */ 04341 for (x = pri->numchans; x >= 0; x--) { 04342 /* find a candidate channel */ 04343 if (pri->pvts[x] && pri->pvts[x]->owner && pri->pvts[x]->isidlecall) { 04344 pri->pvts[x]->owner->_softhangup |= AST_SOFTHANGUP_DEV; 04345 haveidles++; 04346 /* Stop if we have enough idle channels or 04347 can't spare any more active idle ones */ 04348 if ((haveidles >= pri->minunused) || 04349 (activeidles <= pri->minidle)) 04350 break; 04351 } 04352 } 04353 } 04354 } 04355 /* Start with reasonable max */ 04356 if (doidling || pri->resetting) { 04357 /* 04358 * Make sure we stop at least once per second if we're 04359 * monitoring idle channels 04360 */ 04361 lowest = ast_tv(1, 0); 04362 } else { 04363 /* Don't poll for more than 60 seconds */ 04364 lowest = ast_tv(60, 0); 04365 } 04366 for (i = 0; i < SIG_PRI_NUM_DCHANS; i++) { 04367 if (!pri->dchans[i]) { 04368 /* We scanned all D channels on this span. */ 04369 break; 04370 } 04371 next = pri_schedule_next(pri->dchans[i]); 04372 if (next) { 04373 /* We need relative time here */ 04374 tv = ast_tvsub(*next, ast_tvnow()); 04375 if (tv.tv_sec < 0) { 04376 /* 04377 * A timer has already expired. 04378 * By definition zero time is the lowest so we can quit early. 04379 */ 04380 lowest = ast_tv(0, 0); 04381 break; 04382 } 04383 if (ast_tvcmp(tv, lowest) < 0) { 04384 lowest = tv; 04385 } 04386 } 04387 } 04388 ast_mutex_unlock(&pri->lock); 04389 04390 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); 04391 pthread_testcancel(); 04392 e = NULL; 04393 res = poll(fds, numdchans, lowest.tv_sec * 1000 + lowest.tv_usec / 1000); 04394 pthread_testcancel(); 04395 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); 04396 04397 ast_mutex_lock(&pri->lock); 04398 if (!res) { 04399 for (which = 0; which < SIG_PRI_NUM_DCHANS; which++) { 04400 if (!pri->dchans[which]) 04401 break; 04402 /* Just a timeout, run the scheduler */ 04403 e = pri_schedule_run(pri->dchans[which]); 04404 if (e) 04405 break; 04406 } 04407 } else if (res > -1) { 04408 for (which = 0; which < SIG_PRI_NUM_DCHANS; which++) { 04409 if (!pri->dchans[which]) 04410 break; 04411 if (fds[which].revents & POLLPRI) { 04412 sig_pri_handle_dchan_exception(pri, which); 04413 } else if (fds[which].revents & POLLIN) { 04414 e = pri_check_event(pri->dchans[which]); 04415 } 04416 if (e) 04417 break; 04418 } 04419 } else if (errno != EINTR) 04420 ast_log(LOG_WARNING, "pri_event returned error %d (%s)\n", errno, strerror(errno)); 04421 04422 if (e) { 04423 if (pri->debug) { 04424 ast_verbose("Span: %d Processing event: %s\n", 04425 pri->span, pri_event2str(e->e)); 04426 } 04427 04428 if (e->e != PRI_EVENT_DCHAN_DOWN) { 04429 if (!(pri->dchanavail[which] & DCHAN_UP)) { 04430 ast_verb(2, "%s D-Channel on span %d up\n", pri_order(which), pri->span); 04431 } 04432 pri->dchanavail[which] |= DCHAN_UP; 04433 } else { 04434 if (pri->dchanavail[which] & DCHAN_UP) { 04435 ast_verb(2, "%s D-Channel on span %d down\n", pri_order(which), pri->span); 04436 } 04437 pri->dchanavail[which] &= ~DCHAN_UP; 04438 } 04439 04440 if ((e->e != PRI_EVENT_DCHAN_UP) && (e->e != PRI_EVENT_DCHAN_DOWN) && (pri->pri != pri->dchans[which])) 04441 /* Must be an NFAS group that has the secondary dchan active */ 04442 pri->pri = pri->dchans[which]; 04443 04444 switch (e->e) { 04445 case PRI_EVENT_DCHAN_UP: 04446 pri->no_d_channels = 0; 04447 if (!pri->pri) pri_find_dchan(pri); 04448 04449 /* Note presense of D-channel */ 04450 time(&pri->lastreset); 04451 04452 /* Restart in 5 seconds */ 04453 if (pri->resetinterval > -1) { 04454 pri->lastreset -= pri->resetinterval; 04455 pri->lastreset += 5; 04456 } 04457 pri->resetting = 0; 04458 /* Take the channels from inalarm condition */ 04459 for (i = 0; i < pri->numchans; i++) { 04460 if (pri->pvts[i]) { 04461 sig_pri_set_alarm(pri->pvts[i], 0); 04462 } 04463 } 04464 sig_pri_span_devstate_changed(pri); 04465 break; 04466 case PRI_EVENT_DCHAN_DOWN: 04467 pri_find_dchan(pri); 04468 if (!pri_is_up(pri)) { 04469 pri->resetting = 0; 04470 if (pri->sig == SIG_BRI_PTMP) { 04471 /* For PTMP connections with non persistent layer 2 we want 04472 * to *not* declare inalarm unless there actually is an alarm */ 04473 break; 04474 } 04475 /* Hangup active channels and put them in alarm mode */ 04476 for (i = 0; i < pri->numchans; i++) { 04477 struct sig_pri_chan *p = pri->pvts[i]; 04478 if (p) { 04479 if (!p->pri || !p->pri->pri || pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0) { 04480 /* T309 is not enabled : hangup calls when alarm occurs */ 04481 if (p->call) { 04482 if (p->pri && p->pri->pri) { 04483 pri_hangup(p->pri->pri, p->call, -1); 04484 pri_destroycall(p->pri->pri, p->call); 04485 p->call = NULL; 04486 } else 04487 ast_log(LOG_WARNING, "The PRI Call have not been destroyed\n"); 04488 } 04489 if (p->owner) 04490 p->owner->_softhangup |= AST_SOFTHANGUP_DEV; 04491 } 04492 sig_pri_set_alarm(p, 1); 04493 } 04494 } 04495 sig_pri_span_devstate_changed(pri); 04496 } 04497 break; 04498 case PRI_EVENT_RESTART: 04499 if (e->restart.channel > -1) { 04500 chanpos = pri_find_principle(pri, e->restart.channel, NULL); 04501 if (chanpos < 0) 04502 ast_log(LOG_WARNING, "Restart requested on odd/unavailable channel number %d/%d on span %d\n", 04503 PRI_SPAN(e->restart.channel), PRI_CHANNEL(e->restart.channel), pri->span); 04504 else { 04505 int skipit = 0; 04506 #if defined(HAVE_PRI_SERVICE_MESSAGES) 04507 unsigned why; 04508 04509 why = pri->pvts[chanpos]->service_status; 04510 if (why) { 04511 ast_log(LOG_NOTICE, 04512 "span '%d' channel '%d' out-of-service (reason: %s), ignoring RESTART\n", 04513 pri->span, PRI_CHANNEL(e->restart.channel), 04514 (why & SRVST_FAREND) ? (why & SRVST_NEAREND) ? "both ends" : "far end" : "near end"); 04515 skipit = 1; 04516 } 04517 #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */ 04518 sig_pri_lock_private(pri->pvts[chanpos]); 04519 if (!skipit) { 04520 ast_verb(3, "B-channel %d/%d restarted on span %d\n", 04521 PRI_SPAN(e->restart.channel), PRI_CHANNEL(e->restart.channel), pri->span); 04522 if (pri->pvts[chanpos]->call) { 04523 pri_destroycall(pri->pri, pri->pvts[chanpos]->call); 04524 pri->pvts[chanpos]->call = NULL; 04525 } 04526 } 04527 /* Force soft hangup if appropriate */ 04528 if (pri->pvts[chanpos]->owner) 04529 pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV; 04530 sig_pri_unlock_private(pri->pvts[chanpos]); 04531 } 04532 } else { 04533 ast_verb(3, "Restart requested on entire span %d\n", pri->span); 04534 for (x = 0; x < pri->numchans; x++) 04535 if (pri->pvts[x]) { 04536 sig_pri_lock_private(pri->pvts[x]); 04537 if (pri->pvts[x]->call) { 04538 pri_destroycall(pri->pri, pri->pvts[x]->call); 04539 pri->pvts[x]->call = NULL; 04540 } 04541 if (pri->pvts[x]->owner) 04542 pri->pvts[x]->owner->_softhangup |= AST_SOFTHANGUP_DEV; 04543 sig_pri_unlock_private(pri->pvts[x]); 04544 } 04545 } 04546 break; 04547 case PRI_EVENT_KEYPAD_DIGIT: 04548 if (sig_pri_is_cis_call(e->digit.channel)) { 04549 sig_pri_handle_cis_subcmds(pri, e->e, e->digit.subcmds, 04550 e->digit.call); 04551 break; 04552 } 04553 chanpos = pri_find_principle(pri, e->digit.channel, e->digit.call); 04554 if (chanpos < 0) { 04555 ast_log(LOG_WARNING, "KEYPAD_DIGITs received on unconfigured channel %d/%d span %d\n", 04556 PRI_SPAN(e->digit.channel), PRI_CHANNEL(e->digit.channel), pri->span); 04557 } else { 04558 chanpos = pri_fixup_principle(pri, chanpos, e->digit.call); 04559 if (chanpos > -1) { 04560 sig_pri_lock_private(pri->pvts[chanpos]); 04561 sig_pri_handle_subcmds(pri, chanpos, e->e, e->digit.channel, 04562 e->digit.subcmds, e->digit.call); 04563 /* queue DTMF frame if the PBX for this call was already started (we're forwarding KEYPAD_DIGITs further on */ 04564 if ((pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING) 04565 && pri->pvts[chanpos]->call == e->digit.call 04566 && pri->pvts[chanpos]->owner) { 04567 /* how to do that */ 04568 int digitlen = strlen(e->digit.digits); 04569 int i; 04570 04571 for (i = 0; i < digitlen; i++) { 04572 struct ast_frame f = { AST_FRAME_DTMF, .subclass.integer = e->digit.digits[i], }; 04573 04574 pri_queue_frame(pri, chanpos, &f); 04575 } 04576 } 04577 sig_pri_unlock_private(pri->pvts[chanpos]); 04578 } 04579 } 04580 break; 04581 04582 case PRI_EVENT_INFO_RECEIVED: 04583 if (sig_pri_is_cis_call(e->ring.channel)) { 04584 sig_pri_handle_cis_subcmds(pri, e->e, e->ring.subcmds, 04585 e->ring.call); 04586 break; 04587 } 04588 chanpos = pri_find_principle(pri, e->ring.channel, e->ring.call); 04589 if (chanpos < 0) { 04590 ast_log(LOG_WARNING, "INFO received on unconfigured channel %d/%d span %d\n", 04591 PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span); 04592 } else { 04593 chanpos = pri_fixup_principle(pri, chanpos, e->ring.call); 04594 if (chanpos > -1) { 04595 sig_pri_lock_private(pri->pvts[chanpos]); 04596 sig_pri_handle_subcmds(pri, chanpos, e->e, e->ring.channel, 04597 e->ring.subcmds, e->ring.call); 04598 /* queue DTMF frame if the PBX for this call was already started (we're forwarding INFORMATION further on */ 04599 if ((pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING) 04600 && pri->pvts[chanpos]->call == e->ring.call 04601 && pri->pvts[chanpos]->owner) { 04602 /* how to do that */ 04603 int digitlen = strlen(e->ring.callednum); 04604 int i; 04605 04606 for (i = 0; i < digitlen; i++) { 04607 struct ast_frame f = { AST_FRAME_DTMF, .subclass.integer = e->ring.callednum[i], }; 04608 04609 pri_queue_frame(pri, chanpos, &f); 04610 } 04611 } 04612 sig_pri_unlock_private(pri->pvts[chanpos]); 04613 } 04614 } 04615 break; 04616 #if defined(HAVE_PRI_SERVICE_MESSAGES) 04617 case PRI_EVENT_SERVICE: 04618 chanpos = pri_find_principle(pri, e->service.channel, NULL); 04619 if (chanpos < 0) { 04620 ast_log(LOG_WARNING, "Received service change status %d on unconfigured channel %d/%d span %d\n", 04621 e->service_ack.changestatus, PRI_SPAN(e->service_ack.channel), PRI_CHANNEL(e->service_ack.channel), pri->span); 04622 } else { 04623 char db_chan_name[20]; 04624 char db_answer[5]; 04625 int ch; 04626 unsigned *why; 04627 04628 ch = pri->pvts[chanpos]->channel; 04629 snprintf(db_chan_name, sizeof(db_chan_name), "%s/%d:%d", dahdi_db, pri->span, ch); 04630 why = &pri->pvts[chanpos]->service_status; 04631 switch (e->service.changestatus) { 04632 case 0: /* in-service */ 04633 /* Far end wants to be in service now. */ 04634 ast_db_del(db_chan_name, SRVST_DBKEY); 04635 *why &= ~SRVST_FAREND; 04636 if (*why) { 04637 snprintf(db_answer, sizeof(db_answer), "%s:%u", 04638 SRVST_TYPE_OOS, *why); 04639 ast_db_put(db_chan_name, SRVST_DBKEY, db_answer); 04640 } else { 04641 sig_pri_span_devstate_changed(pri); 04642 } 04643 break; 04644 case 2: /* out-of-service */ 04645 /* Far end wants to be out-of-service now. */ 04646 ast_db_del(db_chan_name, SRVST_DBKEY); 04647 *why |= SRVST_FAREND; 04648 snprintf(db_answer, sizeof(db_answer), "%s:%u", SRVST_TYPE_OOS, 04649 *why); 04650 ast_db_put(db_chan_name, SRVST_DBKEY, db_answer); 04651 sig_pri_span_devstate_changed(pri); 04652 break; 04653 default: 04654 ast_log(LOG_ERROR, "Huh? changestatus is: %d\n", e->service.changestatus); 04655 break; 04656 } 04657 ast_log(LOG_NOTICE, "Channel %d/%d span %d (logical: %d) received a change of service message, status '%d'\n", 04658 PRI_SPAN(e->service.channel), PRI_CHANNEL(e->service.channel), pri->span, ch, e->service.changestatus); 04659 } 04660 break; 04661 case PRI_EVENT_SERVICE_ACK: 04662 chanpos = pri_find_principle(pri, e->service_ack.channel, NULL); 04663 if (chanpos < 0) { 04664 ast_log(LOG_WARNING, "Received service acknowledge change status '%d' on unconfigured channel %d/%d span %d\n", 04665 e->service_ack.changestatus, PRI_SPAN(e->service_ack.channel), PRI_CHANNEL(e->service_ack.channel), pri->span); 04666 } else { 04667 ast_debug(2, "Channel %d/%d span %d received a change os service acknowledgement message, status '%d'\n", 04668 PRI_SPAN(e->service_ack.channel), PRI_CHANNEL(e->service_ack.channel), pri->span, e->service_ack.changestatus); 04669 } 04670 break; 04671 #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */ 04672 case PRI_EVENT_RING: 04673 if (!ast_strlen_zero(pri->msn_list) 04674 && !sig_pri_msn_match(pri->msn_list, e->ring.callednum)) { 04675 /* The call is not for us so ignore it. */ 04676 ast_verb(3, 04677 "Ignoring call to '%s' on span %d. Its not in the MSN list: %s\n", 04678 e->ring.callednum, pri->span, pri->msn_list); 04679 pri_destroycall(pri->pri, e->ring.call); 04680 break; 04681 } 04682 if (sig_pri_is_cis_call(e->ring.channel)) { 04683 sig_pri_handle_cis_subcmds(pri, e->e, e->ring.subcmds, 04684 e->ring.call); 04685 break; 04686 } 04687 if (e->ring.channel == -1 || PRI_CHANNEL(e->ring.channel) == 0xFF) { 04688 /* Any channel requested. */ 04689 chanpos = pri_find_empty_chan(pri, 1); 04690 } else if (PRI_CHANNEL(e->ring.channel) == 0x00) { 04691 /* No channel specified. */ 04692 #if defined(HAVE_PRI_CALL_WAITING) 04693 if (!pri->allow_call_waiting_calls) 04694 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 04695 { 04696 /* We will not accept incoming call waiting calls. */ 04697 pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_INCOMPATIBLE_DESTINATION); 04698 break; 04699 } 04700 #if defined(HAVE_PRI_CALL_WAITING) 04701 chanpos = pri_find_empty_nobch(pri); 04702 if (chanpos < 0) { 04703 /* We could not find/create a call interface. */ 04704 pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION); 04705 break; 04706 } 04707 /* Setup the call interface to use. */ 04708 sig_pri_init_config(pri->pvts[chanpos], pri); 04709 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 04710 } else { 04711 /* A channel is specified. */ 04712 chanpos = pri_find_principle(pri, e->ring.channel, e->ring.call); 04713 } 04714 /* if no channel specified find one empty */ 04715 if (chanpos < 0) { 04716 ast_log(LOG_WARNING, "Ring requested on unconfigured channel %d/%d span %d\n", 04717 PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span); 04718 } else { 04719 sig_pri_lock_private(pri->pvts[chanpos]); 04720 if (pri->pvts[chanpos]->owner) { 04721 if (pri->pvts[chanpos]->call == e->ring.call) { 04722 ast_log(LOG_WARNING, "Duplicate setup requested on channel %d/%d already in use on span %d\n", 04723 PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span); 04724 sig_pri_unlock_private(pri->pvts[chanpos]); 04725 break; 04726 } else { 04727 /* This is where we handle initial glare */ 04728 ast_debug(1, "Ring requested on channel %d/%d already in use or previously requested on span %d. Attempting to renegotiating channel.\n", 04729 PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span); 04730 sig_pri_unlock_private(pri->pvts[chanpos]); 04731 chanpos = -1; 04732 } 04733 } 04734 if (chanpos > -1) 04735 sig_pri_unlock_private(pri->pvts[chanpos]); 04736 } 04737 if ((chanpos < 0) && (e->ring.flexible)) 04738 chanpos = pri_find_empty_chan(pri, 1); 04739 if (chanpos > -1) { 04740 sig_pri_lock_private(pri->pvts[chanpos]); 04741 pri->pvts[chanpos]->call = e->ring.call; 04742 04743 /* Use plancallingnum as a scratch buffer since it is initialized next. */ 04744 apply_plan_to_number(plancallingnum, sizeof(plancallingnum), pri, 04745 e->ring.redirectingnum, e->ring.callingplanrdnis); 04746 sig_pri_set_rdnis(pri->pvts[chanpos], plancallingnum); 04747 04748 /* Setup caller-id info */ 04749 apply_plan_to_number(plancallingnum, sizeof(plancallingnum), pri, e->ring.callingnum, e->ring.callingplan); 04750 pri->pvts[chanpos]->cid_ani2 = 0; 04751 if (pri->pvts[chanpos]->use_callerid) { 04752 ast_shrink_phone_number(plancallingnum); 04753 ast_copy_string(pri->pvts[chanpos]->cid_num, plancallingnum, sizeof(pri->pvts[chanpos]->cid_num)); 04754 #ifdef PRI_ANI 04755 if (!ast_strlen_zero(e->ring.callingani)) { 04756 apply_plan_to_number(plancallingani, sizeof(plancallingani), pri, e->ring.callingani, e->ring.callingplanani); 04757 ast_shrink_phone_number(plancallingani); 04758 ast_copy_string(pri->pvts[chanpos]->cid_ani, plancallingani, sizeof(pri->pvts[chanpos]->cid_ani)); 04759 } else { 04760 pri->pvts[chanpos]->cid_ani[0] = '\0'; 04761 } 04762 #endif 04763 pri->pvts[chanpos]->cid_subaddr[0] = '\0'; 04764 #if defined(HAVE_PRI_SUBADDR) 04765 if (e->ring.calling.subaddress.valid) { 04766 struct ast_party_subaddress calling_subaddress; 04767 04768 ast_party_subaddress_init(&calling_subaddress); 04769 sig_pri_set_subaddress(&calling_subaddress, 04770 &e->ring.calling.subaddress); 04771 if (calling_subaddress.str) { 04772 ast_copy_string(pri->pvts[chanpos]->cid_subaddr, 04773 calling_subaddress.str, 04774 sizeof(pri->pvts[chanpos]->cid_subaddr)); 04775 } 04776 ast_party_subaddress_free(&calling_subaddress); 04777 } 04778 #endif /* defined(HAVE_PRI_SUBADDR) */ 04779 ast_copy_string(pri->pvts[chanpos]->cid_name, e->ring.callingname, sizeof(pri->pvts[chanpos]->cid_name)); 04780 pri->pvts[chanpos]->cid_ton = e->ring.callingplan; /* this is the callingplan (TON/NPI), e->ring.callingplan>>4 would be the TON */ 04781 pri->pvts[chanpos]->callingpres = e->ring.callingpres; 04782 if (e->ring.ani2 >= 0) { 04783 pri->pvts[chanpos]->cid_ani2 = e->ring.ani2; 04784 } 04785 } else { 04786 pri->pvts[chanpos]->cid_num[0] = '\0'; 04787 pri->pvts[chanpos]->cid_subaddr[0] = '\0'; 04788 pri->pvts[chanpos]->cid_ani[0] = '\0'; 04789 pri->pvts[chanpos]->cid_name[0] = '\0'; 04790 pri->pvts[chanpos]->cid_ton = 0; 04791 pri->pvts[chanpos]->callingpres = 0; 04792 } 04793 04794 /* Setup the user tag for party id's from this device for this call. */ 04795 if (pri->append_msn_to_user_tag) { 04796 snprintf(pri->pvts[chanpos]->user_tag, 04797 sizeof(pri->pvts[chanpos]->user_tag), "%s_%s", 04798 pri->initial_user_tag, 04799 pri->nodetype == PRI_NETWORK 04800 ? plancallingnum : e->ring.callednum); 04801 } else { 04802 ast_copy_string(pri->pvts[chanpos]->user_tag, 04803 pri->initial_user_tag, sizeof(pri->pvts[chanpos]->user_tag)); 04804 } 04805 04806 sig_pri_set_caller_id(pri->pvts[chanpos]); 04807 04808 /* Set DNID on all incoming calls -- even immediate */ 04809 sig_pri_set_dnid(pri->pvts[chanpos], e->ring.callednum); 04810 04811 /* If immediate=yes go to s|1 */ 04812 if (pri->pvts[chanpos]->immediate) { 04813 ast_verb(3, "Going to extension s|1 because of immediate=yes\n"); 04814 pri->pvts[chanpos]->exten[0] = 's'; 04815 pri->pvts[chanpos]->exten[1] = '\0'; 04816 } 04817 /* Get called number */ 04818 else if (!ast_strlen_zero(e->ring.callednum)) { 04819 ast_copy_string(pri->pvts[chanpos]->exten, e->ring.callednum, sizeof(pri->pvts[chanpos]->exten)); 04820 } else if (pri->overlapdial) 04821 pri->pvts[chanpos]->exten[0] = '\0'; 04822 else { 04823 /* Some PRI circuits are set up to send _no_ digits. Handle them as 's'. */ 04824 pri->pvts[chanpos]->exten[0] = 's'; 04825 pri->pvts[chanpos]->exten[1] = '\0'; 04826 } 04827 /* No number yet, but received "sending complete"? */ 04828 if (e->ring.complete && (ast_strlen_zero(e->ring.callednum))) { 04829 ast_verb(3, "Going to extension s|1 because of Complete received\n"); 04830 pri->pvts[chanpos]->exten[0] = 's'; 04831 pri->pvts[chanpos]->exten[1] = '\0'; 04832 } 04833 04834 /* Make sure extension exists (or in overlap dial mode, can exist) */ 04835 if (((pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING) && ast_canmatch_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) || 04836 ast_exists_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) { 04837 /* Setup law */ 04838 if (e->ring.complete || !(pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)) { 04839 /* Just announce proceeding */ 04840 pri->pvts[chanpos]->proceeding = 1; 04841 pri_proceeding(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 0); 04842 } else { 04843 if (pri->switchtype != PRI_SWITCH_GR303_TMC) 04844 pri_need_more_info(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 1); 04845 else 04846 pri_answer(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 1); 04847 } 04848 04849 /* Start PBX */ 04850 if (!e->ring.complete 04851 && (pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING) 04852 && ast_matchmore_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) { 04853 /* 04854 * Release the PRI lock while we create the channel 04855 * so other threads can send D channel messages. 04856 */ 04857 ast_mutex_unlock(&pri->lock); 04858 c = sig_pri_new_ast_channel(pri->pvts[chanpos], 04859 AST_STATE_RESERVED, 04860 (e->ring.layer1 == PRI_LAYER_1_ALAW) 04861 ? SIG_PRI_ALAW : SIG_PRI_ULAW, 04862 e->ring.ctype, pri->pvts[chanpos]->exten, NULL); 04863 ast_mutex_lock(&pri->lock); 04864 if (c) { 04865 #if defined(HAVE_PRI_SUBADDR) 04866 if (e->ring.calling.subaddress.valid) { 04867 /* Set Calling Subaddress */ 04868 sig_pri_lock_owner(pri, chanpos); 04869 sig_pri_set_subaddress( 04870 &pri->pvts[chanpos]->owner->caller.id.subaddress, 04871 &e->ring.calling.subaddress); 04872 if (!e->ring.calling.subaddress.type 04873 && !ast_strlen_zero( 04874 (char *) e->ring.calling.subaddress.data)) { 04875 /* NSAP */ 04876 pbx_builtin_setvar_helper(c, "CALLINGSUBADDR", 04877 (char *) e->ring.calling.subaddress.data); 04878 } 04879 ast_channel_unlock(c); 04880 } 04881 if (e->ring.called_subaddress.valid) { 04882 /* Set Called Subaddress */ 04883 sig_pri_lock_owner(pri, chanpos); 04884 sig_pri_set_subaddress( 04885 &pri->pvts[chanpos]->owner->dialed.subaddress, 04886 &e->ring.called_subaddress); 04887 if (!e->ring.called_subaddress.type 04888 && !ast_strlen_zero( 04889 (char *) e->ring.called_subaddress.data)) { 04890 /* NSAP */ 04891 pbx_builtin_setvar_helper(c, "CALLEDSUBADDR", 04892 (char *) e->ring.called_subaddress.data); 04893 } 04894 ast_channel_unlock(c); 04895 } 04896 #else 04897 if (!ast_strlen_zero(e->ring.callingsubaddr)) { 04898 pbx_builtin_setvar_helper(c, "CALLINGSUBADDR", e->ring.callingsubaddr); 04899 } 04900 #endif /* !defined(HAVE_PRI_SUBADDR) */ 04901 if (e->ring.ani2 >= 0) { 04902 snprintf(ani2str, sizeof(ani2str), "%d", e->ring.ani2); 04903 pbx_builtin_setvar_helper(c, "ANI2", ani2str); 04904 } 04905 04906 #ifdef SUPPORT_USERUSER 04907 if (!ast_strlen_zero(e->ring.useruserinfo)) { 04908 pbx_builtin_setvar_helper(c, "USERUSERINFO", e->ring.useruserinfo); 04909 } 04910 #endif 04911 04912 snprintf(calledtonstr, sizeof(calledtonstr), "%d", e->ring.calledplan); 04913 pbx_builtin_setvar_helper(c, "CALLEDTON", calledtonstr); 04914 if (e->ring.redirectingreason >= 0) { 04915 /* This is now just a status variable. Use REDIRECTING() dialplan function. */ 04916 pbx_builtin_setvar_helper(c, "PRIREDIRECTREASON", redirectingreason2str(e->ring.redirectingreason)); 04917 } 04918 #if defined(HAVE_PRI_REVERSE_CHARGE) 04919 pri->pvts[chanpos]->reverse_charging_indication = e->ring.reversecharge; 04920 #endif 04921 #if defined(HAVE_PRI_SETUP_KEYPAD) 04922 ast_copy_string(pri->pvts[chanpos]->keypad_digits, 04923 e->ring.keypad_digits, 04924 sizeof(pri->pvts[chanpos]->keypad_digits)); 04925 #endif /* defined(HAVE_PRI_SETUP_KEYPAD) */ 04926 04927 sig_pri_handle_subcmds(pri, chanpos, e->e, e->ring.channel, 04928 e->ring.subcmds, e->ring.call); 04929 04930 } 04931 if (c && !ast_pthread_create_detached(&threadid, NULL, pri_ss_thread, pri->pvts[chanpos])) { 04932 ast_verb(3, "Accepting overlap call from '%s' to '%s' on channel %d/%d, span %d\n", 04933 plancallingnum, S_OR(pri->pvts[chanpos]->exten, "<unspecified>"), 04934 pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span); 04935 } else { 04936 ast_log(LOG_WARNING, "Unable to start PBX on channel %d/%d, span %d\n", 04937 pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span); 04938 if (c) 04939 ast_hangup(c); 04940 else { 04941 pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_SWITCH_CONGESTION); 04942 pri->pvts[chanpos]->call = NULL; 04943 } 04944 } 04945 } else { 04946 /* 04947 * Release the PRI lock while we create the channel 04948 * so other threads can send D channel messages. 04949 */ 04950 ast_mutex_unlock(&pri->lock); 04951 c = sig_pri_new_ast_channel(pri->pvts[chanpos], 04952 AST_STATE_RING, 04953 (e->ring.layer1 == PRI_LAYER_1_ALAW) 04954 ? SIG_PRI_ALAW : SIG_PRI_ULAW, e->ring.ctype, 04955 pri->pvts[chanpos]->exten, NULL); 04956 ast_mutex_lock(&pri->lock); 04957 if (c) { 04958 /* 04959 * It is reasonably safe to set the following 04960 * channel variables while the PRI and DAHDI private 04961 * structures are locked. The PBX has not been 04962 * started yet and it is unlikely that any other task 04963 * will do anything with the channel we have just 04964 * created. 04965 */ 04966 #if defined(HAVE_PRI_SUBADDR) 04967 if (e->ring.calling.subaddress.valid) { 04968 /* Set Calling Subaddress */ 04969 sig_pri_lock_owner(pri, chanpos); 04970 sig_pri_set_subaddress( 04971 &pri->pvts[chanpos]->owner->caller.id.subaddress, 04972 &e->ring.calling.subaddress); 04973 if (!e->ring.calling.subaddress.type 04974 && !ast_strlen_zero( 04975 (char *) e->ring.calling.subaddress.data)) { 04976 /* NSAP */ 04977 pbx_builtin_setvar_helper(c, "CALLINGSUBADDR", 04978 (char *) e->ring.calling.subaddress.data); 04979 } 04980 ast_channel_unlock(c); 04981 } 04982 if (e->ring.called_subaddress.valid) { 04983 /* Set Called Subaddress */ 04984 sig_pri_lock_owner(pri, chanpos); 04985 sig_pri_set_subaddress( 04986 &pri->pvts[chanpos]->owner->dialed.subaddress, 04987 &e->ring.called_subaddress); 04988 if (!e->ring.called_subaddress.type 04989 && !ast_strlen_zero( 04990 (char *) e->ring.called_subaddress.data)) { 04991 /* NSAP */ 04992 pbx_builtin_setvar_helper(c, "CALLEDSUBADDR", 04993 (char *) e->ring.called_subaddress.data); 04994 } 04995 ast_channel_unlock(c); 04996 } 04997 #else 04998 if (!ast_strlen_zero(e->ring.callingsubaddr)) { 04999 pbx_builtin_setvar_helper(c, "CALLINGSUBADDR", e->ring.callingsubaddr); 05000 } 05001 #endif /* !defined(HAVE_PRI_SUBADDR) */ 05002 if (e->ring.ani2 >= 0) { 05003 snprintf(ani2str, sizeof(ani2str), "%d", e->ring.ani2); 05004 pbx_builtin_setvar_helper(c, "ANI2", ani2str); 05005 } 05006 05007 #ifdef SUPPORT_USERUSER 05008 if (!ast_strlen_zero(e->ring.useruserinfo)) { 05009 pbx_builtin_setvar_helper(c, "USERUSERINFO", e->ring.useruserinfo); 05010 } 05011 #endif 05012 05013 if (e->ring.redirectingreason >= 0) { 05014 /* This is now just a status variable. Use REDIRECTING() dialplan function. */ 05015 pbx_builtin_setvar_helper(c, "PRIREDIRECTREASON", redirectingreason2str(e->ring.redirectingreason)); 05016 } 05017 #if defined(HAVE_PRI_REVERSE_CHARGE) 05018 pri->pvts[chanpos]->reverse_charging_indication = e->ring.reversecharge; 05019 #endif 05020 #if defined(HAVE_PRI_SETUP_KEYPAD) 05021 ast_copy_string(pri->pvts[chanpos]->keypad_digits, 05022 e->ring.keypad_digits, 05023 sizeof(pri->pvts[chanpos]->keypad_digits)); 05024 #endif /* defined(HAVE_PRI_SETUP_KEYPAD) */ 05025 05026 snprintf(calledtonstr, sizeof(calledtonstr), "%d", e->ring.calledplan); 05027 pbx_builtin_setvar_helper(c, "CALLEDTON", calledtonstr); 05028 05029 sig_pri_handle_subcmds(pri, chanpos, e->e, e->ring.channel, 05030 e->ring.subcmds, e->ring.call); 05031 05032 } 05033 if (c && !ast_pbx_start(c)) { 05034 ast_verb(3, "Accepting call from '%s' to '%s' on channel %d/%d, span %d\n", 05035 plancallingnum, pri->pvts[chanpos]->exten, 05036 pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span); 05037 sig_pri_set_echocanceller(pri->pvts[chanpos], 1); 05038 } else { 05039 ast_log(LOG_WARNING, "Unable to start PBX on channel %d/%d, span %d\n", 05040 pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span); 05041 if (c) { 05042 ast_hangup(c); 05043 } else { 05044 pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_SWITCH_CONGESTION); 05045 pri->pvts[chanpos]->call = NULL; 05046 } 05047 } 05048 } 05049 } else { 05050 ast_verb(3, "Extension '%s' in context '%s' from '%s' does not exist. Rejecting call on channel %d/%d, span %d\n", 05051 pri->pvts[chanpos]->exten, pri->pvts[chanpos]->context, pri->pvts[chanpos]->cid_num, pri->pvts[chanpos]->logicalspan, 05052 pri->pvts[chanpos]->prioffset, pri->span); 05053 pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_UNALLOCATED); 05054 pri->pvts[chanpos]->call = NULL; 05055 pri->pvts[chanpos]->exten[0] = '\0'; 05056 } 05057 sig_pri_unlock_private(pri->pvts[chanpos]); 05058 } else { 05059 if (e->ring.flexible) 05060 pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION); 05061 else 05062 pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_REQUESTED_CHAN_UNAVAIL); 05063 } 05064 break; 05065 case PRI_EVENT_RINGING: 05066 if (sig_pri_is_cis_call(e->ringing.channel)) { 05067 sig_pri_handle_cis_subcmds(pri, e->e, e->ringing.subcmds, 05068 e->ringing.call); 05069 break; 05070 } 05071 chanpos = pri_find_principle(pri, e->ringing.channel, e->ringing.call); 05072 if (chanpos < 0) { 05073 ast_log(LOG_WARNING, "Ringing requested on unconfigured channel %d/%d span %d\n", 05074 PRI_SPAN(e->ringing.channel), PRI_CHANNEL(e->ringing.channel), pri->span); 05075 } else { 05076 chanpos = pri_fixup_principle(pri, chanpos, e->ringing.call); 05077 if (chanpos < 0) { 05078 ast_log(LOG_WARNING, "Ringing requested on channel %d/%d not in use on span %d\n", 05079 PRI_SPAN(e->ringing.channel), PRI_CHANNEL(e->ringing.channel), pri->span); 05080 } else { 05081 sig_pri_lock_private(pri->pvts[chanpos]); 05082 05083 sig_pri_handle_subcmds(pri, chanpos, e->e, e->ringing.channel, 05084 e->ringing.subcmds, e->ringing.call); 05085 sig_pri_cc_generic_check(pri, chanpos, AST_CC_CCNR); 05086 sig_pri_set_echocanceller(pri->pvts[chanpos], 1); 05087 pri_queue_control(pri, chanpos, AST_CONTROL_RINGING); 05088 pri->pvts[chanpos]->alerting = 1; 05089 05090 if ( 05091 #ifdef PRI_PROGRESS_MASK 05092 e->ringing.progressmask & PRI_PROG_INBAND_AVAILABLE 05093 #else 05094 e->ringing.progress == 8 05095 #endif 05096 ) { 05097 sig_pri_open_media(pri->pvts[chanpos]); 05098 } 05099 05100 05101 #ifdef SUPPORT_USERUSER 05102 if (!ast_strlen_zero(e->ringing.useruserinfo)) { 05103 struct ast_channel *owner; 05104 05105 sig_pri_lock_owner(pri, chanpos); 05106 owner = pri->pvts[chanpos]->owner; 05107 if (owner) { 05108 pbx_builtin_setvar_helper(owner, "USERUSERINFO", 05109 e->ringing.useruserinfo); 05110 ast_channel_unlock(owner); 05111 } 05112 } 05113 #endif 05114 05115 sig_pri_unlock_private(pri->pvts[chanpos]); 05116 } 05117 } 05118 break; 05119 case PRI_EVENT_PROGRESS: 05120 if (sig_pri_is_cis_call(e->proceeding.channel)) { 05121 sig_pri_handle_cis_subcmds(pri, e->e, e->proceeding.subcmds, 05122 e->proceeding.call); 05123 break; 05124 } 05125 chanpos = pri_find_principle(pri, e->proceeding.channel, e->proceeding.call); 05126 if (chanpos > -1) { 05127 sig_pri_lock_private(pri->pvts[chanpos]); 05128 sig_pri_handle_subcmds(pri, chanpos, e->e, e->proceeding.channel, 05129 e->proceeding.subcmds, e->proceeding.call); 05130 05131 if (e->proceeding.cause > -1) { 05132 ast_verb(3, "PROGRESS with cause code %d received\n", e->proceeding.cause); 05133 05134 /* Work around broken, out of spec USER_BUSY cause in a progress message */ 05135 if (e->proceeding.cause == AST_CAUSE_USER_BUSY) { 05136 if (pri->pvts[chanpos]->owner) { 05137 ast_verb(3, "PROGRESS with 'user busy' received, signaling AST_CONTROL_BUSY instead of AST_CONTROL_PROGRESS\n"); 05138 05139 pri->pvts[chanpos]->owner->hangupcause = e->proceeding.cause; 05140 pri_queue_control(pri, chanpos, AST_CONTROL_BUSY); 05141 } 05142 } 05143 } 05144 05145 if (!pri->pvts[chanpos]->progress 05146 && !pri->pvts[chanpos]->no_b_channel 05147 #ifdef PRI_PROGRESS_MASK 05148 && (e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE) 05149 #else 05150 && e->proceeding.progress == 8 05151 #endif 05152 ) { 05153 /* Bring voice path up */ 05154 ast_debug(1, "Queuing frame from PRI_EVENT_PROGRESS on channel %d/%d span %d\n", 05155 pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset,pri->span); 05156 pri_queue_control(pri, chanpos, AST_CONTROL_PROGRESS); 05157 pri->pvts[chanpos]->progress = 1; 05158 sig_pri_set_dialing(pri->pvts[chanpos], 0); 05159 sig_pri_open_media(pri->pvts[chanpos]); 05160 } 05161 sig_pri_unlock_private(pri->pvts[chanpos]); 05162 } 05163 break; 05164 case PRI_EVENT_PROCEEDING: 05165 if (sig_pri_is_cis_call(e->proceeding.channel)) { 05166 sig_pri_handle_cis_subcmds(pri, e->e, e->proceeding.subcmds, 05167 e->proceeding.call); 05168 break; 05169 } 05170 chanpos = pri_find_principle(pri, e->proceeding.channel, e->proceeding.call); 05171 if (chanpos > -1) { 05172 sig_pri_lock_private(pri->pvts[chanpos]); 05173 sig_pri_handle_subcmds(pri, chanpos, e->e, e->proceeding.channel, 05174 e->proceeding.subcmds, e->proceeding.call); 05175 if (!pri->pvts[chanpos]->proceeding) { 05176 ast_debug(1, "Queuing frame from PRI_EVENT_PROCEEDING on channel %d/%d span %d\n", 05177 pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset,pri->span); 05178 pri_queue_control(pri, chanpos, AST_CONTROL_PROCEEDING); 05179 pri->pvts[chanpos]->proceeding = 1; 05180 } 05181 if (!pri->pvts[chanpos]->progress 05182 && !pri->pvts[chanpos]->no_b_channel 05183 #ifdef PRI_PROGRESS_MASK 05184 && (e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE) 05185 #else 05186 && e->proceeding.progress == 8 05187 #endif 05188 ) { 05189 /* Bring voice path up */ 05190 pri_queue_control(pri, chanpos, AST_CONTROL_PROGRESS); 05191 pri->pvts[chanpos]->progress = 1; 05192 sig_pri_set_dialing(pri->pvts[chanpos], 0); 05193 sig_pri_open_media(pri->pvts[chanpos]); 05194 } 05195 sig_pri_unlock_private(pri->pvts[chanpos]); 05196 } 05197 break; 05198 case PRI_EVENT_FACILITY: 05199 if (!e->facility.call || sig_pri_is_cis_call(e->facility.channel)) { 05200 /* Event came in on the dummy channel or a CIS call. */ 05201 #if defined(HAVE_PRI_CALL_REROUTING) 05202 sig_pri_handle_cis_subcmds(pri, e->e, e->facility.subcmds, 05203 e->facility.subcall); 05204 #else 05205 sig_pri_handle_cis_subcmds(pri, e->e, e->facility.subcmds, 05206 e->facility.call); 05207 #endif /* !defined(HAVE_PRI_CALL_REROUTING) */ 05208 break; 05209 } 05210 chanpos = pri_find_principle(pri, e->facility.channel, e->facility.call); 05211 if (chanpos < 0) { 05212 ast_log(LOG_WARNING, "Facility requested on unconfigured channel %d/%d span %d\n", 05213 PRI_SPAN(e->facility.channel), PRI_CHANNEL(e->facility.channel), pri->span); 05214 } else { 05215 chanpos = pri_fixup_principle(pri, chanpos, e->facility.call); 05216 if (chanpos < 0) { 05217 ast_log(LOG_WARNING, "Facility requested on channel %d/%d not in use on span %d\n", 05218 PRI_SPAN(e->facility.channel), PRI_CHANNEL(e->facility.channel), pri->span); 05219 } else { 05220 sig_pri_lock_private(pri->pvts[chanpos]); 05221 #if defined(HAVE_PRI_CALL_REROUTING) 05222 sig_pri_handle_subcmds(pri, chanpos, e->e, e->facility.channel, 05223 e->facility.subcmds, e->facility.subcall); 05224 #else 05225 sig_pri_handle_subcmds(pri, chanpos, e->e, e->facility.channel, 05226 e->facility.subcmds, e->facility.call); 05227 #endif /* !defined(HAVE_PRI_CALL_REROUTING) */ 05228 sig_pri_unlock_private(pri->pvts[chanpos]); 05229 } 05230 } 05231 break; 05232 case PRI_EVENT_ANSWER: 05233 if (sig_pri_is_cis_call(e->answer.channel)) { 05234 #if defined(HAVE_PRI_CALL_WAITING) 05235 /* Call is CIS so do normal CONNECT_ACKNOWLEDGE. */ 05236 pri_connect_ack(pri->pri, e->answer.call, 0); 05237 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 05238 sig_pri_handle_cis_subcmds(pri, e->e, e->answer.subcmds, 05239 e->answer.call); 05240 break; 05241 } 05242 chanpos = pri_find_principle(pri, e->answer.channel, e->answer.call); 05243 if (chanpos < 0) { 05244 ast_log(LOG_WARNING, "Answer on unconfigured channel %d/%d span %d\n", 05245 PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), pri->span); 05246 break; 05247 } 05248 chanpos = pri_fixup_principle(pri, chanpos, e->answer.call); 05249 if (chanpos < 0) { 05250 ast_log(LOG_WARNING, "Answer requested on channel %d/%d not in use on span %d\n", 05251 PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), pri->span); 05252 break; 05253 } 05254 #if defined(HAVE_PRI_CALL_WAITING) 05255 if (pri->pvts[chanpos]->is_call_waiting) { 05256 if (pri->pvts[chanpos]->no_b_channel) { 05257 int new_chanpos; 05258 05259 /* 05260 * Need to find a free channel now or 05261 * kill the call with PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION. 05262 */ 05263 new_chanpos = pri_find_empty_chan(pri, 1); 05264 if (new_chanpos < 0) { 05265 sig_pri_lock_private(pri->pvts[chanpos]); 05266 sig_pri_handle_subcmds(pri, chanpos, e->e, e->answer.channel, 05267 e->answer.subcmds, e->answer.call); 05268 sig_pri_cc_generic_check(pri, chanpos, AST_CC_CCBS); 05269 if (pri->pvts[chanpos]->owner) { 05270 pri->pvts[chanpos]->owner->hangupcause = PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION; 05271 switch (pri->pvts[chanpos]->owner->_state) { 05272 case AST_STATE_BUSY: 05273 case AST_STATE_UP: 05274 ast_softhangup_nolock(pri->pvts[chanpos]->owner, AST_SOFTHANGUP_DEV); 05275 break; 05276 default: 05277 pri_queue_control(pri, chanpos, AST_CONTROL_CONGESTION); 05278 break; 05279 } 05280 } else { 05281 pri->pvts[chanpos]->is_call_waiting = 0; 05282 ast_atomic_fetchadd_int(&pri->num_call_waiting_calls, -1); 05283 pri_hangup(pri->pri, e->answer.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION); 05284 pri->pvts[chanpos]->call = NULL; 05285 } 05286 sig_pri_unlock_private(pri->pvts[chanpos]); 05287 break; 05288 } 05289 chanpos = pri_fixup_principle(pri, new_chanpos, e->answer.call); 05290 if (chanpos < 0) { 05291 ast_log(LOG_WARNING, 05292 "Unable to move call waiting call channel on span %d\n", 05293 pri->span); 05294 break; 05295 } 05296 } 05297 pri_connect_ack(pri->pri, e->answer.call, PVT_TO_CHANNEL(pri->pvts[chanpos])); 05298 } else { 05299 /* Call is normal so do normal CONNECT_ACKNOWLEDGE. */ 05300 pri_connect_ack(pri->pri, e->answer.call, 0); 05301 } 05302 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 05303 sig_pri_lock_private(pri->pvts[chanpos]); 05304 05305 #if defined(HAVE_PRI_CALL_WAITING) 05306 if (pri->pvts[chanpos]->is_call_waiting) { 05307 pri->pvts[chanpos]->is_call_waiting = 0; 05308 ast_atomic_fetchadd_int(&pri->num_call_waiting_calls, -1); 05309 sig_pri_span_devstate_changed(pri); 05310 } 05311 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 05312 sig_pri_handle_subcmds(pri, chanpos, e->e, e->answer.channel, 05313 e->answer.subcmds, e->answer.call); 05314 pri->pvts[chanpos]->proceeding = 1; 05315 sig_pri_open_media(pri->pvts[chanpos]); 05316 pri_queue_control(pri, chanpos, AST_CONTROL_ANSWER); 05317 /* Enable echo cancellation if it's not on already */ 05318 sig_pri_set_dialing(pri->pvts[chanpos], 0); 05319 sig_pri_set_echocanceller(pri->pvts[chanpos], 1); 05320 05321 #ifdef SUPPORT_USERUSER 05322 if (!ast_strlen_zero(e->answer.useruserinfo)) { 05323 struct ast_channel *owner; 05324 05325 sig_pri_lock_owner(pri, chanpos); 05326 owner = pri->pvts[chanpos]->owner; 05327 if (owner) { 05328 pbx_builtin_setvar_helper(owner, "USERUSERINFO", 05329 e->answer.useruserinfo); 05330 ast_channel_unlock(owner); 05331 } 05332 } 05333 #endif 05334 05335 sig_pri_unlock_private(pri->pvts[chanpos]); 05336 break; 05337 #if defined(HAVE_PRI_CALL_WAITING) 05338 case PRI_EVENT_CONNECT_ACK: 05339 if (sig_pri_is_cis_call(e->connect_ack.channel)) { 05340 sig_pri_handle_cis_subcmds(pri, e->e, e->connect_ack.subcmds, 05341 e->connect_ack.call); 05342 break; 05343 } 05344 chanpos = pri_find_principle(pri, e->connect_ack.channel, 05345 e->connect_ack.call); 05346 if (chanpos < 0) { 05347 ast_log(LOG_WARNING, "Connect ACK on unconfigured channel %d/%d span %d\n", 05348 PRI_SPAN(e->connect_ack.channel), 05349 PRI_CHANNEL(e->connect_ack.channel), pri->span); 05350 break; 05351 } 05352 chanpos = pri_fixup_principle(pri, chanpos, e->connect_ack.call); 05353 if (chanpos < 0) { 05354 ast_log(LOG_WARNING, "Connect ACK requested on channel %d/%d not in use on span %d\n", 05355 PRI_SPAN(e->connect_ack.channel), 05356 PRI_CHANNEL(e->connect_ack.channel), pri->span); 05357 break; 05358 } 05359 05360 sig_pri_lock_private(pri->pvts[chanpos]); 05361 sig_pri_span_devstate_changed(pri); 05362 sig_pri_handle_subcmds(pri, chanpos, e->e, e->connect_ack.channel, 05363 e->connect_ack.subcmds, e->connect_ack.call); 05364 sig_pri_open_media(pri->pvts[chanpos]); 05365 sig_pri_unlock_private(pri->pvts[chanpos]); 05366 break; 05367 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 05368 case PRI_EVENT_HANGUP: 05369 if (sig_pri_is_cis_call(e->hangup.channel)) { 05370 sig_pri_handle_cis_subcmds(pri, e->e, e->hangup.subcmds, 05371 e->hangup.call); 05372 pri_hangup(pri->pri, e->hangup.call, e->hangup.cause); 05373 break; 05374 } 05375 chanpos = pri_find_principle(pri, e->hangup.channel, e->hangup.call); 05376 if (chanpos < 0) { 05377 ast_log(LOG_WARNING, "Hangup requested on unconfigured channel %d/%d span %d\n", 05378 PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span); 05379 /* 05380 * Continue hanging up the call even though 05381 * it is on an unconfigured channel. 05382 */ 05383 pri_hangup(pri->pri, e->hangup.call, e->hangup.cause); 05384 } else { 05385 chanpos = pri_fixup_principle(pri, chanpos, e->hangup.call); 05386 if (chanpos > -1) { 05387 sig_pri_lock_private(pri->pvts[chanpos]); 05388 sig_pri_handle_subcmds(pri, chanpos, e->e, e->hangup.channel, 05389 e->hangup.subcmds, e->hangup.call); 05390 if (!pri->pvts[chanpos]->alreadyhungup) { 05391 /* we're calling here dahdi_hangup so once we get there we need to clear p->call after calling pri_hangup */ 05392 pri->pvts[chanpos]->alreadyhungup = 1; 05393 switch (e->hangup.cause) { 05394 case PRI_CAUSE_USER_BUSY: 05395 case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION: 05396 sig_pri_cc_generic_check(pri, chanpos, AST_CC_CCBS); 05397 break; 05398 default: 05399 break; 05400 } 05401 if (pri->pvts[chanpos]->owner) { 05402 int do_hangup = 0; 05403 /* Queue a BUSY instead of a hangup if our cause is appropriate */ 05404 pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause; 05405 switch (pri->pvts[chanpos]->owner->_state) { 05406 case AST_STATE_BUSY: 05407 case AST_STATE_UP: 05408 do_hangup = 1; 05409 break; 05410 default: 05411 if (!pri->pvts[chanpos]->outgoing) { 05412 /* 05413 * The incoming call leg hung up before getting 05414 * connected so just hangup the call. 05415 */ 05416 do_hangup = 1; 05417 break; 05418 } 05419 switch (e->hangup.cause) { 05420 case PRI_CAUSE_USER_BUSY: 05421 pri_queue_control(pri, chanpos, AST_CONTROL_BUSY); 05422 break; 05423 case PRI_CAUSE_CALL_REJECTED: 05424 case PRI_CAUSE_NETWORK_OUT_OF_ORDER: 05425 case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION: 05426 case PRI_CAUSE_SWITCH_CONGESTION: 05427 case PRI_CAUSE_DESTINATION_OUT_OF_ORDER: 05428 case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE: 05429 pri_queue_control(pri, chanpos, AST_CONTROL_CONGESTION); 05430 break; 05431 default: 05432 do_hangup = 1; 05433 break; 05434 } 05435 break; 05436 } 05437 05438 if (do_hangup) { 05439 #if defined(HAVE_PRI_AOC_EVENTS) 05440 if (detect_aoc_e_subcmd(e->hangup.subcmds)) { 05441 /* If a AOC-E msg was sent during the release, we must use a 05442 * AST_CONTROL_HANGUP frame to guarantee that frame gets read before hangup */ 05443 pri_queue_control(pri, chanpos, AST_CONTROL_HANGUP); 05444 } else { 05445 pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV; 05446 } 05447 #else 05448 pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV; 05449 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 05450 } 05451 } else { 05452 /* 05453 * Continue hanging up the call even though 05454 * we do not have an owner. 05455 */ 05456 pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause); 05457 pri->pvts[chanpos]->call = NULL; 05458 } 05459 ast_verb(3, "Channel %d/%d, span %d got hangup, cause %d\n", 05460 pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, e->hangup.cause); 05461 } else { 05462 /* Continue hanging up the call. */ 05463 pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause); 05464 pri->pvts[chanpos]->call = NULL; 05465 } 05466 if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL) { 05467 ast_verb(3, "Forcing restart of channel %d/%d on span %d since channel reported in use\n", 05468 PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span); 05469 pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos])); 05470 pri->pvts[chanpos]->resetting = 1; 05471 } 05472 if (e->hangup.aoc_units > -1) 05473 ast_verb(3, "Channel %d/%d, span %d received AOC-E charging %d unit%s\n", 05474 pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s"); 05475 05476 #ifdef SUPPORT_USERUSER 05477 if (!ast_strlen_zero(e->hangup.useruserinfo)) { 05478 struct ast_channel *owner; 05479 05480 sig_pri_lock_owner(pri, chanpos); 05481 owner = pri->pvts[chanpos]->owner; 05482 if (owner) { 05483 pbx_builtin_setvar_helper(owner, "USERUSERINFO", 05484 e->hangup.useruserinfo); 05485 ast_channel_unlock(owner); 05486 } 05487 } 05488 #endif 05489 05490 sig_pri_unlock_private(pri->pvts[chanpos]); 05491 } else { 05492 /* 05493 * Continue hanging up the call even though 05494 * we do not remember it (if we ever did). 05495 */ 05496 pri_hangup(pri->pri, e->hangup.call, e->hangup.cause); 05497 } 05498 } 05499 break; 05500 case PRI_EVENT_HANGUP_REQ: 05501 if (sig_pri_is_cis_call(e->hangup.channel)) { 05502 sig_pri_handle_cis_subcmds(pri, e->e, e->hangup.subcmds, 05503 e->hangup.call); 05504 pri_hangup(pri->pri, e->hangup.call, e->hangup.cause); 05505 break; 05506 } 05507 chanpos = pri_find_principle(pri, e->hangup.channel, e->hangup.call); 05508 if (chanpos < 0) { 05509 ast_log(LOG_WARNING, "Hangup REQ requested on unconfigured channel %d/%d span %d\n", 05510 PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span); 05511 /* 05512 * Continue hanging up the call even though 05513 * it is on an unconfigured channel. 05514 */ 05515 pri_hangup(pri->pri, e->hangup.call, e->hangup.cause); 05516 } else { 05517 chanpos = pri_fixup_principle(pri, chanpos, e->hangup.call); 05518 if (chanpos > -1) { 05519 sig_pri_lock_private(pri->pvts[chanpos]); 05520 sig_pri_handle_subcmds(pri, chanpos, e->e, e->hangup.channel, 05521 e->hangup.subcmds, e->hangup.call); 05522 #if defined(HAVE_PRI_CALL_HOLD) 05523 if (e->hangup.call_active && e->hangup.call_held 05524 && pri->hold_disconnect_transfer) { 05525 /* We are to transfer the call instead of simply hanging up. */ 05526 sig_pri_unlock_private(pri->pvts[chanpos]); 05527 if (!sig_pri_attempt_transfer(pri, e->hangup.call_held, 1, 05528 e->hangup.call_active, 0, NULL, NULL)) { 05529 break; 05530 } 05531 sig_pri_lock_private(pri->pvts[chanpos]); 05532 } 05533 #endif /* defined(HAVE_PRI_CALL_HOLD) */ 05534 switch (e->hangup.cause) { 05535 case PRI_CAUSE_USER_BUSY: 05536 case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION: 05537 sig_pri_cc_generic_check(pri, chanpos, AST_CC_CCBS); 05538 break; 05539 default: 05540 break; 05541 } 05542 if (pri->pvts[chanpos]->owner) { 05543 int do_hangup = 0; 05544 05545 pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause; 05546 switch (pri->pvts[chanpos]->owner->_state) { 05547 case AST_STATE_BUSY: 05548 case AST_STATE_UP: 05549 do_hangup = 1; 05550 break; 05551 default: 05552 if (!pri->pvts[chanpos]->outgoing) { 05553 /* 05554 * The incoming call leg hung up before getting 05555 * connected so just hangup the call. 05556 */ 05557 do_hangup = 1; 05558 break; 05559 } 05560 switch (e->hangup.cause) { 05561 case PRI_CAUSE_USER_BUSY: 05562 pri_queue_control(pri, chanpos, AST_CONTROL_BUSY); 05563 break; 05564 case PRI_CAUSE_CALL_REJECTED: 05565 case PRI_CAUSE_NETWORK_OUT_OF_ORDER: 05566 case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION: 05567 case PRI_CAUSE_SWITCH_CONGESTION: 05568 case PRI_CAUSE_DESTINATION_OUT_OF_ORDER: 05569 case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE: 05570 pri_queue_control(pri, chanpos, AST_CONTROL_CONGESTION); 05571 break; 05572 default: 05573 do_hangup = 1; 05574 break; 05575 } 05576 break; 05577 } 05578 05579 if (do_hangup) { 05580 #if defined(HAVE_PRI_AOC_EVENTS) 05581 if (!pri->pvts[chanpos]->holding_aoce 05582 && pri->aoce_delayhangup 05583 && ast_bridged_channel(pri->pvts[chanpos]->owner)) { 05584 sig_pri_send_aoce_termination_request(pri, chanpos, 05585 pri_get_timer(pri->pri, PRI_TIMER_T305) / 2); 05586 } else if (detect_aoc_e_subcmd(e->hangup.subcmds)) { 05587 /* If a AOC-E msg was sent during the Disconnect, we must use a AST_CONTROL_HANGUP frame 05588 * to guarantee that frame gets read before hangup */ 05589 pri_queue_control(pri, chanpos, AST_CONTROL_HANGUP); 05590 } else { 05591 pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV; 05592 } 05593 #else 05594 pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV; 05595 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 05596 } 05597 ast_verb(3, "Channel %d/%d, span %d got hangup request, cause %d\n", 05598 PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span, e->hangup.cause); 05599 } else { 05600 /* 05601 * Continue hanging up the call even though 05602 * we do not have an owner. 05603 */ 05604 pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause); 05605 pri->pvts[chanpos]->call = NULL; 05606 } 05607 if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL) { 05608 ast_verb(3, "Forcing restart of channel %d/%d span %d since channel reported in use\n", 05609 PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span); 05610 pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos])); 05611 pri->pvts[chanpos]->resetting = 1; 05612 } 05613 05614 #ifdef SUPPORT_USERUSER 05615 if (!ast_strlen_zero(e->hangup.useruserinfo)) { 05616 struct ast_channel *owner; 05617 05618 sig_pri_lock_owner(pri, chanpos); 05619 owner = pri->pvts[chanpos]->owner; 05620 if (owner) { 05621 pbx_builtin_setvar_helper(owner, "USERUSERINFO", 05622 e->hangup.useruserinfo); 05623 ast_channel_unlock(owner); 05624 } 05625 } 05626 #endif 05627 05628 sig_pri_unlock_private(pri->pvts[chanpos]); 05629 } else { 05630 /* 05631 * Continue hanging up the call even though 05632 * we do not remember it (if we ever did). 05633 */ 05634 pri_hangup(pri->pri, e->hangup.call, e->hangup.cause); 05635 } 05636 } 05637 break; 05638 case PRI_EVENT_HANGUP_ACK: 05639 if (sig_pri_is_cis_call(e->hangup.channel)) { 05640 sig_pri_handle_cis_subcmds(pri, e->e, e->hangup.subcmds, 05641 e->hangup.call); 05642 break; 05643 } 05644 chanpos = pri_find_principle(pri, e->hangup.channel, e->hangup.call); 05645 if (chanpos < 0) { 05646 ast_log(LOG_WARNING, "Hangup ACK requested on unconfigured channel number %d/%d span %d\n", 05647 PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span); 05648 } else { 05649 chanpos = pri_fixup_principle(pri, chanpos, e->hangup.call); 05650 if (chanpos > -1) { 05651 sig_pri_lock_private(pri->pvts[chanpos]); 05652 pri->pvts[chanpos]->call = NULL; 05653 pri->pvts[chanpos]->resetting = 0; 05654 if (pri->pvts[chanpos]->owner) { 05655 ast_verb(3, "Channel %d/%d, span %d got hangup ACK\n", PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span); 05656 } 05657 #ifdef SUPPORT_USERUSER 05658 if (!ast_strlen_zero(e->hangup.useruserinfo)) { 05659 struct ast_channel *owner; 05660 05661 sig_pri_lock_owner(pri, chanpos); 05662 owner = pri->pvts[chanpos]->owner; 05663 if (owner) { 05664 pbx_builtin_setvar_helper(owner, "USERUSERINFO", 05665 e->hangup.useruserinfo); 05666 ast_channel_unlock(owner); 05667 } 05668 } 05669 #endif 05670 sig_pri_unlock_private(pri->pvts[chanpos]); 05671 } 05672 } 05673 break; 05674 case PRI_EVENT_CONFIG_ERR: 05675 ast_log(LOG_WARNING, "PRI Error on span %d: %s\n", pri->span, e->err.err); 05676 break; 05677 case PRI_EVENT_RESTART_ACK: 05678 chanpos = pri_find_principle(pri, e->restartack.channel, NULL); 05679 if (chanpos < 0) { 05680 /* Sometime switches (e.g. I421 / British Telecom) don't give us the 05681 channel number, so we have to figure it out... This must be why 05682 everybody resets exactly a channel at a time. */ 05683 for (x = 0; x < pri->numchans; x++) { 05684 if (pri->pvts[x] && pri->pvts[x]->resetting) { 05685 chanpos = x; 05686 sig_pri_lock_private(pri->pvts[chanpos]); 05687 ast_debug(1, "Assuming restart ack is really for channel %d/%d span %d\n", pri->pvts[chanpos]->logicalspan, 05688 pri->pvts[chanpos]->prioffset, pri->span); 05689 if (pri->pvts[chanpos]->owner) { 05690 ast_log(LOG_WARNING, "Got restart ack on channel %d/%d with owner on span %d\n", pri->pvts[chanpos]->logicalspan, 05691 pri->pvts[chanpos]->prioffset, pri->span); 05692 pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV; 05693 } 05694 pri->pvts[chanpos]->resetting = 0; 05695 ast_verb(3, "B-channel %d/%d successfully restarted on span %d\n", pri->pvts[chanpos]->logicalspan, 05696 pri->pvts[chanpos]->prioffset, pri->span); 05697 sig_pri_unlock_private(pri->pvts[chanpos]); 05698 if (pri->resetting) 05699 pri_check_restart(pri); 05700 break; 05701 } 05702 } 05703 if (chanpos < 0) { 05704 ast_log(LOG_WARNING, "Restart ACK requested on strange channel %d/%d span %d\n", 05705 PRI_SPAN(e->restartack.channel), PRI_CHANNEL(e->restartack.channel), pri->span); 05706 } 05707 } else { 05708 if (pri->pvts[chanpos]) { 05709 sig_pri_lock_private(pri->pvts[chanpos]); 05710 if (pri->pvts[chanpos]->owner) { 05711 ast_log(LOG_WARNING, "Got restart ack on channel %d/%d span %d with owner\n", 05712 PRI_SPAN(e->restartack.channel), PRI_CHANNEL(e->restartack.channel), pri->span); 05713 pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV; 05714 } 05715 pri->pvts[chanpos]->resetting = 0; 05716 ast_verb(3, "B-channel %d/%d successfully restarted on span %d\n", pri->pvts[chanpos]->logicalspan, 05717 pri->pvts[chanpos]->prioffset, pri->span); 05718 sig_pri_unlock_private(pri->pvts[chanpos]); 05719 if (pri->resetting) 05720 pri_check_restart(pri); 05721 } 05722 } 05723 break; 05724 case PRI_EVENT_SETUP_ACK: 05725 if (sig_pri_is_cis_call(e->setup_ack.channel)) { 05726 sig_pri_handle_cis_subcmds(pri, e->e, e->setup_ack.subcmds, 05727 e->setup_ack.call); 05728 break; 05729 } 05730 chanpos = pri_find_principle(pri, e->setup_ack.channel, e->setup_ack.call); 05731 if (chanpos < 0) { 05732 ast_log(LOG_WARNING, "Received SETUP_ACKNOWLEDGE on unconfigured channel %d/%d span %d\n", 05733 PRI_SPAN(e->setup_ack.channel), PRI_CHANNEL(e->setup_ack.channel), pri->span); 05734 } else { 05735 chanpos = pri_fixup_principle(pri, chanpos, e->setup_ack.call); 05736 if (chanpos > -1) { 05737 sig_pri_lock_private(pri->pvts[chanpos]); 05738 sig_pri_handle_subcmds(pri, chanpos, e->e, e->setup_ack.channel, 05739 e->setup_ack.subcmds, e->setup_ack.call); 05740 pri->pvts[chanpos]->setup_ack = 1; 05741 /* Send any queued digits */ 05742 for (x = 0;x < strlen(pri->pvts[chanpos]->dialdest); x++) { 05743 ast_debug(1, "Sending pending digit '%c'\n", pri->pvts[chanpos]->dialdest[x]); 05744 pri_information(pri->pri, pri->pvts[chanpos]->call, 05745 pri->pvts[chanpos]->dialdest[x]); 05746 } 05747 sig_pri_unlock_private(pri->pvts[chanpos]); 05748 } else 05749 ast_log(LOG_WARNING, "Unable to move channel %d!\n", e->setup_ack.channel); 05750 } 05751 break; 05752 case PRI_EVENT_NOTIFY: 05753 if (sig_pri_is_cis_call(e->notify.channel)) { 05754 #if defined(HAVE_PRI_CALL_HOLD) 05755 sig_pri_handle_cis_subcmds(pri, e->e, e->notify.subcmds, 05756 e->notify.call); 05757 #else 05758 sig_pri_handle_cis_subcmds(pri, e->e, e->notify.subcmds, NULL); 05759 #endif /* !defined(HAVE_PRI_CALL_HOLD) */ 05760 break; 05761 } 05762 #if defined(HAVE_PRI_CALL_HOLD) 05763 chanpos = pri_find_principle(pri, e->notify.channel, e->notify.call); 05764 #else 05765 chanpos = pri_find_principle(pri, e->notify.channel, NULL); 05766 #endif /* !defined(HAVE_PRI_CALL_HOLD) */ 05767 if (chanpos < 0) { 05768 ast_log(LOG_WARNING, "Received NOTIFY on unconfigured channel %d/%d span %d\n", 05769 PRI_SPAN(e->notify.channel), PRI_CHANNEL(e->notify.channel), pri->span); 05770 } else { 05771 sig_pri_lock_private(pri->pvts[chanpos]); 05772 #if defined(HAVE_PRI_CALL_HOLD) 05773 sig_pri_handle_subcmds(pri, chanpos, e->e, e->notify.channel, 05774 e->notify.subcmds, e->notify.call); 05775 #else 05776 sig_pri_handle_subcmds(pri, chanpos, e->e, e->notify.channel, 05777 e->notify.subcmds, NULL); 05778 #endif /* !defined(HAVE_PRI_CALL_HOLD) */ 05779 switch (e->notify.info) { 05780 case PRI_NOTIFY_REMOTE_HOLD: 05781 if (!pri->discardremoteholdretrieval) { 05782 pri_queue_control(pri, chanpos, AST_CONTROL_HOLD); 05783 } 05784 break; 05785 case PRI_NOTIFY_REMOTE_RETRIEVAL: 05786 if (!pri->discardremoteholdretrieval) { 05787 pri_queue_control(pri, chanpos, AST_CONTROL_UNHOLD); 05788 } 05789 break; 05790 } 05791 sig_pri_unlock_private(pri->pvts[chanpos]); 05792 } 05793 break; 05794 #if defined(HAVE_PRI_CALL_HOLD) 05795 case PRI_EVENT_HOLD: 05796 /* We should not be getting any CIS calls with this message type. */ 05797 if (sig_pri_handle_hold(pri, e)) { 05798 pri_hold_rej(pri->pri, e->hold.call, 05799 PRI_CAUSE_RESOURCE_UNAVAIL_UNSPECIFIED); 05800 } else { 05801 pri_hold_ack(pri->pri, e->hold.call); 05802 } 05803 break; 05804 #endif /* defined(HAVE_PRI_CALL_HOLD) */ 05805 #if defined(HAVE_PRI_CALL_HOLD) 05806 case PRI_EVENT_HOLD_ACK: 05807 ast_debug(1, "Event: HOLD_ACK\n"); 05808 break; 05809 #endif /* defined(HAVE_PRI_CALL_HOLD) */ 05810 #if defined(HAVE_PRI_CALL_HOLD) 05811 case PRI_EVENT_HOLD_REJ: 05812 ast_debug(1, "Event: HOLD_REJ\n"); 05813 break; 05814 #endif /* defined(HAVE_PRI_CALL_HOLD) */ 05815 #if defined(HAVE_PRI_CALL_HOLD) 05816 case PRI_EVENT_RETRIEVE: 05817 /* We should not be getting any CIS calls with this message type. */ 05818 sig_pri_handle_retrieve(pri, e); 05819 break; 05820 #endif /* defined(HAVE_PRI_CALL_HOLD) */ 05821 #if defined(HAVE_PRI_CALL_HOLD) 05822 case PRI_EVENT_RETRIEVE_ACK: 05823 ast_debug(1, "Event: RETRIEVE_ACK\n"); 05824 break; 05825 #endif /* defined(HAVE_PRI_CALL_HOLD) */ 05826 #if defined(HAVE_PRI_CALL_HOLD) 05827 case PRI_EVENT_RETRIEVE_REJ: 05828 ast_debug(1, "Event: RETRIEVE_REJ\n"); 05829 break; 05830 #endif /* defined(HAVE_PRI_CALL_HOLD) */ 05831 default: 05832 ast_debug(1, "Event: %d\n", e->e); 05833 break; 05834 } 05835 } 05836 ast_mutex_unlock(&pri->lock); 05837 } 05838 /* Never reached */ 05839 return NULL; 05840 }
void pri_event_alarm | ( | struct sig_pri_span * | pri, | |
int | index, | |||
int | before_start_pri | |||
) |
Definition at line 1671 of file sig_pri.c.
References DCHAN_NOTINALARM, DCHAN_UP, sig_pri_span::dchanavail, and pri_find_dchan().
Referenced by my_handle_dchan_exception(), and prepare_pri().
01672 { 01673 pri->dchanavail[index] &= ~(DCHAN_NOTINALARM | DCHAN_UP); 01674 if (!before_start_pri) 01675 pri_find_dchan(pri); 01676 }
void pri_event_noalarm | ( | struct sig_pri_span * | pri, | |
int | index, | |||
int | before_start_pri | |||
) |
Definition at line 1678 of file sig_pri.c.
References DCHAN_NOTINALARM, sig_pri_span::dchanavail, and sig_pri_span::dchans.
Referenced by my_handle_dchan_exception(), and prepare_pri().
01679 { 01680 pri->dchanavail[index] |= DCHAN_NOTINALARM; 01681 if (!before_start_pri) 01682 pri_restart(pri->dchans[index]); 01683 }
static int pri_find_dchan | ( | struct sig_pri_span * | pri | ) | [static] |
Definition at line 966 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().
00967 { 00968 int oldslot = -1; 00969 struct pri *old; 00970 int newslot = -1; 00971 int x; 00972 old = pri->pri; 00973 for (x = 0; x < SIG_PRI_NUM_DCHANS; x++) { 00974 if ((pri->dchanavail[x] == DCHAN_AVAILABLE) && (newslot < 0)) 00975 newslot = x; 00976 if (pri->dchans[x] == old) { 00977 oldslot = x; 00978 } 00979 } 00980 if (newslot < 0) { 00981 newslot = 0; 00982 /* This is annoying to see on non persistent layer 2 connections. Let's not complain in that case */ 00983 if (pri->sig != SIG_BRI_PTMP && !pri->no_d_channels) { 00984 pri->no_d_channels = 1; 00985 ast_log(LOG_WARNING, 00986 "Span %d: No D-channels available! Using Primary channel as D-channel anyway!\n", 00987 pri->span); 00988 } 00989 } else { 00990 pri->no_d_channels = 0; 00991 } 00992 if (old && (oldslot != newslot)) 00993 ast_log(LOG_NOTICE, "Switching from d-channel fd %d to fd %d!\n", 00994 pri->fds[oldslot], pri->fds[newslot]); 00995 pri->pri = pri->dchans[newslot]; 00996 return 0; 00997 }
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 1093 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().
01094 { 01095 int x; 01096 int span; 01097 int principle; 01098 int prioffset; 01099 01100 if (channel < 0) { 01101 /* Channel is not picked yet. */ 01102 return -1; 01103 } 01104 01105 prioffset = PRI_CHANNEL(channel); 01106 if (!prioffset || (channel & PRI_HELD_CALL)) { 01107 if (!call) { 01108 /* Cannot find a call waiting call or held call without a call. */ 01109 return -1; 01110 } 01111 principle = -1; 01112 for (x = 0; x < pri->numchans; ++x) { 01113 if (pri->pvts[x] 01114 && pri->pvts[x]->call == call) { 01115 principle = x; 01116 break; 01117 } 01118 } 01119 return principle; 01120 } 01121 01122 span = PRI_SPAN(channel); 01123 if (!(channel & PRI_EXPLICIT)) { 01124 int index; 01125 01126 index = pri_active_dchan_index(pri); 01127 if (index == -1) { 01128 return -1; 01129 } 01130 span = pri->dchan_logical_span[index]; 01131 } 01132 01133 principle = -1; 01134 for (x = 0; x < pri->numchans; x++) { 01135 if (pri->pvts[x] 01136 && pri->pvts[x]->prioffset == prioffset 01137 && pri->pvts[x]->logicalspan == span 01138 && !pri->pvts[x]->no_b_channel) { 01139 principle = x; 01140 break; 01141 } 01142 } 01143 01144 return principle; 01145 }
static int pri_fixup_principle | ( | struct sig_pri_span * | pri, | |
int | principle, | |||
q931_call * | call | |||
) | [static] |
Definition at line 1160 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_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().
01161 { 01162 int x; 01163 01164 if (principle < 0 || pri->numchans <= principle) { 01165 /* Out of rannge */ 01166 return -1; 01167 } 01168 if (!call) { 01169 /* No call */ 01170 return principle; 01171 } 01172 if (pri->pvts[principle] && pri->pvts[principle]->call == call) { 01173 /* Call is already on the specified principle. */ 01174 return principle; 01175 } 01176 01177 /* Find the old principle location. */ 01178 for (x = 0; x < pri->numchans; x++) { 01179 struct sig_pri_chan *new_chan; 01180 struct sig_pri_chan *old_chan; 01181 01182 if (!pri->pvts[x] || pri->pvts[x]->call != call) { 01183 continue; 01184 } 01185 01186 /* Found our call */ 01187 new_chan = pri->pvts[principle]; 01188 old_chan = pri->pvts[x]; 01189 01190 /* Get locks to safely move to the new private structure. */ 01191 sig_pri_lock_private(old_chan); 01192 sig_pri_lock_owner(pri, x); 01193 sig_pri_lock_private(new_chan); 01194 01195 ast_verb(3, "Moving call (%s) from channel %d to %d.\n", 01196 old_chan->owner ? old_chan->owner->name : "", 01197 old_chan->channel, new_chan->channel); 01198 if (new_chan->owner) { 01199 ast_log(LOG_WARNING, 01200 "Can't move call (%s) from channel %d to %d. It is already in use.\n", 01201 old_chan->owner ? old_chan->owner->name : "", 01202 old_chan->channel, new_chan->channel); 01203 sig_pri_unlock_private(new_chan); 01204 if (old_chan->owner) { 01205 ast_channel_unlock(old_chan->owner); 01206 } 01207 sig_pri_unlock_private(old_chan); 01208 return -1; 01209 } 01210 01211 sig_pri_fixup_chans(old_chan, new_chan); 01212 01213 /* Fix it all up now */ 01214 new_chan->owner = old_chan->owner; 01215 old_chan->owner = NULL; 01216 01217 new_chan->call = old_chan->call; 01218 old_chan->call = NULL; 01219 01220 /* Transfer flags from the old channel. */ 01221 #if defined(HAVE_PRI_AOC_EVENTS) 01222 new_chan->aoc_s_request_invoke_id_valid = old_chan->aoc_s_request_invoke_id_valid; 01223 new_chan->waiting_for_aoce = old_chan->waiting_for_aoce; 01224 new_chan->holding_aoce = old_chan->holding_aoce; 01225 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 01226 new_chan->alerting = old_chan->alerting; 01227 new_chan->alreadyhungup = old_chan->alreadyhungup; 01228 new_chan->isidlecall = old_chan->isidlecall; 01229 new_chan->proceeding = old_chan->proceeding; 01230 new_chan->progress = old_chan->progress; 01231 new_chan->setup_ack = old_chan->setup_ack; 01232 new_chan->outgoing = old_chan->outgoing; 01233 new_chan->digital = old_chan->digital; 01234 #if defined(HAVE_PRI_CALL_WAITING) 01235 new_chan->is_call_waiting = old_chan->is_call_waiting; 01236 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 01237 01238 #if defined(HAVE_PRI_AOC_EVENTS) 01239 old_chan->aoc_s_request_invoke_id_valid = 0; 01240 old_chan->waiting_for_aoce = 0; 01241 old_chan->holding_aoce = 0; 01242 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 01243 old_chan->alerting = 0; 01244 old_chan->alreadyhungup = 0; 01245 old_chan->isidlecall = 0; 01246 old_chan->proceeding = 0; 01247 old_chan->progress = 0; 01248 old_chan->setup_ack = 0; 01249 old_chan->outgoing = 0; 01250 old_chan->digital = 0; 01251 #if defined(HAVE_PRI_CALL_WAITING) 01252 old_chan->is_call_waiting = 0; 01253 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 01254 01255 /* More stuff to transfer to the new channel. */ 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 926 of file sig_pri.c.
References DCHAN_AVAILABLE, sig_pri_span::dchanavail, and SIG_PRI_NUM_DCHANS.
Referenced by pri_dchannel().
00927 { 00928 int x; 00929 for (x = 0; x < SIG_PRI_NUM_DCHANS; x++) { 00930 if (pri->dchanavail[x] == DCHAN_AVAILABLE) 00931 return 1; 00932 } 00933 return 0; 00934 }
int pri_maintenance_bservice | ( | struct pri * | pri, | |
struct sig_pri_chan * | p, | |||
int | changestatus | |||
) |
Definition at line 7358 of file sig_pri.c.
References sig_pri_chan::channel, PRI_SPAN, and PVT_TO_CHANNEL().
07359 { 07360 int channel = PVT_TO_CHANNEL(p); 07361 int span = PRI_SPAN(channel); 07362 07363 return pri_maintenance_service(pri, span, channel, changestatus); 07364 }
static char* pri_order | ( | int | level | ) | [static] |
Definition at line 936 of file sig_pri.c.
Referenced by pri_dchannel(), and sig_pri_cli_show_span().
00937 { 00938 switch (level) { 00939 case 0: 00940 return "Primary"; 00941 case 1: 00942 return "Secondary"; 00943 case 2: 00944 return "Tertiary"; 00945 case 3: 00946 return "Quaternary"; 00947 default: 00948 return "<Unknown>"; 00949 } 00950 }
static void pri_queue_control | ( | struct sig_pri_span * | pri, | |
int | chanpos, | |||
int | subclass | |||
) | [static] |
Definition at line 1067 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().
01068 { 01069 struct ast_frame f = {AST_FRAME_CONTROL, }; 01070 struct sig_pri_chan *p = pri->pvts[chanpos]; 01071 01072 if (p->calls->queue_control) { 01073 p->calls->queue_control(p->chan_pvt, subclass); 01074 } 01075 01076 f.subclass.integer = subclass; 01077 pri_queue_frame(pri, chanpos, &f); 01078 }
static void pri_queue_frame | ( | struct sig_pri_span * | pri, | |
int | chanpos, | |||
struct ast_frame * | frame | |||
) | [static] |
Definition at line 1044 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().
01045 { 01046 sig_pri_lock_owner(pri, chanpos); 01047 if (pri->pvts[chanpos]->owner) { 01048 ast_queue_frame(pri->pvts[chanpos]->owner, frame); 01049 ast_channel_unlock(pri->pvts[chanpos]->owner); 01050 } 01051 }
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 7333 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().
07334 { 07335 int res = -1; 07336 07337 sig_pri_lock_private(p); 07338 07339 if (!p->pri || !p->call) { 07340 ast_log(LOG_DEBUG, "Unable to find pri or call on channel!\n"); 07341 sig_pri_unlock_private(p); 07342 return -1; 07343 } 07344 07345 if (!pri_grab(p, p->pri)) { 07346 res = pri_callrerouting_facility(p->pri->pri, p->call, destination, original, reason); 07347 pri_rel(p->pri); 07348 } else { 07349 ast_log(LOG_DEBUG, "Unable to grab pri to send callrerouting facility on span %d!\n", p->pri->span); 07350 } 07351 07352 sig_pri_unlock_private(p); 07353 07354 return res; 07355 }
int pri_send_keypad_facility_exec | ( | struct sig_pri_chan * | p, | |
const char * | digits | |||
) |
Definition at line 7309 of file sig_pri.c.
References ast_debug, sig_pri_chan::call, sig_pri_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().
07310 { 07311 sig_pri_lock_private(p); 07312 07313 if (!p->pri || !p->call) { 07314 ast_debug(1, "Unable to find pri or call on channel!\n"); 07315 sig_pri_unlock_private(p); 07316 return -1; 07317 } 07318 07319 if (!pri_grab(p, p->pri)) { 07320 pri_keypad_facility(p->pri->pri, p->call, digits); 07321 pri_rel(p->pri); 07322 } else { 07323 ast_debug(1, "Unable to grab pri to send keypad facility!\n"); 07324 sig_pri_unlock_private(p); 07325 return -1; 07326 } 07327 07328 sig_pri_unlock_private(p); 07329 07330 return 0; 07331 }
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, 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_chan::pri, pri_gendigittimeout, pri_grab(), pri_matchdigittimeout, pri_rel(), PVT_TO_CHANNEL(), 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(), 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 (p->pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING) { 01641 sig_pri_lock_private(p); 01642 if (p->pri->pri) { 01643 if (!pri_grab(p, p->pri)) { 01644 pri_proceeding(p->pri->pri, p->call, PVT_TO_CHANNEL(p), 0); 01645 p->proceeding = 1; 01646 pri_rel(p->pri); 01647 } else { 01648 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->pri->span); 01649 } 01650 } 01651 sig_pri_unlock_private(p); 01652 } 01653 01654 sig_pri_set_echocanceller(p, 1); 01655 ast_setstate(chan, AST_STATE_RING); 01656 res = ast_pbx_run(chan); 01657 if (res) { 01658 ast_log(LOG_WARNING, "PBX exited non-zero!\n"); 01659 } 01660 } else { 01661 ast_log(LOG_DEBUG, "No such possible extension '%s' in context '%s'\n", exten, chan->context); 01662 chan->hangupcause = AST_CAUSE_UNALLOCATED; 01663 ast_hangup(chan); 01664 p->exten[0] = '\0'; 01665 /* Since we send release complete here, we won't get one */ 01666 p->call = NULL; 01667 } 01668 return NULL; 01669 }
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 6677 of file sig_pri.c.
References ast_setstate(), AST_STATE_UP, sig_pri_chan::call, sig_pri_chan::digital, sig_pri_chan::pri, sig_pri_span::pri, pri_grab(), pri_rel(), sig_pri_chan::proceeding, sig_pri_open_media(), and sig_pri_set_dialing().
Referenced by dahdi_answer().
06678 { 06679 int res = 0; 06680 /* Send a pri acknowledge */ 06681 if (!pri_grab(p, p->pri)) { 06682 #if defined(HAVE_PRI_AOC_EVENTS) 06683 if (p->aoc_s_request_invoke_id_valid) { 06684 /* if AOC-S was requested and the invoke id is still present on answer. That means 06685 * no AOC-S rate list was provided, so send a NULL response which will indicate that 06686 * AOC-S is not available */ 06687 pri_aoc_s_request_response_send(p->pri->pri, p->call, 06688 p->aoc_s_request_invoke_id, NULL); 06689 p->aoc_s_request_invoke_id_valid = 0; 06690 } 06691 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 06692 p->proceeding = 1; 06693 sig_pri_set_dialing(p, 0); 06694 sig_pri_open_media(p); 06695 res = pri_answer(p->pri->pri, p->call, 0, !p->digital); 06696 pri_rel(p->pri); 06697 } else { 06698 res = -1; 06699 } 06700 ast_setstate(ast, AST_STATE_UP); 06701 return res; 06702 }
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 2002 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().
02003 { 02004 struct attempt_xfer_call { 02005 q931_call *pri; 02006 struct ast_channel *ast; 02007 int held; 02008 int chanpos; 02009 }; 02010 int retval; 02011 struct ast_channel *transferee; 02012 struct attempt_xfer_call *call_1; 02013 struct attempt_xfer_call *call_2; 02014 struct attempt_xfer_call *swap_call; 02015 struct attempt_xfer_call c1; 02016 struct attempt_xfer_call c2; 02017 02018 c1.pri = call_1_pri; 02019 c1.held = call_1_held; 02020 call_1 = &c1; 02021 02022 c2.pri = call_2_pri; 02023 c2.held = call_2_held; 02024 call_2 = &c2; 02025 02026 call_1->chanpos = pri_find_pri_call(pri, call_1->pri); 02027 call_2->chanpos = pri_find_pri_call(pri, call_2->pri); 02028 if (call_1->chanpos < 0 || call_2->chanpos < 0) { 02029 /* Calls not found in span control. */ 02030 if (rsp_callback) { 02031 /* Transfer failed. */ 02032 rsp_callback(data, 0); 02033 } 02034 return -1; 02035 } 02036 02037 /* Attempt to make transferee and target consistent. */ 02038 if (!call_1->held && call_2->held) { 02039 /* 02040 * Swap call_1 and call_2 to make call_1 the transferee(held call) 02041 * and call_2 the target(active call). 02042 */ 02043 swap_call = call_1; 02044 call_1 = call_2; 02045 call_2 = swap_call; 02046 } 02047 02048 /* Deadlock avoidance is attempted. */ 02049 sig_pri_lock_private(pri->pvts[call_1->chanpos]); 02050 sig_pri_lock_owner(pri, call_1->chanpos); 02051 sig_pri_lock_private(pri->pvts[call_2->chanpos]); 02052 sig_pri_lock_owner(pri, call_2->chanpos); 02053 02054 call_1->ast = pri->pvts[call_1->chanpos]->owner; 02055 call_2->ast = pri->pvts[call_2->chanpos]->owner; 02056 if (!call_1->ast || !call_2->ast) { 02057 /* At least one owner is not present. */ 02058 if (call_1->ast) { 02059 ast_channel_unlock(call_1->ast); 02060 } 02061 if (call_2->ast) { 02062 ast_channel_unlock(call_2->ast); 02063 } 02064 sig_pri_unlock_private(pri->pvts[call_1->chanpos]); 02065 sig_pri_unlock_private(pri->pvts[call_2->chanpos]); 02066 if (rsp_callback) { 02067 /* Transfer failed. */ 02068 rsp_callback(data, 0); 02069 } 02070 return -1; 02071 } 02072 02073 for (;;) { 02074 transferee = ast_bridged_channel(call_1->ast); 02075 if (transferee) { 02076 break; 02077 } 02078 02079 /* Try masquerading the other way. */ 02080 swap_call = call_1; 02081 call_1 = call_2; 02082 call_2 = swap_call; 02083 02084 transferee = ast_bridged_channel(call_1->ast); 02085 if (transferee) { 02086 break; 02087 } 02088 02089 /* Could not transfer. Neither call is bridged. */ 02090 ast_channel_unlock(call_1->ast); 02091 ast_channel_unlock(call_2->ast); 02092 sig_pri_unlock_private(pri->pvts[call_1->chanpos]); 02093 sig_pri_unlock_private(pri->pvts[call_2->chanpos]); 02094 02095 if (rsp_callback) { 02096 /* Transfer failed. */ 02097 rsp_callback(data, 0); 02098 } 02099 return -1; 02100 } 02101 02102 ast_verb(3, "TRANSFERRING %s to %s\n", call_1->ast->name, call_2->ast->name); 02103 02104 /* 02105 * Setup transfer masquerade. 02106 * 02107 * Note: There is an extremely nasty deadlock avoidance issue 02108 * with ast_channel_transfer_masquerade(). Deadlock may be possible if 02109 * the channels involved are proxies (chan_agent channels) and 02110 * it is called with locks. Unfortunately, there is no simple 02111 * or even merely difficult way to guarantee deadlock avoidance 02112 * and still be able to send an ECT success response without the 02113 * possibility of the bridged channel hanging up on us. 02114 */ 02115 ast_mutex_unlock(&pri->lock); 02116 retval = ast_channel_transfer_masquerade( 02117 call_2->ast, 02118 &call_2->ast->connected, 02119 call_2->held, 02120 transferee, 02121 &call_1->ast->connected, 02122 call_1->held); 02123 02124 /* Reacquire the pri->lock to hold off completion of the transfer masquerade. */ 02125 ast_mutex_lock(&pri->lock); 02126 02127 ast_channel_unlock(call_1->ast); 02128 ast_channel_unlock(call_2->ast); 02129 sig_pri_unlock_private(pri->pvts[call_1->chanpos]); 02130 sig_pri_unlock_private(pri->pvts[call_2->chanpos]); 02131 02132 if (rsp_callback) { 02133 /* 02134 * Report transfer status. 02135 * 02136 * Must do the callback before the masquerade completes to ensure 02137 * that the protocol message goes out before the call leg is 02138 * disconnected. 02139 */ 02140 rsp_callback(data, retval ? 0 : 1); 02141 } 02142 return retval; 02143 }
int sig_pri_available | ( | struct sig_pri_chan ** | pvt, | |
int | is_specific_channel | |||
) |
Definition at line 6779 of file sig_pri.c.
References sig_pri_chan::pri, and sig_pri_available_check().
Referenced by available().
06780 { 06781 struct sig_pri_chan *p = *pvt; 06782 06783 if (!p->pri) { 06784 /* Something is wrong here. A PRI channel without the pri pointer? */ 06785 return 0; 06786 } 06787 06788 if ( 06789 #if defined(HAVE_PRI_CALL_WAITING) 06790 /* 06791 * Only do call waiting calls if we have any 06792 * call waiting call outstanding. We do not 06793 * want new calls to steal a B channel 06794 * freed for an earlier call waiting call. 06795 */ 06796 !p->pri->num_call_waiting_calls && 06797 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 06798 sig_pri_available_check(p)) { 06799 return 1; 06800 } 06801 06802 #if defined(HAVE_PRI_CALL_WAITING) 06803 if (!is_specific_channel) { 06804 struct sig_pri_chan *cw; 06805 06806 cw = sig_pri_cw_available(p->pri); 06807 if (cw) { 06808 /* We have a call waiting interface to use instead. */ 06809 *pvt = cw; 06810 return 1; 06811 } 06812 } 06813 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 06814 return 0; 06815 }
static int sig_pri_available_check | ( | struct sig_pri_chan * | pvt | ) | [static] |
Definition at line 6714 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().
06715 { 06716 /* 06717 * If no owner, interface has a B channel, not resetting, not already with call, 06718 * not in alarm, and in-service then available. 06719 */ 06720 if (!pvt->owner && !pvt->no_b_channel && !pvt->resetting && !pvt->call 06721 && !pvt->inalarm) { 06722 #if defined(HAVE_PRI_SERVICE_MESSAGES) 06723 if (pvt->service_status) { 06724 return 0; 06725 } 06726 #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */ 06727 return 1; 06728 } 06729 return 0; 06730 }
int sig_pri_call | ( | struct sig_pri_chan * | p, | |
struct ast_channel * | ast, | |||
char * | rdest, | |||
int | timeout, | |||
int | layer1 | |||
) |
Definition at line 6036 of file sig_pri.c.
References ast_channel::_state, ao2_ref, sig_pri_span::append_msn_to_user_tag, args, AST_APP_ARG, ast_app_parse_options(), ast_assert, ast_cc_get_monitor_by_recall_core_id(), ast_cc_is_recall(), ast_channel_get_device_name(), AST_CHANNEL_NAME, ast_copy_string(), AST_DECLARE_APP_ARGS, ast_free, ast_log(), AST_NONSTANDARD_APP_ARGS, ast_party_subaddress_init(), ast_setstate(), AST_STATE_DIALING, AST_STATE_DOWN, AST_STATE_RESERVED, ast_strdup, ast_strlen_zero(), ast_test_flag, ast_transfercapability2str(), ast_verb, sig_pri_chan::call, ast_channel::caller, sig_pri_chan::channel, ast_channel::connected, sig_pri_chan::dialdest, sig_pri_span::dialplan, dialplan2str(), sig_pri_chan::digital, ext, sig_pri_span::facilityenable, sig_pri_chan::hidecallerid, sig_pri_chan::hidecalleridname, ast_party_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_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().
06037 { 06038 char dest[256]; /* must be same length as p->dialdest */ 06039 struct ast_party_subaddress dialed_subaddress; /* Called subaddress */ 06040 struct pri_sr *sr; 06041 char *c, *l, *n, *s; 06042 #ifdef SUPPORT_USERUSER 06043 const char *useruser; 06044 #endif 06045 int core_id; 06046 int pridialplan; 06047 int dp_strip; 06048 int prilocaldialplan; 06049 int ldp_strip; 06050 int exclusive; 06051 #if defined(HAVE_PRI_SETUP_KEYPAD) 06052 const char *keypad; 06053 #endif /* defined(HAVE_PRI_SETUP_KEYPAD) */ 06054 AST_DECLARE_APP_ARGS(args, 06055 AST_APP_ARG(group); /* channel/group token */ 06056 AST_APP_ARG(ext); /* extension token */ 06057 AST_APP_ARG(opts); /* options token */ 06058 AST_APP_ARG(other); /* Any remining unused arguments */ 06059 ); 06060 struct ast_flags opts; 06061 char *opt_args[OPT_ARG_ARRAY_SIZE]; 06062 06063 ast_log(LOG_DEBUG, "CALLER NAME: %s NUM: %s\n", 06064 S_COR(ast->connected.id.name.valid, ast->connected.id.name.str, ""), 06065 S_COR(ast->connected.id.number.valid, ast->connected.id.number.str, "")); 06066 06067 if (!p->pri) { 06068 ast_log(LOG_ERROR, "Could not find pri on channel %d\n", p->channel); 06069 return -1; 06070 } 06071 06072 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { 06073 ast_log(LOG_WARNING, "sig_pri_call called on %s, neither down nor reserved\n", ast->name); 06074 return -1; 06075 } 06076 06077 p->dialdest[0] = '\0'; 06078 p->outgoing = 1; 06079 06080 ast_copy_string(dest, rdest, sizeof(dest)); 06081 AST_NONSTANDARD_APP_ARGS(args, dest, '/'); 06082 if (ast_app_parse_options(sig_pri_call_opts, &opts, opt_args, args.opts)) { 06083 /* General invalid option syntax. */ 06084 return -1; 06085 } 06086 06087 c = args.ext; 06088 if (!c) { 06089 c = ""; 06090 } 06091 06092 /* setup dialed_subaddress if found */ 06093 ast_party_subaddress_init(&dialed_subaddress); 06094 s = strchr(c, ':'); 06095 if (s) { 06096 *s = '\0'; 06097 s++; 06098 /* prefix */ 06099 /* 'n' = NSAP */ 06100 /* 'U' = odd, 'u'= even */ 06101 /* Default = NSAP */ 06102 switch (*s) { 06103 case 'U': 06104 dialed_subaddress.odd_even_indicator = 1; 06105 /* fall through */ 06106 case 'u': 06107 s++; 06108 dialed_subaddress.type = 2; 06109 break; 06110 case 'N': 06111 case 'n': 06112 s++; 06113 /* default already covered with ast_party_subaddress_init */ 06114 break; 06115 } 06116 dialed_subaddress.str = s; 06117 dialed_subaddress.valid = 1; 06118 s = NULL; 06119 } 06120 06121 l = NULL; 06122 n = NULL; 06123 if (!p->hidecallerid) { 06124 if (ast->connected.id.number.valid) { 06125 /* If we get to the end of this loop without breaking, there's no 06126 * calleridnum. This is done instead of testing for "unknown" or 06127 * the thousands of other ways that the calleridnum could be 06128 * invalid. */ 06129 for (l = ast->connected.id.number.str; l && *l; l++) { 06130 if (strchr("0123456789", *l)) { 06131 l = ast->connected.id.number.str; 06132 break; 06133 } 06134 } 06135 } else { 06136 l = NULL; 06137 } 06138 if (!p->hidecalleridname) { 06139 n = ast->connected.id.name.valid ? ast->connected.id.name.str : NULL; 06140 } 06141 } 06142 06143 if (strlen(c) < p->stripmsd) { 06144 ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd); 06145 return -1; 06146 } 06147 if (pri_grab(p, p->pri)) { 06148 ast_log(LOG_WARNING, "Failed to grab PRI!\n"); 06149 return -1; 06150 } 06151 if (!(p->call = pri_new_call(p->pri->pri))) { 06152 ast_log(LOG_WARNING, "Unable to create call on channel %d\n", p->channel); 06153 pri_rel(p->pri); 06154 return -1; 06155 } 06156 if (!(sr = pri_sr_new())) { 06157 ast_log(LOG_WARNING, "Failed to allocate setup request channel %d\n", p->channel); 06158 pri_destroycall(p->pri->pri, p->call); 06159 p->call = NULL; 06160 pri_rel(p->pri); 06161 return -1; 06162 } 06163 06164 sig_pri_set_digital(p, IS_DIGITAL(ast->transfercapability)); /* push up to parent for EC */ 06165 06166 #if defined(HAVE_PRI_CALL_WAITING) 06167 if (p->is_call_waiting) { 06168 /* 06169 * Indicate that this is a call waiting call. 06170 * i.e., Normal call but with no B channel. 06171 */ 06172 pri_sr_set_channel(sr, 0, 0, 1); 06173 } else 06174 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 06175 { 06176 /* Should the picked channel be used exclusively? */ 06177 if (p->priexclusive || p->pri->nodetype == PRI_NETWORK) { 06178 exclusive = 1; 06179 } else { 06180 exclusive = 0; 06181 } 06182 pri_sr_set_channel(sr, PVT_TO_CHANNEL(p), exclusive, 1); 06183 } 06184 06185 pri_sr_set_bearer(sr, p->digital ? PRI_TRANS_CAP_DIGITAL : ast->transfercapability, 06186 (p->digital ? -1 : layer1)); 06187 06188 if (p->pri->facilityenable) 06189 pri_facility_enable(p->pri->pri); 06190 06191 ast_verb(3, "Requested transfer capability: 0x%.2x - %s\n", ast->transfercapability, ast_transfercapability2str(ast->transfercapability)); 06192 dp_strip = 0; 06193 pridialplan = p->pri->dialplan - 1; 06194 if (pridialplan == -2 || pridialplan == -3) { /* compute dynamically */ 06195 if (strncmp(c + p->stripmsd, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) { 06196 if (pridialplan == -2) { 06197 dp_strip = strlen(p->pri->internationalprefix); 06198 } 06199 pridialplan = PRI_INTERNATIONAL_ISDN; 06200 } else if (strncmp(c + p->stripmsd, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) { 06201 if (pridialplan == -2) { 06202 dp_strip = strlen(p->pri->nationalprefix); 06203 } 06204 pridialplan = PRI_NATIONAL_ISDN; 06205 } else { 06206 pridialplan = PRI_LOCAL_ISDN; 06207 } 06208 } 06209 while (c[p->stripmsd] > '9' && c[p->stripmsd] != '*' && c[p->stripmsd] != '#') { 06210 switch (c[p->stripmsd]) { 06211 case 'U': 06212 pridialplan = (PRI_TON_UNKNOWN << 4) | (pridialplan & 0xf); 06213 break; 06214 case 'I': 06215 pridialplan = (PRI_TON_INTERNATIONAL << 4) | (pridialplan & 0xf); 06216 break; 06217 case 'N': 06218 pridialplan = (PRI_TON_NATIONAL << 4) | (pridialplan & 0xf); 06219 break; 06220 case 'L': 06221 pridialplan = (PRI_TON_NET_SPECIFIC << 4) | (pridialplan & 0xf); 06222 break; 06223 case 'S': 06224 pridialplan = (PRI_TON_SUBSCRIBER << 4) | (pridialplan & 0xf); 06225 break; 06226 case 'V': 06227 pridialplan = (PRI_TON_ABBREVIATED << 4) | (pridialplan & 0xf); 06228 break; 06229 case 'R': 06230 pridialplan = (PRI_TON_RESERVED << 4) | (pridialplan & 0xf); 06231 break; 06232 case 'u': 06233 pridialplan = PRI_NPI_UNKNOWN | (pridialplan & 0xf0); 06234 break; 06235 case 'e': 06236 pridialplan = PRI_NPI_E163_E164 | (pridialplan & 0xf0); 06237 break; 06238 case 'x': 06239 pridialplan = PRI_NPI_X121 | (pridialplan & 0xf0); 06240 break; 06241 case 'f': 06242 pridialplan = PRI_NPI_F69 | (pridialplan & 0xf0); 06243 break; 06244 case 'n': 06245 pridialplan = PRI_NPI_NATIONAL | (pridialplan & 0xf0); 06246 break; 06247 case 'p': 06248 pridialplan = PRI_NPI_PRIVATE | (pridialplan & 0xf0); 06249 break; 06250 case 'r': 06251 pridialplan = PRI_NPI_RESERVED | (pridialplan & 0xf0); 06252 break; 06253 default: 06254 if (isalpha(c[p->stripmsd])) { 06255 ast_log(LOG_WARNING, "Unrecognized pridialplan %s modifier: %c\n", 06256 c[p->stripmsd] > 'Z' ? "NPI" : "TON", c[p->stripmsd]); 06257 } 06258 break; 06259 } 06260 c++; 06261 } 06262 #if defined(HAVE_PRI_SETUP_KEYPAD) 06263 if (ast_test_flag(&opts, OPT_KEYPAD) 06264 && !ast_strlen_zero(opt_args[OPT_ARG_KEYPAD])) { 06265 /* We have a keypad facility digits option with digits. */ 06266 keypad = opt_args[OPT_ARG_KEYPAD]; 06267 pri_sr_set_keypad_digits(sr, keypad); 06268 } else { 06269 keypad = NULL; 06270 } 06271 if (!keypad || !ast_strlen_zero(c + p->stripmsd + dp_strip)) 06272 #endif /* defined(HAVE_PRI_SETUP_KEYPAD) */ 06273 { 06274 pri_sr_set_called(sr, c + p->stripmsd + dp_strip, pridialplan, s ? 1 : 0); 06275 } 06276 06277 #if defined(HAVE_PRI_SUBADDR) 06278 if (dialed_subaddress.valid) { 06279 struct pri_party_subaddress subaddress; 06280 06281 memset(&subaddress, 0, sizeof(subaddress)); 06282 sig_pri_party_subaddress_from_ast(&subaddress, &dialed_subaddress); 06283 pri_sr_set_called_subaddress(sr, &subaddress); 06284 } 06285 #endif /* defined(HAVE_PRI_SUBADDR) */ 06286 #if defined(HAVE_PRI_REVERSE_CHARGE) 06287 if (ast_test_flag(&opts, OPT_REVERSE_CHARGE)) { 06288 pri_sr_set_reversecharge(sr, PRI_REVERSECHARGE_REQUESTED); 06289 } 06290 #endif /* defined(HAVE_PRI_REVERSE_CHARGE) */ 06291 #if defined(HAVE_PRI_AOC_EVENTS) 06292 if (ast_test_flag(&opts, OPT_AOC_REQUEST) 06293 && !ast_strlen_zero(opt_args[OPT_ARG_AOC_REQUEST])) { 06294 if (strchr(opt_args[OPT_ARG_AOC_REQUEST], 's')) { 06295 pri_sr_set_aoc_charging_request(sr, PRI_AOC_REQUEST_S); 06296 } 06297 if (strchr(opt_args[OPT_ARG_AOC_REQUEST], 'd')) { 06298 pri_sr_set_aoc_charging_request(sr, PRI_AOC_REQUEST_D); 06299 } 06300 if (strchr(opt_args[OPT_ARG_AOC_REQUEST], 'e')) { 06301 pri_sr_set_aoc_charging_request(sr, PRI_AOC_REQUEST_E); 06302 } 06303 } 06304 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 06305 06306 /* Setup the user tag for party id's from this device for this call. */ 06307 if (p->pri->append_msn_to_user_tag) { 06308 snprintf(p->user_tag, sizeof(p->user_tag), "%s_%s", p->pri->initial_user_tag, 06309 p->pri->nodetype == PRI_NETWORK 06310 ? c + p->stripmsd + dp_strip 06311 : S_COR(ast->connected.id.number.valid, 06312 ast->connected.id.number.str, "")); 06313 } else { 06314 ast_copy_string(p->user_tag, p->pri->initial_user_tag, sizeof(p->user_tag)); 06315 } 06316 06317 /* 06318 * Replace the caller id tag from the channel creation 06319 * with the actual tag value. 06320 */ 06321 ast_free(ast->caller.id.tag); 06322 ast->caller.id.tag = ast_strdup(p->user_tag); 06323 06324 ldp_strip = 0; 06325 prilocaldialplan = p->pri->localdialplan - 1; 06326 if ((l != NULL) && (prilocaldialplan == -2 || prilocaldialplan == -3)) { /* compute dynamically */ 06327 if (strncmp(l, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) { 06328 if (prilocaldialplan == -2) { 06329 ldp_strip = strlen(p->pri->internationalprefix); 06330 } 06331 prilocaldialplan = PRI_INTERNATIONAL_ISDN; 06332 } else if (strncmp(l, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) { 06333 if (prilocaldialplan == -2) { 06334 ldp_strip = strlen(p->pri->nationalprefix); 06335 } 06336 prilocaldialplan = PRI_NATIONAL_ISDN; 06337 } else { 06338 prilocaldialplan = PRI_LOCAL_ISDN; 06339 } 06340 } 06341 if (l != NULL) { 06342 while (*l > '9' && *l != '*' && *l != '#') { 06343 switch (*l) { 06344 case 'U': 06345 prilocaldialplan = (PRI_TON_UNKNOWN << 4) | (prilocaldialplan & 0xf); 06346 break; 06347 case 'I': 06348 prilocaldialplan = (PRI_TON_INTERNATIONAL << 4) | (prilocaldialplan & 0xf); 06349 break; 06350 case 'N': 06351 prilocaldialplan = (PRI_TON_NATIONAL << 4) | (prilocaldialplan & 0xf); 06352 break; 06353 case 'L': 06354 prilocaldialplan = (PRI_TON_NET_SPECIFIC << 4) | (prilocaldialplan & 0xf); 06355 break; 06356 case 'S': 06357 prilocaldialplan = (PRI_TON_SUBSCRIBER << 4) | (prilocaldialplan & 0xf); 06358 break; 06359 case 'V': 06360 prilocaldialplan = (PRI_TON_ABBREVIATED << 4) | (prilocaldialplan & 0xf); 06361 break; 06362 case 'R': 06363 prilocaldialplan = (PRI_TON_RESERVED << 4) | (prilocaldialplan & 0xf); 06364 break; 06365 case 'u': 06366 prilocaldialplan = PRI_NPI_UNKNOWN | (prilocaldialplan & 0xf0); 06367 break; 06368 case 'e': 06369 prilocaldialplan = PRI_NPI_E163_E164 | (prilocaldialplan & 0xf0); 06370 break; 06371 case 'x': 06372 prilocaldialplan = PRI_NPI_X121 | (prilocaldialplan & 0xf0); 06373 break; 06374 case 'f': 06375 prilocaldialplan = PRI_NPI_F69 | (prilocaldialplan & 0xf0); 06376 break; 06377 case 'n': 06378 prilocaldialplan = PRI_NPI_NATIONAL | (prilocaldialplan & 0xf0); 06379 break; 06380 case 'p': 06381 prilocaldialplan = PRI_NPI_PRIVATE | (prilocaldialplan & 0xf0); 06382 break; 06383 case 'r': 06384 prilocaldialplan = PRI_NPI_RESERVED | (prilocaldialplan & 0xf0); 06385 break; 06386 default: 06387 if (isalpha(*l)) { 06388 ast_log(LOG_WARNING, 06389 "Unrecognized prilocaldialplan %s modifier: %c\n", 06390 *l > 'Z' ? "NPI" : "TON", *l); 06391 } 06392 break; 06393 } 06394 l++; 06395 } 06396 } 06397 pri_sr_set_caller(sr, l ? (l + ldp_strip) : NULL, n, prilocaldialplan, 06398 p->use_callingpres ? ast->connected.id.number.presentation : (l ? PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN : PRES_NUMBER_NOT_AVAILABLE)); 06399 06400 #if defined(HAVE_PRI_SUBADDR) 06401 if (ast->connected.id.subaddress.valid) { 06402 struct pri_party_subaddress subaddress; 06403 06404 memset(&subaddress, 0, sizeof(subaddress)); 06405 sig_pri_party_subaddress_from_ast(&subaddress, &ast->connected.id.subaddress); 06406 pri_sr_set_caller_subaddress(sr, &subaddress); 06407 } 06408 #endif /* defined(HAVE_PRI_SUBADDR) */ 06409 06410 sig_pri_redirecting_update(p, ast); 06411 06412 #ifdef SUPPORT_USERUSER 06413 /* User-user info */ 06414 useruser = pbx_builtin_getvar_helper(p->owner, "USERUSERINFO"); 06415 if (useruser) 06416 pri_sr_set_useruser(sr, useruser); 06417 #endif 06418 06419 #if defined(HAVE_PRI_CCSS) 06420 if (ast_cc_is_recall(ast, &core_id, sig_pri_cc_type_name)) { 06421 struct ast_cc_monitor *monitor; 06422 char device_name[AST_CHANNEL_NAME]; 06423 06424 /* This is a CC recall call. */ 06425 ast_channel_get_device_name(ast, device_name, sizeof(device_name)); 06426 monitor = ast_cc_get_monitor_by_recall_core_id(core_id, device_name); 06427 if (monitor) { 06428 struct sig_pri_cc_monitor_instance *instance; 06429 06430 instance = monitor->private_data; 06431 06432 /* If this fails then we have monitor instance ambiguity. */ 06433 ast_assert(p->pri == instance->pri); 06434 06435 if (pri_cc_call(p->pri->pri, instance->cc_id, p->call, sr)) { 06436 /* The CC recall call failed for some reason. */ 06437 ast_log(LOG_WARNING, "Unable to setup CC recall call to device %s\n", 06438 device_name); 06439 ao2_ref(monitor, -1); 06440 pri_rel(p->pri); 06441 pri_sr_free(sr); 06442 return -1; 06443 } 06444 ao2_ref(monitor, -1); 06445 } else { 06446 core_id = -1; 06447 } 06448 } else 06449 #endif /* defined(HAVE_PRI_CCSS) */ 06450 { 06451 core_id = -1; 06452 } 06453 if (core_id == -1 && pri_setup(p->pri->pri, p->call, sr)) { 06454 ast_log(LOG_WARNING, "Unable to setup call to %s (using %s)\n", 06455 c + p->stripmsd + dp_strip, dialplan2str(p->pri->dialplan)); 06456 pri_rel(p->pri); 06457 pri_sr_free(sr); 06458 return -1; 06459 } 06460 pri_sr_free(sr); 06461 ast_setstate(ast, AST_STATE_DIALING); 06462 sig_pri_set_dialing(p, 1); 06463 pri_rel(p->pri); 06464 return 0; 06465 }
static void sig_pri_cc_generic_check | ( | struct sig_pri_span * | pri, | |
int | chanpos, | |||
enum ast_cc_service_type | service | |||
) | [static] |
Definition at line 2407 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().
02408 { 02409 struct ast_channel *owner; 02410 struct ast_cc_config_params *cc_params; 02411 #if defined(HAVE_PRI_CCSS) 02412 struct ast_cc_monitor *monitor; 02413 char device_name[AST_CHANNEL_NAME]; 02414 #endif /* defined(HAVE_PRI_CCSS) */ 02415 enum ast_cc_monitor_policies monitor_policy; 02416 int core_id; 02417 02418 if (!pri->pvts[chanpos]->outgoing) { 02419 /* This is not an outgoing call so it cannot be CC monitor. */ 02420 return; 02421 } 02422 02423 sig_pri_lock_owner(pri, chanpos); 02424 owner = pri->pvts[chanpos]->owner; 02425 if (!owner) { 02426 return; 02427 } 02428 core_id = ast_cc_get_current_core_id(owner); 02429 if (core_id == -1) { 02430 /* No CC core setup */ 02431 goto done; 02432 } 02433 02434 cc_params = ast_channel_get_cc_config_params(owner); 02435 if (!cc_params) { 02436 /* Could not get CC config parameters. */ 02437 goto done; 02438 } 02439 02440 #if defined(HAVE_PRI_CCSS) 02441 ast_channel_get_device_name(owner, device_name, sizeof(device_name)); 02442 monitor = ast_cc_get_monitor_by_recall_core_id(core_id, device_name); 02443 if (monitor) { 02444 /* CC monitor is already present so no need for generic CC. */ 02445 ao2_ref(monitor, -1); 02446 goto done; 02447 } 02448 #endif /* defined(HAVE_PRI_CCSS) */ 02449 02450 monitor_policy = ast_get_cc_monitor_policy(cc_params); 02451 switch (monitor_policy) { 02452 case AST_CC_MONITOR_NEVER: 02453 /* CCSS is not enabled. */ 02454 break; 02455 case AST_CC_MONITOR_NATIVE: 02456 if (pri->sig == SIG_BRI_PTMP && pri->nodetype == PRI_NETWORK) { 02457 /* Request generic CC monitor. */ 02458 ast_queue_cc_frame(owner, AST_CC_GENERIC_MONITOR_TYPE, 02459 sig_pri_get_orig_dialstring(pri->pvts[chanpos]), service, NULL); 02460 } 02461 break; 02462 case AST_CC_MONITOR_ALWAYS: 02463 if (pri->sig == SIG_BRI_PTMP && pri->nodetype != PRI_NETWORK) { 02464 /* 02465 * Cannot monitor PTMP TE side since this is not defined. 02466 * We are playing the roll of a phone in this case and 02467 * a phone cannot monitor a party over the network without 02468 * protocol help. 02469 */ 02470 break; 02471 } 02472 /* 02473 * We are either falling back or this is a PTMP NT span. 02474 * Request generic CC monitor. 02475 */ 02476 ast_queue_cc_frame(owner, AST_CC_GENERIC_MONITOR_TYPE, 02477 sig_pri_get_orig_dialstring(pri->pvts[chanpos]), service, NULL); 02478 break; 02479 case AST_CC_MONITOR_GENERIC: 02480 if (pri->sig == SIG_BRI_PTMP && pri->nodetype == PRI_NETWORK) { 02481 /* Request generic CC monitor. */ 02482 ast_queue_cc_frame(owner, AST_CC_GENERIC_MONITOR_TYPE, 02483 sig_pri_get_orig_dialstring(pri->pvts[chanpos]), service, NULL); 02484 } 02485 break; 02486 } 02487 02488 done: 02489 ast_channel_unlock(owner); 02490 }
void sig_pri_chan_alarm_notify | ( | struct sig_pri_chan * | p, | |
int | noalarm | |||
) |
Definition at line 7193 of file sig_pri.c.
References ast_channel::_softhangup, ast_log(), AST_SOFTHANGUP_DEV, sig_pri_chan::call, LOG_WARNING, sig_pri_chan::owner, sig_pri_chan::pri, sig_pri_span::pri, pri_grab(), pri_rel(), and sig_pri_set_alarm().
Referenced by dahdi_handle_event(), and handle_init_event().
07194 { 07195 sig_pri_set_alarm(p, !noalarm); 07196 if (!noalarm) { 07197 if (!p->pri || !p->pri->pri || (pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0)) { 07198 /* T309 is not enabled : hangup calls when alarm occurs */ 07199 if (p->call) { 07200 if (p->pri && p->pri->pri) { 07201 if (!pri_grab(p, p->pri)) { 07202 pri_hangup(p->pri->pri, p->call, -1); 07203 pri_destroycall(p->pri->pri, p->call); 07204 p->call = NULL; 07205 pri_rel(p->pri); 07206 } else 07207 ast_log(LOG_WARNING, "Failed to grab PRI!\n"); 07208 } else 07209 ast_log(LOG_WARNING, "The PRI Call has not been destroyed\n"); 07210 } 07211 if (p->owner) 07212 p->owner->_softhangup |= AST_SOFTHANGUP_DEV; 07213 } 07214 } 07215 }
void sig_pri_chan_delete | ( | struct sig_pri_chan * | doomed | ) |
Delete the sig_pri private channel structure.
doomed | sig_pri private channel structure to delete. |
Definition at line 7245 of file sig_pri.c.
References ast_free.
Referenced by destroy_dahdi_pvt().
07246 { 07247 ast_free(doomed); 07248 }
struct sig_pri_chan* sig_pri_chan_new | ( | void * | pvt_data, | |
struct sig_pri_callback * | callback, | |||
struct sig_pri_span * | pri, | |||
int | logicalspan, | |||
int | channo, | |||
int | trunkgroup | |||
) |
Definition at line 7217 of file sig_pri.c.
References ast_calloc, and sig_pri_chan::pri.
07218 { 07219 struct sig_pri_chan *p; 07220 07221 p = ast_calloc(1, sizeof(*p)); 07222 if (!p) 07223 return p; 07224 07225 p->logicalspan = logicalspan; 07226 p->prioffset = channo; 07227 p->mastertrunkgroup = trunkgroup; 07228 07229 p->calls = callback; 07230 p->chan_pvt = pvt_data; 07231 07232 p->pri = pri; 07233 07234 return p; 07235 }
void sig_pri_cli_show_span | ( | int | fd, | |
int * | dchannels, | |||
struct sig_pri_span * | pri | |||
) |
Definition at line 7281 of file sig_pri.c.
References ast_cli(), build_status(), DAHDI_OVERLAPDIAL_INCOMING, sig_pri_span::dchanavail, sig_pri_span::dchans, free, sig_pri_span::overlapdial, sig_pri_chan::pri, sig_pri_span::pri, pri_order(), and status.
Referenced by handle_pri_show_span().
07282 { 07283 int x; 07284 char status[256]; 07285 07286 for (x = 0; x < SIG_PRI_NUM_DCHANS; x++) { 07287 if (pri->dchans[x]) { 07288 #ifdef PRI_DUMP_INFO_STR 07289 char *info_str = NULL; 07290 #endif 07291 ast_cli(fd, "%s D-channel: %d\n", pri_order(x), dchannels[x]); 07292 build_status(status, sizeof(status), pri->dchanavail[x], pri->dchans[x] == pri->pri); 07293 ast_cli(fd, "Status: %s\n", status); 07294 #ifdef PRI_DUMP_INFO_STR 07295 info_str = pri_dump_info_str(pri->pri); 07296 if (info_str) { 07297 ast_cli(fd, "%s", info_str); 07298 free(info_str); 07299 } 07300 #else 07301 pri_dump_info(pri->pri); 07302 #endif 07303 ast_cli(fd, "Overlap Recv: %s\n\n", (pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)?"Yes":"No"); 07304 ast_cli(fd, "\n"); 07305 } 07306 } 07307 }
void sig_pri_cli_show_spans | ( | int | fd, | |
int | span, | |||
struct sig_pri_span * | pri | |||
) |
Definition at line 7269 of file sig_pri.c.
References ast_cli(), build_status(), sig_pri_span::dchanavail, sig_pri_span::dchans, sig_pri_chan::pri, sig_pri_span::pri, and status.
Referenced by handle_pri_show_spans().
07270 { 07271 char status[256]; 07272 int x; 07273 for (x = 0; x < SIG_PRI_NUM_DCHANS; x++) { 07274 if (pri->dchans[x]) { 07275 build_status(status, sizeof(status), pri->dchanavail[x], pri->dchans[x] == pri->pri); 07276 ast_cli(fd, "PRI span %d/%d: %s\n", span, x, status); 07277 } 07278 } 07279 }
static int sig_pri_cmp_pri_chans | ( | const void * | left, | |
const void * | right | |||
) | [static] |
Definition at line 6977 of file sig_pri.c.
References sig_pri_chan::channel.
Referenced by sig_pri_sort_pri_chans().
06978 { 06979 const struct sig_pri_chan *pvt_left; 06980 const struct sig_pri_chan *pvt_right; 06981 06982 pvt_left = *(struct sig_pri_chan **) left; 06983 pvt_right = *(struct sig_pri_chan **) right; 06984 if (!pvt_left) { 06985 if (!pvt_right) { 06986 return 0; 06987 } 06988 return 1; 06989 } 06990 if (!pvt_right) { 06991 return -1; 06992 } 06993 06994 return pvt_left->channel - pvt_right->channel; 06995 }
int sig_pri_digit_begin | ( | struct sig_pri_chan * | pvt, | |
struct ast_channel * | ast, | |||
char | digit | |||
) |
Definition at line 6819 of file sig_pri.c.
References ast_channel::_state, ast_debug, ast_log(), AST_STATE_DIALING, sig_pri_chan::call, sig_pri_chan::dialdest, LOG_WARNING, sig_pri_chan::pri, sig_pri_span::pri, pri_grab(), pri_rel(), sig_pri_chan::proceeding, sig_pri_chan::setup_ack, and sig_pri_span::span.
Referenced by dahdi_digit_begin().
06820 { 06821 if ((ast->_state == AST_STATE_DIALING) && !pvt->proceeding) { 06822 if (pvt->setup_ack) { 06823 if (!pri_grab(pvt, pvt->pri)) { 06824 pri_information(pvt->pri->pri, pvt->call, digit); 06825 pri_rel(pvt->pri); 06826 } else { 06827 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", pvt->pri->span); 06828 } 06829 } else if (strlen(pvt->dialdest) < sizeof(pvt->dialdest) - 1) { 06830 int res; 06831 ast_debug(1, "Queueing digit '%c' since setup_ack not yet received\n", digit); 06832 res = strlen(pvt->dialdest); 06833 pvt->dialdest[res++] = digit; 06834 pvt->dialdest[res] = '\0'; 06835 } 06836 return 0; 06837 } 06838 return 1; 06839 }
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 5957 of file sig_pri.c.
References args, AST_APP_ARG, AST_DECLARE_APP_ARGS, AST_NONSTANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), ext, and sig_pri_chan::stripmsd.
Referenced by dahdi_request().
05958 { 05959 char *dial; 05960 char *number; 05961 char *subaddr; 05962 AST_DECLARE_APP_ARGS(args, 05963 AST_APP_ARG(group); /* channel/group token */ 05964 AST_APP_ARG(ext); /* extension token */ 05965 //AST_APP_ARG(opts); /* options token */ 05966 AST_APP_ARG(other); /* Any remining unused arguments */ 05967 ); 05968 05969 /* Get private copy of dial string and break it up. */ 05970 dial = ast_strdupa(rdest); 05971 AST_NONSTANDARD_APP_ARGS(args, dial, '/'); 05972 05973 number = args.ext; 05974 if (!number) { 05975 number = ""; 05976 } 05977 05978 /* Find and extract dialed_subaddress */ 05979 subaddr = strchr(number, ':'); 05980 if (subaddr) { 05981 *subaddr++ = '\0'; 05982 05983 /* Skip subaddress type prefix. */ 05984 switch (*subaddr) { 05985 case 'U': 05986 case 'u': 05987 case 'N': 05988 case 'n': 05989 ++subaddr; 05990 break; 05991 default: 05992 break; 05993 } 05994 } 05995 05996 /* Skip type-of-number/dial-plan prefix characters. */ 05997 if (strlen(number) < p->stripmsd) { 05998 number = ""; 05999 } else { 06000 number += p->stripmsd; 06001 while (isalpha(*number)) { 06002 ++number; 06003 } 06004 } 06005 06006 /* Fill buffer with extracted number and subaddress. */ 06007 if (ast_strlen_zero(subaddr)) { 06008 /* Put in called number only since there is no subaddress. */ 06009 snprintf(called, called_buff_size, "%s", number); 06010 } else { 06011 /* Put in called number and subaddress. */ 06012 snprintf(called, called_buff_size, "%s:%s", number, subaddr); 06013 } 06014 }
void sig_pri_fixup | ( | struct ast_channel * | oldchan, | |
struct ast_channel * | newchan, | |||
struct sig_pri_chan * | pchan | |||
) |
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 3506 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.
03508 { 03509 int index; 03510 #if defined(HAVE_PRI_CCSS) 03511 struct ast_cc_agent *agent; 03512 struct sig_pri_cc_agent_prv *agent_prv; 03513 struct sig_pri_cc_monitor_instance *monitor; 03514 #endif /* defined(HAVE_PRI_CCSS) */ 03515 03516 if (!subcmds) { 03517 return; 03518 } 03519 for (index = 0; index < subcmds->counter_subcmd; ++index) { 03520 const struct pri_subcommand *subcmd = &subcmds->subcmd[index]; 03521 03522 switch (subcmd->cmd) { 03523 #if defined(STATUS_REQUEST_PLACE_HOLDER) 03524 case PRI_SUBCMD_STATUS_REQ: 03525 case PRI_SUBCMD_STATUS_REQ_RSP: 03526 /* Ignore for now. */ 03527 break; 03528 #endif /* defined(STATUS_REQUEST_PLACE_HOLDER) */ 03529 #if defined(HAVE_PRI_CCSS) 03530 case PRI_SUBCMD_CC_REQ: 03531 agent = sig_pri_find_cc_agent_by_cc_id(pri, subcmd->u.cc_request.cc_id); 03532 if (!agent) { 03533 pri_cc_cancel(pri->pri, subcmd->u.cc_request.cc_id); 03534 break; 03535 } 03536 if (!ast_cc_request_is_within_limits()) { 03537 if (pri_cc_req_rsp(pri->pri, subcmd->u.cc_request.cc_id, 03538 5/* queue_full */)) { 03539 pri_cc_cancel(pri->pri, subcmd->u.cc_request.cc_id); 03540 } 03541 ast_cc_failed(agent->core_id, "%s agent system CC queue full", 03542 sig_pri_cc_type_name); 03543 ao2_ref(agent, -1); 03544 break; 03545 } 03546 agent_prv = agent->private_data; 03547 agent_prv->cc_request_response_pending = 1; 03548 if (ast_cc_agent_accept_request(agent->core_id, 03549 "%s caller accepted CC offer.", sig_pri_cc_type_name)) { 03550 agent_prv->cc_request_response_pending = 0; 03551 if (pri_cc_req_rsp(pri->pri, subcmd->u.cc_request.cc_id, 03552 2/* short_term_denial */)) { 03553 pri_cc_cancel(pri->pri, subcmd->u.cc_request.cc_id); 03554 } 03555 ast_cc_failed(agent->core_id, "%s agent CC core request accept failed", 03556 sig_pri_cc_type_name); 03557 } 03558 ao2_ref(agent, -1); 03559 break; 03560 #endif /* defined(HAVE_PRI_CCSS) */ 03561 #if defined(HAVE_PRI_CCSS) 03562 case PRI_SUBCMD_CC_REQ_RSP: 03563 monitor = sig_pri_find_cc_monitor_by_cc_id(pri, 03564 subcmd->u.cc_request_rsp.cc_id); 03565 if (!monitor) { 03566 pri_cc_cancel(pri->pri, subcmd->u.cc_request_rsp.cc_id); 03567 break; 03568 } 03569 switch (subcmd->u.cc_request_rsp.status) { 03570 case 0:/* success */ 03571 ast_cc_monitor_request_acked(monitor->core_id, 03572 "%s far end accepted CC request", sig_pri_cc_type_name); 03573 break; 03574 case 1:/* timeout */ 03575 ast_verb(2, "core_id:%d %s CC request timeout\n", monitor->core_id, 03576 sig_pri_cc_type_name); 03577 ast_cc_monitor_failed(monitor->core_id, monitor->name, 03578 "%s CC request timeout", sig_pri_cc_type_name); 03579 break; 03580 case 2:/* error */ 03581 ast_verb(2, "core_id:%d %s CC request error: %s\n", monitor->core_id, 03582 sig_pri_cc_type_name, 03583 pri_facility_error2str(subcmd->u.cc_request_rsp.fail_code)); 03584 ast_cc_monitor_failed(monitor->core_id, monitor->name, 03585 "%s CC request error", sig_pri_cc_type_name); 03586 break; 03587 case 3:/* reject */ 03588 ast_verb(2, "core_id:%d %s CC request reject: %s\n", monitor->core_id, 03589 sig_pri_cc_type_name, 03590 pri_facility_reject2str(subcmd->u.cc_request_rsp.fail_code)); 03591 ast_cc_monitor_failed(monitor->core_id, monitor->name, 03592 "%s CC request reject", sig_pri_cc_type_name); 03593 break; 03594 default: 03595 ast_verb(2, "core_id:%d %s CC request unknown status %d\n", 03596 monitor->core_id, sig_pri_cc_type_name, 03597 subcmd->u.cc_request_rsp.status); 03598 ast_cc_monitor_failed(monitor->core_id, monitor->name, 03599 "%s CC request unknown status", sig_pri_cc_type_name); 03600 break; 03601 } 03602 ao2_ref(monitor, -1); 03603 break; 03604 #endif /* defined(HAVE_PRI_CCSS) */ 03605 #if defined(HAVE_PRI_CCSS) 03606 case PRI_SUBCMD_CC_REMOTE_USER_FREE: 03607 monitor = sig_pri_find_cc_monitor_by_cc_id(pri, 03608 subcmd->u.cc_remote_user_free.cc_id); 03609 if (!monitor) { 03610 pri_cc_cancel(pri->pri, subcmd->u.cc_remote_user_free.cc_id); 03611 break; 03612 } 03613 ast_cc_monitor_callee_available(monitor->core_id, 03614 "%s callee has become available", sig_pri_cc_type_name); 03615 ao2_ref(monitor, -1); 03616 break; 03617 #endif /* defined(HAVE_PRI_CCSS) */ 03618 #if defined(HAVE_PRI_CCSS) 03619 case PRI_SUBCMD_CC_B_FREE: 03620 monitor = sig_pri_find_cc_monitor_by_cc_id(pri, 03621 subcmd->u.cc_b_free.cc_id); 03622 if (!monitor) { 03623 pri_cc_cancel(pri->pri, subcmd->u.cc_b_free.cc_id); 03624 break; 03625 } 03626 ast_cc_monitor_party_b_free(monitor->core_id); 03627 ao2_ref(monitor, -1); 03628 break; 03629 #endif /* defined(HAVE_PRI_CCSS) */ 03630 #if defined(HAVE_PRI_CCSS) 03631 case PRI_SUBCMD_CC_STATUS_REQ: 03632 monitor = sig_pri_find_cc_monitor_by_cc_id(pri, 03633 subcmd->u.cc_status_req.cc_id); 03634 if (!monitor) { 03635 pri_cc_cancel(pri->pri, subcmd->u.cc_status_req.cc_id); 03636 break; 03637 } 03638 ast_cc_monitor_status_request(monitor->core_id); 03639 ao2_ref(monitor, -1); 03640 break; 03641 #endif /* defined(HAVE_PRI_CCSS) */ 03642 #if defined(HAVE_PRI_CCSS) 03643 case PRI_SUBCMD_CC_STATUS_REQ_RSP: 03644 agent = sig_pri_find_cc_agent_by_cc_id(pri, subcmd->u.cc_status_req_rsp.cc_id); 03645 if (!agent) { 03646 pri_cc_cancel(pri->pri, subcmd->u.cc_status_req_rsp.cc_id); 03647 break; 03648 } 03649 ast_cc_agent_status_response(agent->core_id, 03650 subcmd->u.cc_status_req_rsp.status ? AST_DEVICE_INUSE 03651 : AST_DEVICE_NOT_INUSE); 03652 ao2_ref(agent, -1); 03653 break; 03654 #endif /* defined(HAVE_PRI_CCSS) */ 03655 #if defined(HAVE_PRI_CCSS) 03656 case PRI_SUBCMD_CC_STATUS: 03657 agent = sig_pri_find_cc_agent_by_cc_id(pri, subcmd->u.cc_status.cc_id); 03658 if (!agent) { 03659 pri_cc_cancel(pri->pri, subcmd->u.cc_status.cc_id); 03660 break; 03661 } 03662 if (subcmd->u.cc_status.status) { 03663 ast_cc_agent_caller_busy(agent->core_id, "%s agent caller is busy", 03664 sig_pri_cc_type_name); 03665 } else { 03666 ast_cc_agent_caller_available(agent->core_id, 03667 "%s agent caller is available", sig_pri_cc_type_name); 03668 } 03669 ao2_ref(agent, -1); 03670 break; 03671 #endif /* defined(HAVE_PRI_CCSS) */ 03672 #if defined(HAVE_PRI_CCSS) 03673 case PRI_SUBCMD_CC_CANCEL: 03674 sig_pri_cc_link_canceled(pri, subcmd->u.cc_cancel.cc_id, 03675 subcmd->u.cc_cancel.is_agent); 03676 break; 03677 #endif /* defined(HAVE_PRI_CCSS) */ 03678 #if defined(HAVE_PRI_CCSS) 03679 case PRI_SUBCMD_CC_STOP_ALERTING: 03680 monitor = sig_pri_find_cc_monitor_by_cc_id(pri, 03681 subcmd->u.cc_stop_alerting.cc_id); 03682 if (!monitor) { 03683 pri_cc_cancel(pri->pri, subcmd->u.cc_stop_alerting.cc_id); 03684 break; 03685 } 03686 ast_cc_monitor_stop_ringing(monitor->core_id); 03687 ao2_ref(monitor, -1); 03688 break; 03689 #endif /* defined(HAVE_PRI_CCSS) */ 03690 #if defined(HAVE_PRI_AOC_EVENTS) 03691 case PRI_SUBCMD_AOC_E: 03692 /* Queue AST_CONTROL_AOC frame */ 03693 sig_pri_aoc_e_from_pri(&subcmd->u.aoc_e, NULL, 0); 03694 break; 03695 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 03696 default: 03697 ast_debug(2, 03698 "Unknown CIS subcommand(%d) in %s event on span %d.\n", 03699 subcmd->cmd, pri_event2str(event_id), pri->span); 03700 break; 03701 } 03702 } 03703 }
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 4103 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.
04104 { 04105 int retval; 04106 int chanpos_old; 04107 int chanpos_new; 04108 struct ast_channel *bridged; 04109 struct ast_channel *owner; 04110 04111 chanpos_old = pri_find_principle(pri, ev->hold.channel, ev->hold.call); 04112 if (chanpos_old < 0) { 04113 ast_log(LOG_WARNING, 04114 "Received HOLD on unconfigured channel %d/%d span %d\n", 04115 PRI_SPAN(ev->hold.channel), PRI_CHANNEL(ev->hold.channel), pri->span); 04116 return -1; 04117 } 04118 if (pri->pvts[chanpos_old]->no_b_channel) { 04119 /* Call is already on hold or is call waiting call. */ 04120 return -1; 04121 } 04122 04123 sig_pri_lock_private(pri->pvts[chanpos_old]); 04124 sig_pri_lock_owner(pri, chanpos_old); 04125 owner = pri->pvts[chanpos_old]->owner; 04126 if (!owner) { 04127 retval = -1; 04128 goto done_with_private; 04129 } 04130 bridged = ast_bridged_channel(owner); 04131 if (!bridged) { 04132 /* Cannot hold a call that is not bridged. */ 04133 retval = -1; 04134 goto done_with_owner; 04135 } 04136 chanpos_new = pri_find_empty_nobch(pri); 04137 if (chanpos_new < 0) { 04138 /* No hold channel available. */ 04139 retval = -1; 04140 goto done_with_owner; 04141 } 04142 sig_pri_handle_subcmds(pri, chanpos_old, ev->e, ev->hold.channel, ev->hold.subcmds, 04143 ev->hold.call); 04144 chanpos_new = pri_fixup_principle(pri, chanpos_new, ev->hold.call); 04145 if (chanpos_new < 0) { 04146 /* Should never happen. */ 04147 retval = -1; 04148 } else { 04149 struct ast_frame f = { AST_FRAME_CONTROL, }; 04150 04151 /* 04152 * Things are in an odd state here so we cannot use pri_queue_control(). 04153 * However, we already have the owner lock so we can simply queue the frame. 04154 */ 04155 f.subclass.integer = AST_CONTROL_HOLD; 04156 ast_queue_frame(owner, &f); 04157 04158 sig_pri_span_devstate_changed(pri); 04159 retval = 0; 04160 } 04161 04162 done_with_owner:; 04163 ast_channel_unlock(owner); 04164 done_with_private:; 04165 sig_pri_unlock_private(pri->pvts[chanpos_old]); 04166 04167 return retval; 04168 }
static void sig_pri_handle_retrieve | ( | struct sig_pri_span * | pri, | |
pri_event * | ev | |||
) | [static] |
Definition at line 4184 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().
04185 { 04186 int chanpos; 04187 04188 if (!(ev->retrieve.channel & PRI_HELD_CALL) 04189 || pri_find_principle(pri, ev->retrieve.channel, ev->retrieve.call) < 0) { 04190 /* The call is not currently held. */ 04191 pri_retrieve_rej(pri->pri, ev->retrieve.call, 04192 PRI_CAUSE_RESOURCE_UNAVAIL_UNSPECIFIED); 04193 return; 04194 } 04195 if (PRI_CHANNEL(ev->retrieve.channel) == 0xFF) { 04196 chanpos = pri_find_empty_chan(pri, 1); 04197 } else { 04198 chanpos = pri_find_principle(pri, 04199 ev->retrieve.channel & ~PRI_HELD_CALL, ev->retrieve.call); 04200 if (ev->retrieve.flexible 04201 && (chanpos < 0 || pri->pvts[chanpos]->owner)) { 04202 /* 04203 * Channel selection is flexible and the requested channel 04204 * is bad or already in use. Pick another channel. 04205 */ 04206 chanpos = pri_find_empty_chan(pri, 1); 04207 } 04208 } 04209 if (chanpos < 0) { 04210 pri_retrieve_rej(pri->pri, ev->retrieve.call, 04211 ev->retrieve.flexible ? PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION 04212 : PRI_CAUSE_REQUESTED_CHAN_UNAVAIL); 04213 return; 04214 } 04215 chanpos = pri_fixup_principle(pri, chanpos, ev->retrieve.call); 04216 if (chanpos < 0) { 04217 /* Channel is already in use. */ 04218 pri_retrieve_rej(pri->pri, ev->retrieve.call, 04219 PRI_CAUSE_REQUESTED_CHAN_UNAVAIL); 04220 return; 04221 } 04222 sig_pri_lock_private(pri->pvts[chanpos]); 04223 sig_pri_handle_subcmds(pri, chanpos, ev->e, ev->retrieve.channel, 04224 ev->retrieve.subcmds, ev->retrieve.call); 04225 pri_queue_control(pri, chanpos, AST_CONTROL_UNHOLD); 04226 sig_pri_unlock_private(pri->pvts[chanpos]); 04227 sig_pri_span_devstate_changed(pri); 04228 pri_retrieve_ack(pri->pri, ev->retrieve.call, 04229 PVT_TO_CHANNEL(pri->pvts[chanpos])); 04230 }
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 3762 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().
03764 { 03765 int index; 03766 struct ast_channel *owner; 03767 struct ast_party_redirecting ast_redirecting; 03768 #if defined(HAVE_PRI_TRANSFER) 03769 struct xfer_rsp_data xfer_rsp; 03770 #endif /* defined(HAVE_PRI_TRANSFER) */ 03771 03772 if (!subcmds) { 03773 return; 03774 } 03775 for (index = 0; index < subcmds->counter_subcmd; ++index) { 03776 const struct pri_subcommand *subcmd = &subcmds->subcmd[index]; 03777 03778 switch (subcmd->cmd) { 03779 case PRI_SUBCMD_CONNECTED_LINE: 03780 sig_pri_lock_owner(pri, chanpos); 03781 owner = pri->pvts[chanpos]->owner; 03782 if (owner) { 03783 struct ast_party_connected_line ast_connected; 03784 int caller_id_update; 03785 03786 /* Extract the connected line information */ 03787 ast_party_connected_line_init(&ast_connected); 03788 sig_pri_party_id_convert(&ast_connected.id, &subcmd->u.connected_line.id, 03789 pri); 03790 ast_connected.id.tag = ast_strdup(pri->pvts[chanpos]->user_tag); 03791 03792 caller_id_update = 0; 03793 if (ast_connected.id.name.str) { 03794 /* Save name for Caller-ID update */ 03795 ast_copy_string(pri->pvts[chanpos]->cid_name, 03796 ast_connected.id.name.str, sizeof(pri->pvts[chanpos]->cid_name)); 03797 caller_id_update = 1; 03798 } 03799 if (ast_connected.id.number.str) { 03800 /* Save number for Caller-ID update */ 03801 ast_copy_string(pri->pvts[chanpos]->cid_num, 03802 ast_connected.id.number.str, sizeof(pri->pvts[chanpos]->cid_num)); 03803 pri->pvts[chanpos]->cid_ton = ast_connected.id.number.plan; 03804 caller_id_update = 1; 03805 } 03806 ast_connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER; 03807 03808 pri->pvts[chanpos]->cid_subaddr[0] = '\0'; 03809 #if defined(HAVE_PRI_SUBADDR) 03810 if (ast_connected.id.subaddress.valid) { 03811 ast_party_subaddress_set(&owner->caller.id.subaddress, 03812 &ast_connected.id.subaddress); 03813 if (ast_connected.id.subaddress.str) { 03814 ast_copy_string(pri->pvts[chanpos]->cid_subaddr, 03815 ast_connected.id.subaddress.str, 03816 sizeof(pri->pvts[chanpos]->cid_subaddr)); 03817 } 03818 } 03819 #endif /* defined(HAVE_PRI_SUBADDR) */ 03820 if (caller_id_update) { 03821 struct ast_party_caller ast_caller; 03822 03823 pri->pvts[chanpos]->callingpres = 03824 ast_party_id_presentation(&ast_connected.id); 03825 sig_pri_set_caller_id(pri->pvts[chanpos]); 03826 03827 ast_party_caller_set_init(&ast_caller, &owner->caller); 03828 ast_caller.id = ast_connected.id; 03829 ast_caller.ani = ast_connected.id; 03830 ast_channel_set_caller_event(owner, &ast_caller, NULL); 03831 } 03832 03833 /* Update the connected line information on the other channel */ 03834 if (event_id != PRI_EVENT_RING) { 03835 /* This connected_line update was not from a SETUP message. */ 03836 ast_channel_queue_connected_line_update(owner, &ast_connected, NULL); 03837 } 03838 03839 ast_party_connected_line_free(&ast_connected); 03840 ast_channel_unlock(owner); 03841 } 03842 break; 03843 case PRI_SUBCMD_REDIRECTING: 03844 sig_pri_lock_owner(pri, chanpos); 03845 owner = pri->pvts[chanpos]->owner; 03846 if (owner) { 03847 sig_pri_redirecting_convert(&ast_redirecting, &subcmd->u.redirecting, 03848 &owner->redirecting, pri); 03849 ast_redirecting.from.tag = ast_strdup(pri->pvts[chanpos]->user_tag); 03850 ast_redirecting.to.tag = ast_strdup(pri->pvts[chanpos]->user_tag); 03851 03852 /*! \todo XXX Original called data can be put in a channel data store that is inherited. */ 03853 03854 ast_channel_set_redirecting(owner, &ast_redirecting, NULL); 03855 if (event_id != PRI_EVENT_RING) { 03856 /* This redirection was not from a SETUP message. */ 03857 ast_channel_queue_redirecting_update(owner, &ast_redirecting, NULL); 03858 } 03859 ast_party_redirecting_free(&ast_redirecting); 03860 03861 ast_channel_unlock(owner); 03862 } 03863 break; 03864 #if defined(HAVE_PRI_CALL_REROUTING) 03865 case PRI_SUBCMD_REROUTING: 03866 sig_pri_lock_owner(pri, chanpos); 03867 owner = pri->pvts[chanpos]->owner; 03868 if (owner) { 03869 struct pri_party_redirecting pri_deflection; 03870 03871 if (!call_rsp) { 03872 ast_channel_unlock(owner); 03873 ast_log(LOG_WARNING, 03874 "CallRerouting/CallDeflection to '%s' without call!\n", 03875 subcmd->u.rerouting.deflection.to.number.str); 03876 break; 03877 } 03878 03879 pri_deflection = subcmd->u.rerouting.deflection; 03880 03881 ast_string_field_set(owner, call_forward, pri_deflection.to.number.str); 03882 03883 /* Adjust the deflecting to number based upon the subscription option. */ 03884 switch (subcmd->u.rerouting.subscription_option) { 03885 case 0: /* noNotification */ 03886 case 1: /* notificationWithoutDivertedToNr */ 03887 /* Delete the number because the far end is not supposed to see it. */ 03888 pri_deflection.to.number.presentation = 03889 PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_UNSCREENED; 03890 pri_deflection.to.number.plan = 03891 (PRI_TON_UNKNOWN << 4) | PRI_NPI_E163_E164; 03892 pri_deflection.to.number.str[0] = '\0'; 03893 break; 03894 case 2: /* notificationWithDivertedToNr */ 03895 break; 03896 case 3: /* notApplicable */ 03897 default: 03898 break; 03899 } 03900 sig_pri_redirecting_convert(&ast_redirecting, &pri_deflection, 03901 &owner->redirecting, pri); 03902 ast_redirecting.from.tag = ast_strdup(pri->pvts[chanpos]->user_tag); 03903 ast_redirecting.to.tag = ast_strdup(pri->pvts[chanpos]->user_tag); 03904 ast_channel_set_redirecting(owner, &ast_redirecting, NULL); 03905 ast_party_redirecting_free(&ast_redirecting); 03906 03907 /* 03908 * Send back positive ACK to CallRerouting/CallDeflection. 03909 * 03910 * Note: This call will be hungup by the dial application when 03911 * it processes the call_forward string set above. 03912 */ 03913 pri_rerouting_rsp(pri->pri, call_rsp, subcmd->u.rerouting.invoke_id, 03914 PRI_REROUTING_RSP_OK_CLEAR); 03915 03916 /* This line is BUSY to further attempts by this dialing attempt. */ 03917 ast_queue_control(owner, AST_CONTROL_BUSY); 03918 03919 ast_channel_unlock(owner); 03920 } 03921 break; 03922 #endif /* defined(HAVE_PRI_CALL_REROUTING) */ 03923 #if defined(HAVE_PRI_CCSS) 03924 case PRI_SUBCMD_CC_AVAILABLE: 03925 sig_pri_lock_owner(pri, chanpos); 03926 owner = pri->pvts[chanpos]->owner; 03927 if (owner) { 03928 enum ast_cc_service_type service; 03929 03930 switch (event_id) { 03931 case PRI_EVENT_RINGING: 03932 service = AST_CC_CCNR; 03933 break; 03934 case PRI_EVENT_HANGUP_REQ: 03935 /* We will assume that the cause was busy/congestion. */ 03936 service = AST_CC_CCBS; 03937 break; 03938 default: 03939 service = AST_CC_NONE; 03940 break; 03941 } 03942 if (service == AST_CC_NONE 03943 || sig_pri_cc_available(pri, chanpos, subcmd->u.cc_available.cc_id, 03944 service)) { 03945 pri_cc_cancel(pri->pri, subcmd->u.cc_available.cc_id); 03946 } 03947 ast_channel_unlock(owner); 03948 } else { 03949 /* No asterisk channel. */ 03950 pri_cc_cancel(pri->pri, subcmd->u.cc_available.cc_id); 03951 } 03952 break; 03953 #endif /* defined(HAVE_PRI_CCSS) */ 03954 #if defined(HAVE_PRI_CCSS) 03955 case PRI_SUBCMD_CC_CALL: 03956 sig_pri_lock_owner(pri, chanpos); 03957 owner = pri->pvts[chanpos]->owner; 03958 if (owner) { 03959 struct ast_cc_agent *agent; 03960 03961 agent = sig_pri_find_cc_agent_by_cc_id(pri, subcmd->u.cc_call.cc_id); 03962 if (agent) { 03963 ast_setup_cc_recall_datastore(owner, agent->core_id); 03964 ast_cc_agent_set_interfaces_chanvar(owner); 03965 ast_cc_agent_recalling(agent->core_id, 03966 "%s caller is attempting recall", sig_pri_cc_type_name); 03967 ao2_ref(agent, -1); 03968 } 03969 03970 ast_channel_unlock(owner); 03971 } 03972 break; 03973 #endif /* defined(HAVE_PRI_CCSS) */ 03974 #if defined(HAVE_PRI_CCSS) 03975 case PRI_SUBCMD_CC_CANCEL: 03976 sig_pri_cc_link_canceled(pri, subcmd->u.cc_cancel.cc_id, 03977 subcmd->u.cc_cancel.is_agent); 03978 break; 03979 #endif /* defined(HAVE_PRI_CCSS) */ 03980 #if defined(HAVE_PRI_TRANSFER) 03981 case PRI_SUBCMD_TRANSFER_CALL: 03982 if (!call_rsp) { 03983 /* Should never happen. */ 03984 ast_log(LOG_ERROR, 03985 "Call transfer subcommand without call to send response!\n"); 03986 break; 03987 } 03988 03989 sig_pri_unlock_private(pri->pvts[chanpos]); 03990 xfer_rsp.pri = pri; 03991 xfer_rsp.call = call_rsp; 03992 xfer_rsp.invoke_id = subcmd->u.transfer.invoke_id; 03993 sig_pri_attempt_transfer(pri, 03994 subcmd->u.transfer.call_1, subcmd->u.transfer.is_call_1_held, 03995 subcmd->u.transfer.call_2, subcmd->u.transfer.is_call_2_held, 03996 sig_pri_transfer_rsp, &xfer_rsp); 03997 sig_pri_lock_private(pri->pvts[chanpos]); 03998 break; 03999 #endif /* defined(HAVE_PRI_TRANSFER) */ 04000 #if defined(HAVE_PRI_AOC_EVENTS) 04001 case PRI_SUBCMD_AOC_S: 04002 sig_pri_lock_owner(pri, chanpos); 04003 owner = pri->pvts[chanpos]->owner; 04004 if (owner) { 04005 sig_pri_aoc_s_from_pri(&subcmd->u.aoc_s, owner, 04006 (pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_S)); 04007 ast_channel_unlock(owner); 04008 } 04009 break; 04010 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 04011 #if defined(HAVE_PRI_AOC_EVENTS) 04012 case PRI_SUBCMD_AOC_D: 04013 sig_pri_lock_owner(pri, chanpos); 04014 owner = pri->pvts[chanpos]->owner; 04015 if (owner) { 04016 /* Queue AST_CONTROL_AOC frame on channel */ 04017 sig_pri_aoc_d_from_pri(&subcmd->u.aoc_d, owner, 04018 (pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_D)); 04019 ast_channel_unlock(owner); 04020 } 04021 break; 04022 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 04023 #if defined(HAVE_PRI_AOC_EVENTS) 04024 case PRI_SUBCMD_AOC_E: 04025 sig_pri_lock_owner(pri, chanpos); 04026 owner = pri->pvts[chanpos]->owner; 04027 /* Queue AST_CONTROL_AOC frame */ 04028 sig_pri_aoc_e_from_pri(&subcmd->u.aoc_e, owner, 04029 (pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_E)); 04030 if (owner) { 04031 ast_channel_unlock(owner); 04032 } 04033 break; 04034 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 04035 #if defined(HAVE_PRI_AOC_EVENTS) 04036 case PRI_SUBCMD_AOC_CHARGING_REQ: 04037 sig_pri_lock_owner(pri, chanpos); 04038 owner = pri->pvts[chanpos]->owner; 04039 if (owner) { 04040 sig_pri_aoc_request_from_pri(&subcmd->u.aoc_request, pri->pvts[chanpos], 04041 call_rsp); 04042 ast_channel_unlock(owner); 04043 } 04044 break; 04045 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 04046 #if defined(HAVE_PRI_AOC_EVENTS) 04047 case PRI_SUBCMD_AOC_CHARGING_REQ_RSP: 04048 /* 04049 * An AOC request response may contain an AOC-S rate list. 04050 * If this is the case handle this just like we 04051 * would an incoming AOC-S msg. 04052 */ 04053 if (subcmd->u.aoc_request_response.valid_aoc_s) { 04054 sig_pri_lock_owner(pri, chanpos); 04055 owner = pri->pvts[chanpos]->owner; 04056 if (owner) { 04057 sig_pri_aoc_s_from_pri(&subcmd->u.aoc_request_response.aoc_s, owner, 04058 (pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_S)); 04059 ast_channel_unlock(owner); 04060 } 04061 } 04062 break; 04063 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 04064 #if defined(HAVE_PRI_MCID) 04065 case PRI_SUBCMD_MCID_REQ: 04066 sig_pri_lock_owner(pri, chanpos); 04067 owner = pri->pvts[chanpos]->owner; 04068 sig_pri_mcid_event(pri, &subcmd->u.mcid_req, owner); 04069 if (owner) { 04070 ast_channel_unlock(owner); 04071 } 04072 break; 04073 #endif /* defined(HAVE_PRI_MCID) */ 04074 #if defined(HAVE_PRI_MCID) 04075 case PRI_SUBCMD_MCID_RSP: 04076 /* Ignore for now. */ 04077 break; 04078 #endif /* defined(HAVE_PRI_MCID) */ 04079 default: 04080 ast_debug(2, 04081 "Unknown call subcommand(%d) in %s event on channel %d/%d on span %d.\n", 04082 subcmd->cmd, pri_event2str(event_id), PRI_SPAN(channel), 04083 PRI_CHANNEL(channel), pri->span); 04084 break; 04085 } 04086 } 04087 }
int sig_pri_hangup | ( | struct sig_pri_chan * | p, | |
struct ast_channel * | ast | |||
) |
Definition at line 5855 of file sig_pri.c.
References sig_pri_chan::alerting, sig_pri_chan::alreadyhungup, ast_atomic_fetchadd_int(), ast_log(), sig_pri_chan::call, cause, sig_pri_chan::channel, sig_pri_chan::cid_name, sig_pri_chan::cid_num, sig_pri_chan::cid_subaddr, sig_pri_chan::exten, ast_channel::hangupcause, LOG_DEBUG, LOG_WARNING, sig_pri_chan::outgoing, sig_pri_chan::owner, pbx_builtin_getvar_helper(), sig_pri_chan::pri, sig_pri_span::pri, pri_grab(), pri_rel(), sig_pri_chan::proceeding, sig_pri_chan::progress, sig_pri_chan::setup_ack, sig_pri_set_dialing(), sig_pri_set_digital(), sig_pri_span_devstate_changed(), sig_pri_span::span, ast_channel::tech_pvt, and sig_pri_chan::user_tag.
Referenced by dahdi_hangup().
05856 { 05857 int res; 05858 #ifdef SUPPORT_USERUSER 05859 const char *useruser = pbx_builtin_getvar_helper(ast, "USERUSERINFO"); 05860 #endif 05861 05862 ast_log(LOG_DEBUG, "%s %d\n", __FUNCTION__, p->channel); 05863 if (!ast->tech_pvt) { 05864 ast_log(LOG_WARNING, "Asked to hangup channel not connected\n"); 05865 return 0; 05866 } 05867 05868 p->owner = NULL; 05869 p->outgoing = 0; 05870 sig_pri_set_digital(p, 0); /* push up to parent for EC*/ 05871 #if defined(HAVE_PRI_CALL_WAITING) 05872 if (p->is_call_waiting) { 05873 p->is_call_waiting = 0; 05874 ast_atomic_fetchadd_int(&p->pri->num_call_waiting_calls, -1); 05875 } 05876 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 05877 p->proceeding = 0; 05878 p->progress = 0; 05879 p->alerting = 0; 05880 p->setup_ack = 0; 05881 p->cid_num[0] = '\0'; 05882 p->cid_subaddr[0] = '\0'; 05883 p->cid_name[0] = '\0'; 05884 p->user_tag[0] = '\0'; 05885 p->exten[0] = '\0'; 05886 sig_pri_set_dialing(p, 0); 05887 05888 /* Make sure we have a call (or REALLY have a call in the case of a PRI) */ 05889 if (!pri_grab(p, p->pri)) { 05890 if (p->call) { 05891 if (p->alreadyhungup) { 05892 ast_log(LOG_DEBUG, "Already hungup... Calling hangup once, and clearing call\n"); 05893 05894 #ifdef SUPPORT_USERUSER 05895 pri_call_set_useruser(p->call, useruser); 05896 #endif 05897 05898 #if defined(HAVE_PRI_AOC_EVENTS) 05899 if (p->holding_aoce) { 05900 pri_aoc_e_send(p->pri->pri, p->call, &p->aoc_e); 05901 } 05902 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 05903 pri_hangup(p->pri->pri, p->call, -1); 05904 p->call = NULL; 05905 } else { 05906 const char *cause = pbx_builtin_getvar_helper(ast,"PRI_CAUSE"); 05907 int icause = ast->hangupcause ? ast->hangupcause : -1; 05908 ast_log(LOG_DEBUG, "Not yet hungup... Calling hangup once with icause, and clearing call\n"); 05909 05910 #ifdef SUPPORT_USERUSER 05911 pri_call_set_useruser(p->call, useruser); 05912 #endif 05913 05914 p->alreadyhungup = 1; 05915 if (cause) { 05916 if (atoi(cause)) 05917 icause = atoi(cause); 05918 } 05919 #if defined(HAVE_PRI_AOC_EVENTS) 05920 if (p->holding_aoce) { 05921 pri_aoc_e_send(p->pri->pri, p->call, &p->aoc_e); 05922 } 05923 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 05924 pri_hangup(p->pri->pri, p->call, icause); 05925 } 05926 } 05927 sig_pri_span_devstate_changed(p->pri); 05928 pri_rel(p->pri); 05929 res = 0; 05930 } else { 05931 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->pri->span); 05932 res = -1; 05933 } 05934 05935 #if defined(HAVE_PRI_AOC_EVENTS) 05936 p->aoc_s_request_invoke_id_valid = 0; 05937 p->holding_aoce = 0; 05938 p->waiting_for_aoce = 0; 05939 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 05940 ast->tech_pvt = NULL; 05941 return res; 05942 }
int sig_pri_indicate | ( | struct sig_pri_chan * | p, | |
struct ast_channel * | chan, | |||
int | condition, | |||
const void * | data, | |||
size_t | datalen | |||
) |
Definition at line 6467 of file sig_pri.c.
References ast_channel::_softhangup, ast_channel::_state, sig_pri_chan::alerting, AST_AOC_D, ast_aoc_decode(), ast_aoc_destroy_decoded(), AST_AOC_E, ast_aoc_get_msg_type(), ast_aoc_get_termination_request(), AST_AOC_REQUEST, AST_AOC_S, AST_CAUSE_CONGESTION, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_USER_BUSY, AST_CONTROL_AOC, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HOLD, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_REDIRECTING, AST_CONTROL_RINGING, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, ast_debug, ast_log(), ast_moh_start(), ast_moh_stop(), ast_setstate(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, sig_pri_chan::call, ast_channel::connected, sig_pri_chan::digital, ast_channel::hangupcause, ast_party_connected_line::id, LOG_DEBUG, LOG_WARNING, sig_pri_chan::mohinterpret, ast_channel::name, sig_pri_chan::no_b_channel, sig_pri_chan::outgoing, sig_pri_chan::pri, sig_pri_span::pri, pri_grab(), pri_rel(), sig_pri_chan::priindication_oob, sig_pri_chan::prioffset, sig_pri_chan::proceeding, sig_pri_chan::progress, PVT_TO_CHANNEL(), SIG_PRI_AOC_GRANT_D, SIG_PRI_AOC_GRANT_E, SIG_PRI_AOC_GRANT_S, sig_pri_party_id_from_ast(), sig_pri_play_tone(), sig_pri_redirecting_update(), sig_pri_set_dialing(), sig_pri_set_digital(), SIG_PRI_TONE_BUSY, SIG_PRI_TONE_CONGESTION, SIG_PRI_TONE_RINGTONE, and sig_pri_span::span.
Referenced by dahdi_indicate().
06468 { 06469 int res = -1; 06470 06471 switch (condition) { 06472 case AST_CONTROL_BUSY: 06473 if (p->priindication_oob || p->no_b_channel) { 06474 chan->hangupcause = AST_CAUSE_USER_BUSY; 06475 chan->_softhangup |= AST_SOFTHANGUP_DEV; 06476 res = 0; 06477 } else if (!p->progress && p->pri && !p->outgoing) { 06478 if (p->pri->pri) { 06479 if (!pri_grab(p, p->pri)) { 06480 #ifdef HAVE_PRI_PROG_W_CAUSE 06481 pri_progress_with_cause(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1, PRI_CAUSE_USER_BUSY); /* cause = 17 */ 06482 #else 06483 pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1); 06484 #endif 06485 pri_rel(p->pri); 06486 } else { 06487 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->pri->span); 06488 } 06489 } 06490 p->progress = 1; 06491 res = sig_pri_play_tone(p, SIG_PRI_TONE_BUSY); 06492 } 06493 break; 06494 case AST_CONTROL_RINGING: 06495 if ((!p->alerting) && p->pri && !p->outgoing && (chan->_state != AST_STATE_UP)) { 06496 if (p->pri->pri) { 06497 if (!pri_grab(p, p->pri)) { 06498 pri_acknowledge(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 06499 p->no_b_channel || p->digital ? 0 : 1); 06500 pri_rel(p->pri); 06501 } else { 06502 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->pri->span); 06503 } 06504 } 06505 p->alerting = 1; 06506 } 06507 res = sig_pri_play_tone(p, SIG_PRI_TONE_RINGTONE); 06508 if (chan->_state != AST_STATE_UP) { 06509 if (chan->_state != AST_STATE_RING) 06510 ast_setstate(chan, AST_STATE_RINGING); 06511 } 06512 break; 06513 case AST_CONTROL_PROCEEDING: 06514 ast_debug(1,"Received AST_CONTROL_PROCEEDING on %s\n",chan->name); 06515 if (!p->proceeding && p->pri && !p->outgoing) { 06516 if (p->pri->pri) { 06517 if (!pri_grab(p, p->pri)) { 06518 pri_proceeding(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 06519 p->no_b_channel || p->digital ? 0 : 1); 06520 p->proceeding = 1; 06521 if (!p->no_b_channel && !p->digital) { 06522 sig_pri_set_dialing(p, 0); 06523 } 06524 pri_rel(p->pri); 06525 } else { 06526 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->pri->span); 06527 } 06528 } 06529 } 06530 /* don't continue in ast_indicate */ 06531 res = 0; 06532 break; 06533 case AST_CONTROL_PROGRESS: 06534 ast_debug(1,"Received AST_CONTROL_PROGRESS on %s\n",chan->name); 06535 sig_pri_set_digital(p, 0); /* Digital-only calls isn't allowing any inband progress messages */ 06536 if (!p->progress && !p->alerting && p->pri && !p->outgoing && !p->no_b_channel) { 06537 if (p->pri->pri) { 06538 if (!pri_grab(p, p->pri)) { 06539 #ifdef HAVE_PRI_PROG_W_CAUSE 06540 pri_progress_with_cause(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1, -1); /* no cause at all */ 06541 #else 06542 pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1); 06543 #endif 06544 pri_rel(p->pri); 06545 } else { 06546 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->pri->span); 06547 } 06548 } 06549 p->progress = 1; 06550 } 06551 /* don't continue in ast_indicate */ 06552 res = 0; 06553 break; 06554 case AST_CONTROL_CONGESTION: 06555 chan->hangupcause = AST_CAUSE_CONGESTION; 06556 if (p->priindication_oob || p->no_b_channel) { 06557 chan->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 06558 chan->_softhangup |= AST_SOFTHANGUP_DEV; 06559 res = 0; 06560 } else if (!p->progress && p->pri && !p->outgoing) { 06561 if (p->pri->pri) { 06562 if (!pri_grab(p, p->pri)) { 06563 #ifdef HAVE_PRI_PROG_W_CAUSE 06564 pri_progress_with_cause(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1, PRI_CAUSE_SWITCH_CONGESTION); /* cause = 42 */ 06565 #else 06566 pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1); 06567 #endif 06568 pri_rel(p->pri); 06569 } else { 06570 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->pri->span); 06571 } 06572 } 06573 p->progress = 1; 06574 res = sig_pri_play_tone(p, SIG_PRI_TONE_CONGESTION); 06575 } 06576 break; 06577 case AST_CONTROL_HOLD: 06578 if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) { 06579 if (!pri_grab(p, p->pri)) { 06580 res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_HOLD); 06581 pri_rel(p->pri); 06582 } else { 06583 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->pri->span); 06584 } 06585 } else 06586 ast_moh_start(chan, data, p->mohinterpret); 06587 break; 06588 case AST_CONTROL_UNHOLD: 06589 if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) { 06590 if (!pri_grab(p, p->pri)) { 06591 res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_RETRIEVAL); 06592 pri_rel(p->pri); 06593 } 06594 } else 06595 ast_moh_stop(chan); 06596 break; 06597 case AST_CONTROL_SRCUPDATE: 06598 res = 0; 06599 break; 06600 case -1: 06601 res = sig_pri_play_tone(p, -1); 06602 break; 06603 case AST_CONTROL_CONNECTED_LINE: 06604 ast_debug(1, "Received AST_CONTROL_CONNECTED_LINE on %s\n", chan->name); 06605 if (p->pri && !pri_grab(p, p->pri)) { 06606 struct pri_party_connected_line connected; 06607 06608 memset(&connected, 0, sizeof(connected)); 06609 sig_pri_party_id_from_ast(&connected.id, &chan->connected.id); 06610 06611 pri_connected_line_update(p->pri->pri, p->call, &connected); 06612 pri_rel(p->pri); 06613 } 06614 break; 06615 case AST_CONTROL_REDIRECTING: 06616 ast_debug(1, "Received AST_CONTROL_REDIRECTING on %s\n", chan->name); 06617 if (p->pri && !pri_grab(p, p->pri)) { 06618 sig_pri_redirecting_update(p, chan); 06619 pri_rel(p->pri); 06620 } 06621 break; 06622 case AST_CONTROL_AOC: 06623 #if defined(HAVE_PRI_AOC_EVENTS) 06624 { 06625 struct ast_aoc_decoded *decoded 06626 = ast_aoc_decode((struct ast_aoc_encoded *) data, datalen, chan); 06627 ast_debug(1, "Received AST_CONTROL_AOC on %s\n", chan->name); 06628 if (decoded && p->pri && !pri_grab(p, p->pri)) { 06629 switch (ast_aoc_get_msg_type(decoded)) { 06630 case AST_AOC_S: 06631 if (p->pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_S) { 06632 sig_pri_aoc_s_from_ast(p, decoded); 06633 } 06634 break; 06635 case AST_AOC_D: 06636 if (p->pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_D) { 06637 sig_pri_aoc_d_from_ast(p, decoded); 06638 } 06639 break; 06640 case AST_AOC_E: 06641 if (p->pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_E) { 06642 sig_pri_aoc_e_from_ast(p, decoded); 06643 } 06644 /* if hangup was delayed for this AOC-E msg, waiting_for_aoc 06645 * will be set. A hangup is already occuring via a timeout during 06646 * this delay. Instead of waiting for that timeout to occur, go ahead 06647 * and initiate the softhangup since the delay is no longer necessary */ 06648 if (p->waiting_for_aoce) { 06649 p->waiting_for_aoce = 0; 06650 ast_log(LOG_DEBUG, 06651 "Received final AOC-E msg, continue with hangup on %s\n", 06652 chan->name); 06653 ast_softhangup_nolock(chan, AST_SOFTHANGUP_DEV); 06654 } 06655 break; 06656 case AST_AOC_REQUEST: 06657 /* We do not pass through AOC requests, So unless this 06658 * is an AOC termination request it will be ignored */ 06659 if (ast_aoc_get_termination_request(decoded)) { 06660 pri_hangup(p->pri->pri, p->call, -1); 06661 } 06662 break; 06663 default: 06664 break; 06665 } 06666 pri_rel(p->pri); 06667 } 06668 ast_aoc_destroy_decoded(decoded); 06669 } 06670 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 06671 break; 06672 } 06673 06674 return res; 06675 }
void sig_pri_init_pri | ( | struct sig_pri_span * | pri | ) |
Definition at line 5842 of file sig_pri.c.
References ast_mutex_init, AST_PTHREADT_NULL, and SIG_PRI_NUM_DCHANS.
Referenced by load_module().
05843 { 05844 int i; 05845 05846 memset(pri, 0, sizeof(*pri)); 05847 05848 ast_mutex_init(&pri->lock); 05849 05850 pri->master = AST_PTHREADT_NULL; 05851 for (i = 0; i < SIG_PRI_NUM_DCHANS; i++) 05852 pri->fds[i] = -1; 05853 }
static int sig_pri_is_cis_call | ( | int | channel | ) | [static] |
Definition at line 3484 of file sig_pri.c.
References PRI_CIS_CALL.
03485 { 03486 return channel != -1 && (channel & PRI_CIS_CALL); 03487 }
int sig_pri_load | ( | const char * | cc_type_name | ) |
Load the sig_pri submodule.
cc_type_name | CC type name to use when looking up agent/monitor. |
0 | on success. | |
-1 | on error. |
Definition at line 7942 of file sig_pri.c.
References ao2_container_alloc.
Referenced by load_module().
07943 { 07944 #if defined(HAVE_PRI_CCSS) 07945 sig_pri_cc_type_name = cc_type_name; 07946 sig_pri_cc_monitors = ao2_container_alloc(37, sig_pri_cc_monitor_instance_hash_fn, 07947 sig_pri_cc_monitor_instance_cmp_fn); 07948 if (!sig_pri_cc_monitors) { 07949 return -1; 07950 } 07951 #endif /* defined(HAVE_PRI_CCSS) */ 07952 return 0; 07953 }
static void sig_pri_lock_owner | ( | struct sig_pri_span * | pri, | |
int | chanpos | |||
) | [static] |
Definition at line 1012 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().
01013 { 01014 for (;;) { 01015 if (!pri->pvts[chanpos]->owner) { 01016 /* There is no owner lock to get. */ 01017 break; 01018 } 01019 if (!ast_channel_trylock(pri->pvts[chanpos]->owner)) { 01020 /* We got the lock */ 01021 break; 01022 } 01023 /* We must unlock the PRI to avoid the possibility of a deadlock */ 01024 ast_mutex_unlock(&pri->lock); 01025 PRI_DEADLOCK_AVOIDANCE(pri->pvts[chanpos]); 01026 ast_mutex_lock(&pri->lock); 01027 } 01028 }
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 1799 of file sig_pri.c.
References ast_extension_match(), ast_strdupa, ast_strip(), and ast_strlen_zero().
01800 { 01801 char *pattern; 01802 char *msn_list; 01803 char *list_tail; 01804 01805 msn_list = ast_strdupa(msn_patterns); 01806 01807 list_tail = NULL; 01808 pattern = strtok_r(msn_list, ",", &list_tail); 01809 while (pattern) { 01810 pattern = ast_strip(pattern); 01811 if (!ast_strlen_zero(pattern) && ast_extension_match(pattern, exten)) { 01812 /* Extension matched the pattern. */ 01813 return 1; 01814 } 01815 pattern = strtok_r(NULL, ",", &list_tail); 01816 } 01817 /* Did not match any pattern in the list. */ 01818 return 0; 01819 }
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 (!p->owner) 00874 p->owner = c; 00875 p->isidlecall = 0; 00876 p->alreadyhungup = 0; 00877 c->transfercapability = transfercapability; 00878 pbx_builtin_setvar_helper(c, "TRANSFERCAPABILITY", 00879 ast_transfercapability2str(transfercapability)); 00880 if (transfercapability & AST_TRANS_CAP_DIGITAL) { 00881 sig_pri_set_digital(p, 1); 00882 } 00883 if (p->pri) { 00884 ast_mutex_lock(&p->pri->lock); 00885 sig_pri_span_devstate_changed(p->pri); 00886 ast_mutex_unlock(&p->pri->lock); 00887 } 00888 00889 return c; 00890 }
static void sig_pri_open_media | ( | struct sig_pri_chan * | p | ) | [static] |
Definition at line 901 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().
00902 { 00903 if (p->no_b_channel) { 00904 return; 00905 } 00906 00907 if (p->calls->open_media) { 00908 p->calls->open_media(p->chan_pvt); 00909 } 00910 }
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 1745 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().
01746 { 01747 if (pri_id->name.valid) { 01748 sig_pri_party_name_convert(&ast_id->name, &pri_id->name); 01749 } 01750 if (pri_id->number.valid) { 01751 sig_pri_party_number_convert(&ast_id->number, &pri_id->number, pri); 01752 } 01753 #if defined(HAVE_PRI_SUBADDR) 01754 if (pri_id->subaddress.valid) { 01755 sig_pri_set_subaddress(&ast_id->subaddress, &pri_id->subaddress); 01756 } 01757 #endif /* defined(HAVE_PRI_SUBADDR) */ 01758 }
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 1698 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().
01699 { 01700 ast_name->str = ast_strdup(pri_name->str); 01701 ast_name->char_set = pri_to_ast_char_set(pri_name->char_set); 01702 ast_name->presentation = pri_to_ast_presentation(pri_name->presentation); 01703 ast_name->valid = 1; 01704 }
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 1720 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().
01721 { 01722 char number[AST_MAX_EXTENSION]; 01723 01724 apply_plan_to_number(number, sizeof(number), pri, pri_number->str, pri_number->plan); 01725 ast_number->str = ast_strdup(number); 01726 ast_number->plan = pri_number->plan; 01727 ast_number->presentation = pri_to_ast_presentation(pri_number->presentation); 01728 ast_number->valid = 1; 01729 }
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 1775 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().
01779 { 01780 ast_party_redirecting_set_init(ast_redirecting, ast_guide); 01781 01782 sig_pri_party_id_convert(&ast_redirecting->from, &pri_redirecting->from, pri); 01783 sig_pri_party_id_convert(&ast_redirecting->to, &pri_redirecting->to, pri); 01784 ast_redirecting->count = pri_redirecting->count; 01785 ast_redirecting->reason = pri_to_ast_reason(pri_redirecting->reason); 01786 }
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 912 of file sig_pri.c.
References ast_log(), AST_STATE_RESERVED, sig_pri_chan::channel, sig_pri_chan::exten, LOG_DEBUG, sig_pri_chan::outgoing, and sig_pri_new_ast_channel().
Referenced by dahdi_request(), and pri_dchannel().
00913 { 00914 struct ast_channel *ast; 00915 00916 ast_log(LOG_DEBUG, "%s %d\n", __FUNCTION__, p->channel); 00917 00918 p->outgoing = 1; 00919 ast = sig_pri_new_ast_channel(p, AST_STATE_RESERVED, law, transfercapability, p->exten, requestor); 00920 if (!ast) { 00921 p->outgoing = 0; 00922 } 00923 return ast; 00924 }
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 7010 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().
07011 { 07012 qsort(&pri->pvts, pri->numchans, sizeof(pri->pvts[0]), sig_pri_cmp_pri_chans); 07013 }
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 7015 of file sig_pri.c.
References ARRAY_LEN, AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_MWI, ast_event_subscribe(), ast_event_unsubscribe(), ast_log(), ast_mutex_init, ast_str_alloca, ast_str_buffer(), ast_str_set(), ast_strip(), ast_strlen_zero(), sig_pri_span::dchans, sig_pri_span::enable_service_message_support, sig_pri_span::fds, HAVE_PRI_SERVICE_MESSAGES, sig_pri_span::lock, LOG_ERROR, sig_pri_span::nodetype, sig_pri_span::sig, SIG_BRI, SIG_BRI_PTMP, SIG_PRI_NUM_DCHANS, sig_pri_sort_pri_chans(), sig_pri_span::span, strsep(), and sig_pri_span::switchtype.
Referenced by setup_dahdi_int().
07016 { 07017 int x; 07018 int i; 07019 #if defined(HAVE_PRI_MWI) 07020 char *saveptr; 07021 char *mbox_number; 07022 char *mbox_context; 07023 struct ast_str *mwi_description = ast_str_alloca(64); 07024 #endif /* defined(HAVE_PRI_MWI) */ 07025 07026 #if defined(HAVE_PRI_MWI) 07027 /* Prepare the mbox[] for use. */ 07028 for (i = 0; i < ARRAY_LEN(pri->mbox); ++i) { 07029 if (pri->mbox[i].sub) { 07030 pri->mbox[i].sub = ast_event_unsubscribe(pri->mbox[i].sub); 07031 } 07032 } 07033 #endif /* defined(HAVE_PRI_MWI) */ 07034 07035 ast_mutex_init(&pri->lock); 07036 sig_pri_sort_pri_chans(pri); 07037 07038 #if defined(HAVE_PRI_MWI) 07039 /* 07040 * Split the mwi_mailboxes configuration string into the mbox[]: 07041 * mailbox_number[@context]{,mailbox_number[@context]} 07042 */ 07043 i = 0; 07044 saveptr = pri->mwi_mailboxes; 07045 while (i < ARRAY_LEN(pri->mbox)) { 07046 mbox_number = strsep(&saveptr, ","); 07047 if (!mbox_number) { 07048 break; 07049 } 07050 /* Split the mailbox_number and context */ 07051 mbox_context = strchr(mbox_number, '@'); 07052 if (mbox_context) { 07053 *mbox_context++ = '\0'; 07054 mbox_context = ast_strip(mbox_context); 07055 } 07056 mbox_number = ast_strip(mbox_number); 07057 if (ast_strlen_zero(mbox_number)) { 07058 /* There is no mailbox number. Skip it. */ 07059 continue; 07060 } 07061 if (ast_strlen_zero(mbox_context)) { 07062 /* There was no context so use the default. */ 07063 mbox_context = "default"; 07064 } 07065 07066 /* Fill the mbox[] element. */ 07067 ast_str_set(&mwi_description, -1, "%s span %d[%d] MWI mailbox %s@%s", 07068 sig_pri_cc_type_name, pri->span, i, mbox_number, mbox_context); 07069 pri->mbox[i].sub = ast_event_subscribe(AST_EVENT_MWI, sig_pri_mwi_event_cb, 07070 ast_str_buffer(mwi_description), pri, 07071 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mbox_number, 07072 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, mbox_context, 07073 AST_EVENT_IE_END); 07074 if (!pri->mbox[i].sub) { 07075 ast_log(LOG_ERROR, "%s span %d could not subscribe to MWI events for %s@%s.", 07076 sig_pri_cc_type_name, pri->span, mbox_number, mbox_context); 07077 continue; 07078 } 07079 pri->mbox[i].number = mbox_number; 07080 pri->mbox[i].context = mbox_context; 07081 ++i; 07082 } 07083 #endif /* defined(HAVE_PRI_MWI) */ 07084 07085 for (i = 0; i < SIG_PRI_NUM_DCHANS; i++) { 07086 if (pri->fds[i] == -1) { 07087 break; 07088 } 07089 07090 switch (pri->sig) { 07091 case SIG_BRI: 07092 pri->dchans[i] = pri_new_bri(pri->fds[i], 1, pri->nodetype, pri->switchtype); 07093 break; 07094 case SIG_BRI_PTMP: 07095 pri->dchans[i] = pri_new_bri(pri->fds[i], 0, pri->nodetype, pri->switchtype); 07096 break; 07097 default: 07098 pri->dchans[i] = pri_new(pri->fds[i], pri->nodetype, pri->switchtype); 07099 #if defined(HAVE_PRI_SERVICE_MESSAGES) 07100 if (pri->enable_service_message_support) { 07101 pri_set_service_message_support(pri->dchans[i], 1); 07102 } 07103 #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */ 07104 break; 07105 } 07106 07107 pri_set_overlapdial(pri->dchans[i], (pri->overlapdial & DAHDI_OVERLAPDIAL_OUTGOING) ? 1 : 0); 07108 #ifdef HAVE_PRI_PROG_W_CAUSE 07109 pri_set_chan_mapping_logical(pri->dchans[i], pri->qsigchannelmapping == DAHDI_CHAN_MAPPING_LOGICAL); 07110 #endif 07111 #ifdef HAVE_PRI_INBANDDISCONNECT 07112 pri_set_inbanddisconnect(pri->dchans[i], pri->inbanddisconnect); 07113 #endif 07114 /* Enslave to master if appropriate */ 07115 if (i) 07116 pri_enslave(pri->dchans[0], pri->dchans[i]); 07117 if (!pri->dchans[i]) { 07118 if (pri->fds[i] > 0) 07119 close(pri->fds[i]); 07120 pri->fds[i] = -1; 07121 ast_log(LOG_ERROR, "Unable to create PRI structure\n"); 07122 return -1; 07123 } 07124 pri_set_debug(pri->dchans[i], SIG_PRI_DEBUG_DEFAULT); 07125 pri_set_nsf(pri->dchans[i], pri->nsf); 07126 #ifdef PRI_GETSET_TIMERS 07127 for (x = 0; x < PRI_MAX_TIMERS; x++) { 07128 if (pri->pritimers[x] != 0) 07129 pri_set_timer(pri->dchans[i], x, pri->pritimers[x]); 07130 } 07131 #endif 07132 } 07133 07134 /* Assume primary is the one we use */ 07135 pri->pri = pri->dchans[0]; 07136 07137 #if defined(HAVE_PRI_CALL_HOLD) 07138 pri_hold_enable(pri->pri, 1); 07139 #endif /* defined(HAVE_PRI_CALL_HOLD) */ 07140 #if defined(HAVE_PRI_CALL_REROUTING) 07141 pri_reroute_enable(pri->pri, 1); 07142 #endif /* defined(HAVE_PRI_CALL_REROUTING) */ 07143 #if defined(HAVE_PRI_HANGUP_FIX) 07144 pri_hangup_fix_enable(pri->pri, 1); 07145 #endif /* defined(HAVE_PRI_HANGUP_FIX) */ 07146 #if defined(HAVE_PRI_CCSS) 07147 pri_cc_enable(pri->pri, 1); 07148 pri_cc_recall_mode(pri->pri, pri->cc_ptmp_recall_mode); 07149 pri_cc_retain_signaling_req(pri->pri, pri->cc_qsig_signaling_link_req); 07150 pri_cc_retain_signaling_rsp(pri->pri, pri->cc_qsig_signaling_link_rsp); 07151 #endif /* defined(HAVE_PRI_CCSS) */ 07152 #if defined(HAVE_PRI_TRANSFER) 07153 pri_transfer_enable(pri->pri, 1); 07154 #endif /* defined(HAVE_PRI_TRANSFER) */ 07155 #if defined(HAVE_PRI_AOC_EVENTS) 07156 pri_aoc_events_enable(pri->pri, 1); 07157 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 07158 #if defined(HAVE_PRI_CALL_WAITING) 07159 pri_connect_ack_enable(pri->pri, 1); 07160 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 07161 #if defined(HAVE_PRI_MCID) 07162 pri_mcid_enable(pri->pri, 1); 07163 #endif /* defined(HAVE_PRI_MCID) */ 07164 07165 pri->resetpos = -1; 07166 if (ast_pthread_create_background(&pri->master, NULL, pri_dchannel, pri)) { 07167 for (i = 0; i < SIG_PRI_NUM_DCHANS; i++) { 07168 if (!pri->dchans[i]) 07169 break; 07170 if (pri->fds[i] > 0) 07171 close(pri->fds[i]); 07172 pri->fds[i] = -1; 07173 } 07174 ast_log(LOG_ERROR, "Unable to spawn D-channel: %s\n", strerror(errno)); 07175 return -1; 07176 } 07177 07178 #if defined(HAVE_PRI_MWI) 07179 /* 07180 * Send the initial MWI indications from the event cache for this span. 07181 * 07182 * If we were loaded after app_voicemail the event would already be in 07183 * the cache. If we were loaded before app_voicemail the event would not 07184 * be in the cache yet and app_voicemail will send the event when it 07185 * gets loaded. 07186 */ 07187 sig_pri_mwi_cache_update(pri); 07188 #endif /* defined(HAVE_PRI_MWI) */ 07189 07190 return 0; 07191 }
void sig_pri_stop_pri | ( | struct sig_pri_span * | pri | ) |
Stop PRI span.
pri | Asterisk D channel control structure. |
Definition at line 6950 of file sig_pri.c.
References ARRAY_LEN, and ast_event_unsubscribe().
Referenced by __unload_module().
06951 { 06952 #if defined(HAVE_PRI_MWI) 06953 int idx; 06954 #endif /* defined(HAVE_PRI_MWI) */ 06955 06956 #if defined(HAVE_PRI_MWI) 06957 for (idx = 0; idx < ARRAY_LEN(pri->mbox); ++idx) { 06958 if (pri->mbox[idx].sub) { 06959 pri->mbox[idx].sub = ast_event_unsubscribe(pri->mbox[idx].sub); 06960 } 06961 } 06962 #endif /* defined(HAVE_PRI_MWI) */ 06963 }
void sig_pri_unload | ( | void | ) |
Unload the sig_pri submodule.
Definition at line 7961 of file sig_pri.c.
References ao2_ref.
Referenced by __unload_module().
07962 { 07963 #if defined(HAVE_PRI_CCSS) 07964 if (sig_pri_cc_monitors) { 07965 ao2_ref(sig_pri_cc_monitors, -1); 07966 sig_pri_cc_monitors = NULL; 07967 } 07968 #endif /* defined(HAVE_PRI_CCSS) */ 07969 }
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] |